diff --git a/.ci/azp-linux-test.yml b/.ci/azp-linux-test.yml index a49f3afcc..0135c2895 100644 --- a/.ci/azp-linux-test.yml +++ b/.ci/azp-linux-test.yml @@ -8,34 +8,28 @@ steps: set -e cd src/engine set PATH=${PATH};${CXX_PATH} - ./build.sh ${TOOLSET} --cxx=${CXX} + ./build.sh ${TOOLSET} ./b2 -v cd ../.. displayName: Build - bash: | set -e - CXX_PATH=`which ${CXX}` cd test - echo "using ${TEST_TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam - python test_all.py ${TEST_TOOLSET} + python test_all.py ${TOOLSET} cd .. displayName: Test - bash: | set -e - CXX_PATH=`which ${CXX}` - echo "using ${TEST_TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam - ./src/engine/b2 b2 warnings-as-errors=on variant=debug,release address-model=32,64 toolset=${TEST_TOOLSET} + ./src/engine/b2 b2 warnings-as-errors=on variant=debug,release address-model=32,64 toolset=${TOOLSET} displayName: "No Warnings" - bash: | set -e - CXX_PATH=`which ${CXX}` - echo "using ${TEST_TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam ./bootstrap.sh ${TOOLSET} - ./b2 --prefix=$HOME/temp/.b2 install ${TEST_TOOLSET} + ./b2 --prefix=$HOME/temp/.b2 install toolset=${TOOLSET} rm ./b2 export PATH=$HOME/temp/.b2/bin:$PATH cd $HOME touch build.jam b2 -v - b2 -n --debug-configuration + b2 -n --debug-configuration toolset=${TOOLSET} displayName: Bootstrap diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f4837b8a9..aed8ffdf0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -65,8 +65,8 @@ stages: - job: 'Linux_Latest' strategy: matrix: - GCC 11: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-11, PACKAGES: g++-11, VM_IMAGE: 'ubuntu-latest'} - Clang 12: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-12, PACKAGES: clang-12, LLVM_OS: focal, LLVM_VER: 12, VM_IMAGE: 'ubuntu-latest'} + GCC 11: {TOOLSET: gcc-11, PACKAGES: g++-11, VM_IMAGE: 'ubuntu-latest'} + Clang 12: {TOOLSET: clang-12, PACKAGES: clang-12, LLVM_OS: focal, LLVM_VER: 12, VM_IMAGE: 'ubuntu-latest'} pool: vmImage: $(VM_IMAGE) steps: @@ -97,28 +97,28 @@ stages: - job: 'Linux' strategy: matrix: - GCC 10: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-10, PACKAGES: g++-10, VM_IMAGE: 'ubuntu-latest'} - GCC 9: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-9, PACKAGES: g++-9, VM_IMAGE: 'ubuntu-18.04'} - GCC 8: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-8, PACKAGES: g++-8, VM_IMAGE: 'ubuntu-18.04'} - GCC 7: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-7, PACKAGES: g++-7, VM_IMAGE: 'ubuntu-18.04'} - GCC 6: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-6, PACKAGES: g++-6, VM_IMAGE: 'ubuntu-18.04'} - GCC 5: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-5, PACKAGES: g++-5, VM_IMAGE: 'ubuntu-18.04'} - GCC 4.9: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-4.9, PACKAGES: g++-4.9, VM_IMAGE: 'ubuntu-16.04'} - GCC 4.8: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-4.8, PACKAGES: g++-4.8, VM_IMAGE: 'ubuntu-16.04'} - GCC 4.7: {TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: g++-4.7, PACKAGES: g++-4.7, VM_IMAGE: 'ubuntu-16.04'} - Clang 11: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-11, PACKAGES: clang-11, LLVM_OS: focal, LLVM_VER: 11, VM_IMAGE: 'ubuntu-latest'} - Clang 10: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-10, PACKAGES: clang-10, LLVM_OS: bionic, LLVM_VER: 10, VM_IMAGE: 'ubuntu-18.04'} - Clang 9: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-9, PACKAGES: clang-9, LLVM_OS: bionic, LLVM_VER: 9, VM_IMAGE: 'ubuntu-18.04'} - Clang 8: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-8, PACKAGES: clang-8, LLVM_OS: bionic, LLVM_VER: 8, VM_IMAGE: 'ubuntu-18.04'} - Clang 7: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-7, PACKAGES: clang-7, LLVM_OS: bionic, LLVM_VER: 7, VM_IMAGE: 'ubuntu-18.04'} - Clang 6: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-6.0, PACKAGES: clang-6.0, LLVM_OS: bionic, LLVM_VER: 6.0, VM_IMAGE: 'ubuntu-18.04'} - Clang 5: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-5.0, PACKAGES: clang-5.0, LLVM_OS: bionic, LLVM_VER: 5.0, VM_IMAGE: 'ubuntu-18.04'} - Clang 4: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-4.0, PACKAGES: clang-4.0, LLVM_OS: xenial, LLVM_VER: 4.0, VM_IMAGE: 'ubuntu-16.04'} - Clang 3.9: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-3.9, PACKAGES: clang-3.9, VM_IMAGE: 'ubuntu-16.04'} - Clang 3.8: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-3.8, PACKAGES: clang-3.8, VM_IMAGE: 'ubuntu-16.04'} - Clang 3.7: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-3.7, PACKAGES: clang-3.7, VM_IMAGE: 'ubuntu-16.04'} - Clang 3.6: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-3.6, PACKAGES: clang-3.6, VM_IMAGE: 'ubuntu-16.04'} - Clang 3.5: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++-3.5, PACKAGES: clang-3.5, VM_IMAGE: 'ubuntu-16.04'} + GCC 10: {TOOLSET: gcc-10, PACKAGES: g++-10, VM_IMAGE: 'ubuntu-latest'} + GCC 9: {TOOLSET: gcc-9, PACKAGES: g++-9, VM_IMAGE: 'ubuntu-18.04'} + GCC 8: {TOOLSET: gcc-8, PACKAGES: g++-8, VM_IMAGE: 'ubuntu-18.04'} + GCC 7: {TOOLSET: gcc-7, PACKAGES: g++-7, VM_IMAGE: 'ubuntu-18.04'} + GCC 6: {TOOLSET: gcc-6, PACKAGES: g++-6, VM_IMAGE: 'ubuntu-18.04'} + GCC 5: {TOOLSET: gcc-5, PACKAGES: g++-5, VM_IMAGE: 'ubuntu-18.04'} + GCC 4.9: {TOOLSET: gcc-4.9, PACKAGES: g++-4.9, VM_IMAGE: 'ubuntu-16.04'} + GCC 4.8: {TOOLSET: gcc-4.8, PACKAGES: g++-4.8, VM_IMAGE: 'ubuntu-16.04'} + GCC 4.7: {TOOLSET: gcc-4.7, PACKAGES: g++-4.7, VM_IMAGE: 'ubuntu-16.04'} + Clang 11: {TOOLSET: clang-11, PACKAGES: clang-11, LLVM_OS: focal, LLVM_VER: 11, VM_IMAGE: 'ubuntu-latest'} + Clang 10: {TOOLSET: clang-10, PACKAGES: clang-10, LLVM_OS: bionic, LLVM_VER: 10, VM_IMAGE: 'ubuntu-18.04'} + Clang 9: {TOOLSET: clang-9, PACKAGES: clang-9, LLVM_OS: bionic, LLVM_VER: 9, VM_IMAGE: 'ubuntu-18.04'} + Clang 8: {TOOLSET: clang-8, PACKAGES: clang-8, LLVM_OS: bionic, LLVM_VER: 8, VM_IMAGE: 'ubuntu-18.04'} + Clang 7: {TOOLSET: clang-7, PACKAGES: clang-7, LLVM_OS: bionic, LLVM_VER: 7, VM_IMAGE: 'ubuntu-18.04'} + Clang 6: {TOOLSET: clang-6.0, PACKAGES: clang-6.0, LLVM_OS: bionic, LLVM_VER: 6.0, VM_IMAGE: 'ubuntu-18.04'} + Clang 5: {TOOLSET: clang-5.0, PACKAGES: clang-5.0, LLVM_OS: bionic, LLVM_VER: 5.0, VM_IMAGE: 'ubuntu-18.04'} + Clang 4: {TOOLSET: clang-4.0, PACKAGES: clang-4.0, LLVM_OS: xenial, LLVM_VER: 4.0, VM_IMAGE: 'ubuntu-16.04'} + Clang 3.9: {TOOLSET: clang-3.9, PACKAGES: clang-3.9, VM_IMAGE: 'ubuntu-16.04'} + Clang 3.8: {TOOLSET: clang-3.8, PACKAGES: clang-3.8, VM_IMAGE: 'ubuntu-16.04'} + Clang 3.7: {TOOLSET: clang-3.7, PACKAGES: clang-3.7, VM_IMAGE: 'ubuntu-16.04'} + Clang 3.6: {TOOLSET: clang-3.6, PACKAGES: clang-3.6, VM_IMAGE: 'ubuntu-16.04'} + Clang 3.5: {TOOLSET: clang-3.5, PACKAGES: clang-3.5, VM_IMAGE: 'ubuntu-16.04'} pool: vmImage: $(VM_IMAGE) steps: diff --git a/src/engine/build.sh b/src/engine/build.sh index 2d7d972f3..dae3e1859 100755 --- a/src/engine/build.sh +++ b/src/engine/build.sh @@ -131,8 +131,8 @@ test_compiler () test_toolset () { - if test "${B2_TOOLSET}" = "" ; then return ${TRUE} ; fi - if test "${B2_TOOLSET}" = "$1" -o "${B2_TOOLSET}" = "$2" -o "${B2_TOOLSET}" = "$3" ; then return ${TRUE} ; fi + if test "${TOOLSET}" = "" ; then return ${TRUE} ; fi + if test "${TOOLSET}" = "$1" -o "${TOOLSET}" = "$2" -o "${TOOLSET}" = "$3" ; then return ${TRUE} ; fi return 1 } @@ -151,15 +151,18 @@ test_toolset () # check_toolset () { + TOOLSET=${B2_TOOLSET%%-*} + TOOLSET_SUFFIX=${B2_TOOLSET##$TOOLSET} + # Prefer Clang (clang) on macOS.. - if test_toolset clang && test_uname Darwin && test_compiler clang++ -x c++ -std=c++11 ; then B2_TOOLSET=clang ; return ${TRUE} ; fi + if test_toolset clang && test_uname Darwin && test_compiler clang++$TOOLSET_SUFFIX -x c++ -std=c++11 ; then B2_TOOLSET=clang$TOOLSET_SUFFIX ; return ${TRUE} ; fi # GCC (gcc).. - if test_toolset gcc && test_compiler g++ -x c++ -std=c++11 ; then B2_TOOLSET=gcc ; return ${TRUE} ; fi - if test_toolset gcc && test_compiler g++ -x c++ -std=c++11 -D_GNU_SOURCE ; then B2_TOOLSET=gcc ; return ${TRUE} ; fi + if test_toolset gcc && test_compiler g++$TOOLSET_SUFFIX -x c++ -std=c++11 ; then B2_TOOLSET=gcc$TOOLSET_SUFFIX ; return ${TRUE} ; fi + if test_toolset gcc && test_compiler g++$TOOLSET_SUFFIX -x c++ -std=c++11 -D_GNU_SOURCE ; then B2_TOOLSET=gcc$TOOLSET_SUFFIX ; return ${TRUE} ; fi # GCC (gcc) with -pthread arg (for AIX).. - if test_toolset gcc && test_compiler g++ -x c++ -std=c++11 -pthread ; then B2_TOOLSET=gcc ; return ${TRUE} ; fi + if test_toolset gcc && test_compiler g++$TOOLSET_SUFFIX -x c++ -std=c++11 -pthread ; then B2_TOOLSET=gcc$TOOLSET_SUFFIX ; return ${TRUE} ; fi # Clang (clang).. - if test_toolset clang && test_compiler clang++ -x c++ -std=c++11 ; then B2_TOOLSET=clang ; return ${TRUE} ; fi + if test_toolset clang && test_compiler clang++$TOOLSET_SUFFIX -x c++ -std=c++11 ; then B2_TOOLSET=clang$TOOLSET_SUFFIX ; return ${TRUE} ; fi # Intel macOS (intel-darwin) if test_toolset intel-darwin && test -r "${HOME}/intel/oneapi/setvars.sh" && test_uname Darwin ; then B2_SETUP="source ${HOME}/intel/oneapi/setvars.sh" @@ -318,7 +321,7 @@ fi # Set the additional options needed to build the engine based on the toolset. case "${B2_TOOLSET}" in - gcc) + gcc|gcc-*) CXX_VERSION_OPT=${CXX_VERSION_OPT:---version} B2_CXXFLAGS_RELEASE="-O2 -s" B2_CXXFLAGS_DEBUG="-O0 -g" @@ -384,7 +387,7 @@ case "${B2_TOOLSET}" in B2_CXXFLAGS_DEBUG="-g" ;; - clang*) + clang|clang-*) CXX_VERSION_OPT=${CXX_VERSION_OPT:---version} B2_CXXFLAGS_RELEASE="-O3 -s" B2_CXXFLAGS_DEBUG="-O0 -fno-inline -g" diff --git a/src/tools/clang-linux.jam b/src/tools/clang-linux.jam index 80cd96cfb..5a4581c02 100644 --- a/src/tools/clang-linux.jam +++ b/src/tools/clang-linux.jam @@ -108,12 +108,22 @@ rule init ( version ? : command * : options * ) { rule get-full-version ( command-string ) { - return [ gcc.get-full-version $(command-string) ] ; + return [ common.match-command-output version : "version ([0-9.]+)" + : "$(command-string) --version" ] ; } -rule get-short-version ( command-string ) +rule get-short-version ( command-string : single-digit-since ? ) { - return [ gcc.get-short-version $(command-string) : 4 ] ; + local version = [ get-full-version $(command-string) ] ; + version = [ SPLIT_BY_CHARACTERS $(version) : . ] ; + + import version ; + if [ version.version-less $(version) : $(single-digit-since:E=4) ] + { + return $(version[1-2]:J=.) ; + } + + return $(version[1]) ; } ############################################################################### diff --git a/src/tools/common.jam b/src/tools/common.jam index 705a1986f..804fb01a3 100644 --- a/src/tools/common.jam +++ b/src/tools/common.jam @@ -1155,6 +1155,25 @@ rule find-compiler ( toolset : tool : version ? : command * : additional-paths * return $(command) ; } +rule match-command-output ( kind ? : pattern : command-string ) +{ + local output = [ SHELL $(command-string) : exit-status ] ; + if 0 != $(output[2]) + { + errors.error '$(command-string)' + exited with error code $(output[2]) ; + } + + local match = [ MATCH $(pattern) : $(output[1]) ] ; + if ! $(match) + { + errors.error '$(command-string)' + returned an invalid $kind string '$(output[1])' ; + } + + return $(match) ; +} + rule __test__ ( ) { import assert ; diff --git a/src/tools/gcc.jam b/src/tools/gcc.jam index 332595fc4..f48a00dc9 100644 --- a/src/tools/gcc.jam +++ b/src/tools/gcc.jam @@ -289,36 +289,18 @@ if [ os.name ] = NT JAMSHELL = % ; } -local rule get-version ( command-string ) -{ - local output = [ SHELL $(command-string) : exit-status ] ; - if 0 != $(output[2]) - { - errors.error '$(command-string)' - exited with error code $(output[2]) ; - } - - local version = [ MATCH "^([0-9.]+)" : $(output[1]) ] ; - if ! $(version) - { - errors.error '$(command-string)' - returned an invalid version string '$(output[1])' ; - } - - return $(version) ; -} - rule get-full-version ( command-string ) { # -dumpfullversion is only supported for gcc 7+. # Passing both options works, as the first one that's # recognized will be used. - return [ get-version "$(command-string) -dumpfullversion -dumpversion" ] ; + return [ common.match-command-output version : "^([0-9.]+)" + : "$(command-string) -dumpfullversion -dumpversion" ] ; } rule get-short-version ( command-string : single-digit-since ? ) { - local version = [ get-version "$(command-string) -dumpversion" ] ; + local version = [ get-full-version $(command-string) ] ; version = [ SPLIT_BY_CHARACTERS $(version) : . ] ; import version ; diff --git a/test/BoostBuild.py b/test/BoostBuild.py index c729643dc..be44cea7f 100644 --- a/test/BoostBuild.py +++ b/test/BoostBuild.py @@ -113,6 +113,20 @@ elif windows: elif hasattr(os, "uname"): default_os = os.uname()[0].lower() + +def expand_toolset(toolset, target_os=default_os): + match = re.match(r'^(clang|intel)(-[\d\.]+|)$', toolset) + if match: + if match.group(1) == "intel" and target_os == "windows": + return match.expand(r'\1-win\2') + elif target_os == "darwin": + return match.expand(r'\1-darwin\2') + else: + return match.expand(r'\1-linux\2') + + return toolset + + def prepare_prefixes_and_suffixes(toolset, target_os=default_os): ind = toolset.find('-') if ind == -1: @@ -258,6 +272,7 @@ class Tester(TestCmd.TestCmd): self.use_test_config = use_test_config self.toolset = get_toolset() + self.expanded_toolset = expand_toolset(self.toolset) self.pass_toolset = pass_toolset self.ignore_toolset_requirements = ignore_toolset_requirements @@ -318,6 +333,7 @@ class Tester(TestCmd.TestCmd): def set_toolset(self, toolset, target_os=default_os): self.toolset = toolset + self.expanded_toolset = expand_toolset(toolset, target_os) self.pass_toolset = True prepare_prefixes_and_suffixes(toolset, target_os) @@ -401,7 +417,7 @@ class Tester(TestCmd.TestCmd): n = glob.glob(self.native_file_name(name)) if n: n = n[0] if not n: - n = self.glob_file(name.replace("$toolset", self.toolset + "*") + n = self.glob_file(name.replace("$toolset", self.expanded_toolset + "*") ) if n: if os.path.isdir(n): @@ -420,7 +436,7 @@ class Tester(TestCmd.TestCmd): toolset currently being tested. """ - self.write(name, self.read(name).replace("$toolset", self.toolset)) + self.write(name, self.read(name).replace("$toolset", self.expanded_toolset)) def dump_stdio(self): annotation("STDOUT", self.stdout()) @@ -758,7 +774,7 @@ class Tester(TestCmd.TestCmd): def expect_content(self, name, content, exact=False): actual = self.read(name) - content = content.replace("$toolset", self.toolset + "*") + content = content.replace("$toolset", self.expanded_toolset + "*") matched = False if exact: @@ -852,7 +868,7 @@ class Tester(TestCmd.TestCmd): names = [names] r = map(self.adjust_lib_name, names) r = map(self.adjust_suffix, r) - r = map(lambda x, t=self.toolset: x.replace("$toolset", t + "*"), r) + r = map(lambda x, t=self.expanded_toolset: x.replace("$toolset", t + "*"), r) return list(r) def adjust_name(self, name):