Revamp alt compiler handling for clang 3.9.1 import. master
authorzrj <rimvydas.jasinskas@gmail.com>
Mon, 5 Dec 2016 18:11:24 +0000 (20:11 +0200)
committerzrj <zrj@dragonflybsd.org>
Wed, 7 Dec 2016 06:32:18 +0000 (08:32 +0200)
Many users are still constantly asking weather llvm/clang compiler could be
added into a base as an alternative to current used ones (gcc50 and gcc47).
There are few issues in doing that:
 * It is very hard to keep both compiler flavors in harmony while one or the
   other is being updated. There were always two base compilers in base system
   in DragonFly and common practice still is to replace previous alternative
   compiler with an updated version, performing tests and then flip them up.
 * With clang introduction, this scheme would break badly due to both using
   slightly different c++ capabilities, flags support (WARNS mechanism), etc.
 * Different incompatible libraries libLLVM + libc++ vs libstdc++, also clang
   requiring a lot of effort to rewrite cmake logic into Makefiles for make(1).
 * SBU costs, gcc47 only has ~4min buildtime overhead at -j5 level(i7 laptop)
   while even clang38 tests has shown two-fold increase in buildworld time.
 * How DPorts infrastructure would handle both flavors? License roadmap?

So to make compromise it was chosen to provide a way for users and developers
to select the alternative compiler they like while keeping all groups happy,
ones continuing to enjoy the very fast world rebuilds and others having a way
to further develop and integrate clang into the infrastructure. Since DragonFly
is currently x86_64 only, we might as well experiment more with compilers.

This changeset adds some flexibility when it comes to handling base system
compilers. Even if it would be decided that clang does not fit very well in
DragonFly base system (due to complexities, updating/patching problems and
compilation times), we at least will have a very clean way for adding,
testing and finally making base default upcoming gcc70 and later. All of this
would be possible without disturbing both primary and alternative default
compilers, while developers and users will be testing both base and dports.
Also as a bonus we will be able to add compilers like pcc and scc that have
no native c++ frontend support too while reusing default compiler parts.
For now I am keeping this expansion undocumented and candidate for a revert.

While there mark few places for further work to reduce amount of ORDER: for
faster/better parallelism in btools/ctools bootstrapping stages.

Bootstrap is still fine from DragonFly 4.0.6-RELEASE.

Makefile.inc1
etc/defaults/make.conf
gnu/lib/Makefile
gnu/usr.bin/Makefile
share/man/man5/make.conf.5
share/mk/sys.mk

index 3c7c51a..2b42094 100644 (file)
@@ -918,24 +918,42 @@ bstrap-${_tool}!
 _share=        share/syscons/scrnmaps
 .endif
 
+# XXX we should separate this into new Makefile.inc2.
+# Just to prepare for reduction of ORDER: that slows down parallel crossworld.
+
+# Make sure Makefile.inc1 logic is intact.
+.if !defined(WORLD_ALTCOMPILER)
+.error undefined WORLD_ALTCOMPILER
+.endif)
+
 _gcc_common_cross= lib/libz gnu/usr.bin/gmp gnu/usr.bin/mpfr gnu/usr.bin/mpc
 _gcc50_cross= gnu/usr.bin/cc50
 _gcc50_tools= gnu/usr.bin/cc50/cc_prep gnu/usr.bin/cc50/cc_tools
 .if !defined(NO_ALTCOMPILER)
+. if defined(WORLD_ALTCOMPILER) && (${WORLD_ALTCOMPILER} == "all" || ${WORLD_ALTCOMPILER:Mgcc47})
 _gcc47_cross= gnu/usr.bin/cc47
 _gcc47_tools= gnu/usr.bin/cc47/cc_prep gnu/usr.bin/cc47/cc_tools
+_altcompiler_cross+= ${_gcc47_cross}
+_altcompiler_tools+= _gcc47_tools
+. endif
 .endif
 _custom_cross= libexec/customcc
 _binutils= gnu/usr.bin/${WORLD_BINUTILSVER}
 
-BTOOLSDIRS= ${_gcc47_tools} ${_gcc50_tools} ${_share}
+.for _atools in ${_altcompiler_tools}
+BTOOLSDIRS+=   ${${_atools}}
+.endfor
+BTOOLSDIRS+=   ${_gcc50_tools}
+BTOOLSDIRS+=   ${_share}
 
 build-tools: build-tools-targets
        touch ${BTOOLSDEST}/.build_done
 
 build-tools-targets: ${BTOOLSDIRS:S/^/btools-/}
 
-.ORDER: ${_gcc47_tools:S/^/btools-/}
+.for _atools in ${_altcompiler_tools}
+.ORDER: ${${_atools}:C/^/btools-/}
+.endfor
 .ORDER: ${_gcc50_tools:S/^/btools-/}
 
 .for _tool in ${BTOOLSDIRS}
@@ -958,7 +976,8 @@ _btxld=     usr.sbin/btxld
 CTOOLSDIRS= ${_btxld} ${_binutils} \
                usr.bin/objformat usr.bin/crunch/crunchide \
                ${_gcc_common_cross} \
-               ${_gcc47_cross} ${_gcc50_cross} ${_custom_cross}
+               ${_altcompiler_cross} \
+               ${_gcc50_cross} ${_custom_cross}
 
 cross-tools: cross-tools-targets
        touch ${CTOOLSDEST}/.cross_done
@@ -996,9 +1015,11 @@ libraries:
            HOST_CCVER=${HOST_CCVER} CCVER=gcc50 \
                make -f Makefile.inc1 _startup_libs50 -DSYSBUILD;
 .if !defined(NO_ALTCOMPILER)
+. if defined(WORLD_ALTCOMPILER) && (${WORLD_ALTCOMPILER} == "all" || ${WORLD_ALTCOMPILER:Mgcc47})
        cd ${.CURDIR}; \
            HOST_CCVER=${HOST_CCVER} CCVER=gcc47 \
                make -f Makefile.inc1 _startup_libs47 -DSYSBUILD;
+. endif
 .endif
        cd ${.CURDIR}; \
            make -f Makefile.inc1 _startup_libs -DSYSBUILD; \
@@ -1012,12 +1033,17 @@ libraries:
 # shared libraries for ELF.  The target for _startup_libsXX is
 # specifically built using gccXX.
 #
+.if !defined(NO_ALTCOMPILER)
 _startup_libs47=       gnu/usr.bin/cc47/cc_prep \
                        gnu/usr.bin/cc47/cc_tools \
                        gnu/lib/gcc47/csu \
                        gnu/lib/gcc47/libgcc \
                        gnu/lib/gcc47/libgcc_eh \
                        gnu/lib/gcc47/libgcc_pic
+. if defined(WORLD_ALTCOMPILER) && (${WORLD_ALTCOMPILER} == "all" || ${WORLD_ALTCOMPILER:Mgcc47})
+_startup_libs_alt+=    _startup_libs47
+. endif
+.endif
 _startup_libs50=       gnu/usr.bin/cc50/cc_prep \
                        gnu/usr.bin/cc50/cc_tools \
                        gnu/lib/gcc50/csu \
@@ -1055,7 +1081,11 @@ _prebuild_libs+= lib/libradius lib/libsbuf lib/libtacplus lib/libm \
 
 _generic_libs+=        usr.bin/flex/lib
 
-.for _lib in ${_startup_libs47} ${_startup_libs50} \
+.for _alib in ${_startup_libs_alt}
+__startup_alibs+= ${${_alib}}
+.endfor
+
+.for _lib in ${__startup_alibs} ${_startup_libs50} \
                ${_startup_libs} ${_prebuild_libs} ${_generic_libs}
 ${_lib}__L: .PHONY
 .if exists(${.CURDIR}/${_lib})
@@ -1068,11 +1098,15 @@ ${_lib}__L: .PHONY
                echo "STEP INSTALL ${_lib}"; \
                make DIRPRFX=${_lib}/ install; \
                echo "STEP DONE ${_lib}";
+.else
+.warning missing ${.CURDIR}/${_lib} directory.
 .endif
 .endfor
 
 _startup_libs: ${_startup_libs:S/$/__L/}
-_startup_libs47: ${_startup_libs47:S/$/__L/}
+.for _alib in ${_startup_libs_alt}
+${_alib}: ${${_alib}:C/$/__L/}
+.endfor
 _startup_libs50: ${_startup_libs50:S/$/__L/}
 _prebuild_libs: ${_prebuild_libs:S/$/__L/}
 _generic_libs: ${_generic_libs:S/$/__L/}
@@ -1080,7 +1114,9 @@ _generic_libs: ${_generic_libs:S/$/__L/}
 # library targets must be ordered because there are inter-library
 # races (e.g. generation of tconfig.h)
 #
-.ORDER: ${_startup_libs47:S/$/__L/}
+.for _alib in ${_startup_libs_alt}
+.ORDER: ${${_alib}:C/$/__L/}
+.endfor
 .ORDER: ${_startup_libs50:S/$/__L/}
 .ORDER: ${_startup_libs:S/$/__L/}
 .ORDER: ${_prebuild_libs:S/$/__L/}
@@ -1100,8 +1136,8 @@ ${entry}.${__target}__D: .PHONY
        fi; \
        make ${__target} DIRPRFX=${DIRPRFX}$${edir}/
 .endfor
-par-${__target}: ${SUBDIR:S/$/.${__target}__D/}
-.ORDER: ${SUBDIR:S/$/.${__target}__D/}
+par-${__target}: ${SUBDIR:C/$/.${__target}__D/}
+.ORDER: ${SUBDIR:C/$/.${__target}__D/}
 .endfor
 .ORDER: par-clean par-cleandepend par-cleandir par-obj par-depend par-includes
 
@@ -1192,6 +1228,7 @@ MAKE_PRINT_VAR_ON_ERROR= \
        MACHINE_ARCH \
        MACHINE \
        MAKEFILE \
+       WORLD_ALTCOMPILER \
        .TARGETS \
        .ERROR_TARGET \
        .MAKE.LEVEL
index ec23463..55f4d46 100644 (file)
@@ -113,7 +113,7 @@ THREAD_LIB?=        thread_xu
 #
 # To avoid building various parts of the base system:
 #NO_ALTBINUTILS=true   # do not build the alternative set of binutils
-#NO_ALTCOMPILER=true   # do not build GCC 4.7
+#NO_ALTCOMPILER=true   # do not build GCC 4.7 and other alt compilers
 #NO_CRYPT=     true    # do not build crypto code
 #NO_CVS=       true    # do not build CVS
 #NO_GAMES=     true    # do not enter the games subdirectory
index 69ecc4c..951ad6c 100644 (file)
@@ -4,7 +4,9 @@
 SUBDIR= gcc50
 
 .if !defined(NO_ALTCOMPILER)
+. if defined(WORLD_ALTCOMPILER) && (${WORLD_ALTCOMPILER} == "all" || ${WORLD_ALTCOMPILER:Mgcc47})
 SUBDIR+= gcc47
+. endif
 .endif
 
 .if !defined(NO_CRYPT)
index 3cfc8ca..4bcee4f 100644 (file)
@@ -22,13 +22,15 @@ SUBDIR+= mpfr
 SUBDIR+= mpc
 SUBDIR+= cc50
 
-.if defined(NO_ALTCOMPILER)
-.ORDER: ${BU_PRIMARY} gmp mpfr mpc cc50
-.else
+.if !defined(NO_ALTCOMPILER)
+. if defined(WORLD_ALTCOMPILER) && (${WORLD_ALTCOMPILER} == "all" || ${WORLD_ALTCOMPILER:Mgcc47})
 SUBDIR+= cc47
-.ORDER: ${BU_PRIMARY} gmp mpfr mpc cc50 cc47
+_altcompiler_dirs+= cc47
+. endif
 .endif
 
+.ORDER: ${BU_PRIMARY} gmp mpfr mpc cc50 ${_altcompiler_dirs}
+
 # maximum parallelism
 #
 SUBDIR_ORDERED=
index abe7a52..6fd4582 100644 (file)
@@ -392,7 +392,7 @@ Set to build modules with the system instead of the kernel.
 Set to not build the alternative (non-default) set of binutils.
 .It Va NO_ALTCOMPILER
 .Pq Vt bool
-Set to not build the designated secondary compiler (GCC 4.7).
+Set to not build the designated secondary compiler (GCC 4.7 and others).
 .It Va NO_CRYPT
 .Pq Vt bool
 Set to not build crypto code.
index 476023c..ffce254 100644 (file)
@@ -302,10 +302,19 @@ MACHINE_PLATFORM!=sysctl -n hw.platform
 
 .endif
 
+# Include base system defaults.
 .if exists(/etc/defaults/make.conf)
 .include </etc/defaults/make.conf>
 .endif
 
+# XXX we should some how include src tree etc/defaults/make.conf too. Changes
+# to default/make.conf only applies after installworld so might produce world
+# that no longer can bootstrap itself.
+
+# Private helper for handling alternative compilers and Makefile.inc1 tester.
+WORLD_ALTCOMPILER?= gcc47
+
+# Include global user settings.
 __MAKE_CONF?=/etc/make.conf
 .if exists(${__MAKE_CONF})
 .include "${__MAKE_CONF}"
@@ -335,7 +344,7 @@ WORLD_VERSION!=     ${AWK} '/^\#define[[:blank:]]__DragonFly_version/ {print $$3}' <
 # XXX hint for bsd.port.mk
 OBJFORMAT?=    elf
 
-# Tell bmake to expand -V VAR be default
+# Tell bmake to expand -V VAR by default
 .MAKE.EXPAND_VARIABLES= yes
 
 .if !defined(.PARSEDIR)