diff --git a/.ci/azp-macos-test.yml b/.ci/azp-macos-test.yml index b30b1eac9..e947c0fa4 100644 --- a/.ci/azp-macos-test.yml +++ b/.ci/azp-macos-test.yml @@ -4,25 +4,11 @@ parameters: default: '' steps: -- bash: | - set -e - uname -a - ls -laF /Applications - sudo xcode-select -switch ${XCODE_APP} - which clang++ +- bash: ./.ci/macos-install.sh displayName: Install -- bash: | - set -e - cd src/engine - ./build.sh ${TOOLSET} - ./b2 -v - cd ../.. +- bash: ./.ci/macos-build.sh displayName: Build -- bash: | - set -e - cd test - ./test_all.py ${TOOLSET} - cd .. +- bash: ./.ci/macos-test.sh displayName: Test - bash: | set -e diff --git a/.ci/macos-build.sh b/.ci/macos-build.sh new file mode 100755 index 000000000..a533a2091 --- /dev/null +++ b/.ci/macos-build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -e +cd src/engine +./build.sh ${TOOLSET} +./b2 -v +cd ../.. diff --git a/.ci/macos-install.sh b/.ci/macos-install.sh new file mode 100755 index 000000000..7ea0870fc --- /dev/null +++ b/.ci/macos-install.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -e +uname -a +ls -laF /Applications +sudo xcode-select -switch ${XCODE_APP} +which clang++ diff --git a/.ci/macos-test.sh b/.ci/macos-test.sh new file mode 100755 index 000000000..f1daaf43e --- /dev/null +++ b/.ci/macos-test.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e +cd test +./test_all.py ${TOOLSET} +cd .. diff --git a/.cirrus.yml b/.cirrus.yml index e80e485a2..4984f46b2 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -8,22 +8,25 @@ freebsd_task: skip: "changesIncludeOnly('.ci/azp-*', 'appveyor.yml', 'azure-pipelines.yml', '*.adoc')" # All the GCC's and Clang's currently supported by FreeBSD ports. matrix: - - { name: 'FreeBSD, GCC 14', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++14', PACKAGE: 'lang/gcc14' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, GCC 13', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++13', PACKAGE: 'gcc13' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, GCC 12', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++12', PACKAGE: 'gcc12' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, GCC 11', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++11', PACKAGE: 'gcc11' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - # - { name: 'FreeBSD, GCC 10', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++10', PACKAGE: 'gcc10' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - # - { name: 'FreeBSD, GCC 9', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++9', PACKAGE: 'gcc9' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 19', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++19', PACKAGE: 'devel/llvm19' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 18', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++18', PACKAGE: 'devel/llvm18' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 17', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++17', PACKAGE: 'devel/llvm17' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 16', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++16', PACKAGE: 'devel/llvm16' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 15', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++15', PACKAGE: 'devel/llvm15' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 14', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++14', PACKAGE: 'devel/llvm14' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 13', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++13', PACKAGE: 'devel/llvm13' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 12', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++12', PACKAGE: 'devel/llvm12' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - - { name: 'FreeBSD, Clang 11', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++11', PACKAGE: 'devel/llvm11' }, freebsd_instance: { image_family: 'freebsd-14-2' } } - # - { name: 'FreeBSD, Clang 10', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++10', PACKAGE: 'devel/llvm10' }, freebsd_instance: { image_family: 'freebsd-14-2' } } + - { name: 'FreeBSD, GCC 15', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++15', PACKAGE: 'lang/gcc15' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, GCC 14', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++14', PACKAGE: 'lang/gcc14' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, GCC 13', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++13', PACKAGE: 'gcc13' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, GCC 12', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++12', PACKAGE: 'gcc12' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + # - { name: 'FreeBSD, GCC 11', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++11', PACKAGE: 'gcc11' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + # - { name: 'FreeBSD, GCC 10', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++10', PACKAGE: 'gcc10' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + # - { name: 'FreeBSD, GCC 9', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++9', PACKAGE: 'gcc9' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 21', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++21', PACKAGE: 'devel/llvm21' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 20', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++20', PACKAGE: 'devel/llvm20' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 19', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++19', PACKAGE: 'devel/llvm19' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 18', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++18', PACKAGE: 'devel/llvm18' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 17', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++17', PACKAGE: 'devel/llvm17' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 16', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++16', PACKAGE: 'devel/llvm16' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 15', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++15', PACKAGE: 'devel/llvm15' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 14', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++14', PACKAGE: 'devel/llvm14' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 13', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++13', PACKAGE: 'devel/llvm13' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 12', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++12', PACKAGE: 'devel/llvm12' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + - { name: 'FreeBSD, Clang 11', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++11', PACKAGE: 'devel/llvm11' }, freebsd_instance: { image_family: 'freebsd-14-3' } } + # - { name: 'FreeBSD, Clang 10', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++10', PACKAGE: 'devel/llvm10' }, freebsd_instance: { image_family: 'freebsd-14-3' } } # To install with ports we need to initialize the package manager. To avoid # confirmation prompts we need to set an env var. install_script: [ diff --git a/.editorconfig b/.editorconfig index dd3e9379f..ceb5432a6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -28,3 +28,6 @@ indent_style = space [.clangd] indent_size = 2 indent_style = space + +[*.py] +indent_style = space diff --git a/.github/workflows/qemu_multiarch_linux.yml b/.github/workflows/qemu_multiarch_linux.yml index 08d20ab40..735e07561 100644 --- a/.github/workflows/qemu_multiarch_linux.yml +++ b/.github/workflows/qemu_multiarch_linux.yml @@ -57,6 +57,7 @@ jobs: } name: ${{ matrix.name }} runs-on: ubuntu-latest + timeout-minutes: 60 env: CXX: ${{ matrix.cxx }} CXXFLAGS: ${{ matrix.cxxflags }} diff --git a/.vscode/launch.json b/.vscode/launch.json index bcc092770..81010ec8a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,25 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/.build/gcc-15/debug/cxxstd-11-iso/threading-multi/b2", + "args": ["-d9"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/example/hello", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, { "name": "(gdb) Pipe Launch", "type": "cppdbg", @@ -17,10 +36,7 @@ "pipeTransport": { "debuggerPath": "/usr/local/bin/gdb", "pipeProgram": "/usr/bin/ssh", - "pipeArgs": [ - "-v", - "root@192.168.13.163" - ], + "pipeArgs": ["-v", "root@192.168.13.163"], "pipeCwd": "" }, "MIMode": "gdb", @@ -40,9 +56,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}\\.build\\gcc-10\\debug\\cxxstd-11-iso\\b2.exe", - "args": [ - "-v" - ], + "args": ["-v"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], @@ -67,9 +81,7 @@ "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}\\.build\\msvc-14.3\\debug\\cxxstd-11-iso\\threading-multi\\b2.exe", - "args": [ - "-ftest.jam" - ], + "args": ["-ftest.jam"], "stopAtEntry": false, "cwd": "${workspaceFolder}\\test", "environment": [ @@ -84,11 +96,7 @@ "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}\\.build\\msvc-14.3\\debug\\cxxstd-11-iso\\threading-multi\\b2.exe", - "args": [ - "--debug", - "--build-system=test/test", - "-j1" - ], + "args": ["--debug", "--build-system=test/test", "-j1"], "stopAtEntry": false, "cwd": "${workspaceFolder}\\test", "environment": [] @@ -98,9 +106,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/.build/gcc-14/debug/cxxstd-11-iso/threading-multi/b2", - "args": [ - "-h" - ], + "args": ["-h"], "stopAtEntry": false, "cwd": "${workspaceFolder}/example/hello", "environment": [], @@ -119,14 +125,10 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/.build/gcc-14/debug/address-sanitizer-on/cxxstd-11-iso/threading-multi/b2", - "args": [ - "-n", - "-a" - ], + "args": ["-n", "-a"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { @@ -194,18 +196,13 @@ "name": "(rr) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/.build/gcc-14/debug/cxxstd-11-iso/b2", - "args": [ - "--grep" - ], + "program": "${workspaceFolder}/.build/gcc-15/debug/cxxstd-11-iso/threading-multi/b2", + "args": ["-d9"], "stopAtEntry": false, - "cwd": "${workspaceFolder}", + "cwd": "${workspaceFolder}/example/hello", "environment": [], "externalConsole": true, "MIMode": "gdb", - "miDebuggerServerAddress": "localhost:50505", - // "miDebuggerPath": "rr", - // "miDebuggerArgs": "replay -s 50505", "setupCommands": [ { "description": "Setup to resolve symbols", @@ -220,4 +217,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/README.adoc b/README.adoc index c7e36fc16..0a6ad492d 100644 --- a/README.adoc +++ b/README.adoc @@ -14,11 +14,11 @@ file LICENSE.txt or copy at https://www.bfgroup.xyz/b2/LICENSE.txt) Continuously tested on: -* FreeBSD Clang 11, 12, 13, 14, 15, 16, 17, 18, 19 -* FreeBSD 10, 11, 12, 13, 14 -* Linux Clang 3.9, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 -* Linux GCC 4.8, 4.9, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 -* macOS Xcode 14.1, 14.2, 14.3.1, 15.4, 16.0 +* FreeBSD Clang 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 +* FreeBSD GCC 12, 13, 14, 15 +* Linux Clang 3.9, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 +* Linux GCC 4.8, 4.9, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +* macOS Xcode 13.4.1, 14.3.0, 15.4, 16.4, 26.0.1 * Windows MinGW 8.1.0 * Windows 2015, 2017, 2019, 2022 * Windows MSYS2 MinGW64/32 Clang-16, MinGW64/32 GCC-13 diff --git a/appveyor.yml b/appveyor.yml index f456e0a76..6e3c02f99 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,60 +23,80 @@ skip_commits: environment: matrix: + - job_name: 'Xcode 14.3.0' + job_build: 'XcodeBuild' + job_test: 'XcodeTest' + XCODE_APP: /Applications/Xcode-14.3.0.app + APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma + - job_name: 'Xcode 13.4.1' + job_build: 'XcodeBuild' + job_test: 'XcodeTest' + XCODE_APP: /Applications/Xcode-13.4.1.app + APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma - job_name: 'Visual Studio 2022, Test' - job_group: 'Test' + job_build: 'WindowsBuild' + job_test: 'WindowsTest' TOOLSET: vc143 TEST_TOOLSET: msvc-14.3 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - job_name: 'Visual Studio 2019, Test' - job_group: 'Test' + job_build: 'WindowsBuild' + job_test: 'WindowsTest' TOOLSET: vc142 TEST_TOOLSET: msvc-14.2 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - job_name: 'Visual Studio 2017, Test' - job_group: 'Test' + job_build: 'WindowsBuild' + job_test: 'WindowsTest' TOOLSET: vc141 TEST_TOOLSET: msvc-14.1 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - job_name: 'Visual Studio 2015, Test' - job_group: 'Test' + job_build: 'WindowsBuild' + job_test: 'WindowsTest' TOOLSET: vc14 TEST_TOOLSET: msvc-14.0 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - job_name: 'Clang 18 (VS2022), Test' - job_group: 'Test' + job_build: 'WindowsBuild' + job_test: 'WindowsTest' TOOLSET: clang-win TEST_TOOLSET: clang-win B2_DONT_EMBED_MANIFEST: true # lld-link: error: unable to find mt.exe in PATH: no such file or directory APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - job_name: 'Clang 9 (VS2015), Test' - job_group: 'Test' + job_build: 'WindowsBuild' + job_test: 'WindowsTest' TOOLSET: clang-win TEST_TOOLSET: clang-win B2_DONT_EMBED_MANIFEST: true # lld-link: error: unable to find mt.exe in PATH: no such file or directory APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - job_name: 'Cygwin 3.4.6 x64, Test' - job_group: 'TestCygwin' + job_build: 'WindowsBuild' + job_test: 'CygwinTest' TOOLSET: gcc TEST_TOOLSET: gcc APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 B2_CXX_PATH: C:/cygwin64/bin -build_script: - - cmd: | - cd src/engine - set PATH=%B2_CXX_PATH%;%PATH% - - cmd: | - ./build.bat %TOOLSET% - - cmd: | - cd ../.. - src\engine\b2.exe -v - for: + - matrix: only: - - job_group: 'Test' + - job_build: 'WindowsBuild' + build_script: + - cmd: | + cd src/engine + set PATH=%B2_CXX_PATH%;%PATH% + - cmd: | + ./build.bat %TOOLSET% + - cmd: | + cd ../.. + src\engine\b2.exe -v + - matrix: + only: + - job_test: 'WindowsTest' test_script: - cmd: | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" @@ -96,3 +116,13 @@ for: echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" bootstrap.bat %TOOLSET% b2.exe --debug-configuration --prefix=./.b2 install toolset=%TEST_TOOLSET% + + - matrix: + only: + - job_build: 'XcodeBuild' + install: + - ./.ci/macos-install.sh + build_script: + - ./.ci/macos-build.sh + test_script: + - ./.ci/macos-test.sh diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 82a60a6ab..1cdbe1db5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -34,12 +34,12 @@ variables: - { name: linux_latest_vm, value: 'ubuntu-24.04' } - { name: linux_latest_os, value: 'noble' } - { name: windows_latest_vm, value: 'windows-2022' } -- { name: clang_latest, value: '20' } +- { name: clang_latest, value: '21' } - { name: clang_latest_libstdcxx, value: '12' } - { name: gcc_latest, value: '14' } - { name: vc_latest, value: 'vc143' } - { name: vs_latest, value: '2022' } -- { name: xc_latest, value: '16.0' } +- { name: xc_latest, value: '16.4' } - { name: macos_latest_vm, value: 'macOS-15' } - { name: co_options, value: '--name container' } @@ -76,6 +76,7 @@ resources: - { container: linux_gcc5, image: 'teeks99/gcc-ubuntu:5', options: "${{variables.co_options}}" } - { container: linux_gcc49, image: 'teeks99/gcc-ubuntu:4.9', options: "${{variables.co_options}}" } - { container: linux_gcc48, image: 'teeks99/gcc-ubuntu:4.8', options: "${{variables.co_options}}" } + - { container: linux_clang21, image: 'teeks99/clang-ubuntu:21', options: "${{variables.co_options}}" } - { container: linux_clang20, image: 'teeks99/clang-ubuntu:20', options: "${{variables.co_options}}" } - { container: linux_clang19, image: 'teeks99/clang-ubuntu:19', options: "${{variables.co_options}}" } - { container: linux_clang18, image: 'teeks99/clang-ubuntu:18', options: "${{variables.co_options}}" } @@ -268,6 +269,8 @@ stages: - job: 'Co_Linux' strategy: matrix: + GCC 15: {CXX: g++-15, TOOLSET: gcc-15, CONTAINER: "linux_gcc15"} + GCC 14: {CXX: g++-14, TOOLSET: gcc-14, CONTAINER: "linux_gcc14"} GCC 13: {CXX: g++-13, TOOLSET: gcc-13, CONTAINER: "linux_gcc13"} GCC 12: {CXX: g++-12, TOOLSET: gcc-12, CONTAINER: "linux_gcc12"} GCC 11: {CXX: g++-11, TOOLSET: gcc-11, CONTAINER: "linux_gcc11"} @@ -279,6 +282,8 @@ stages: GCC 5: {CXX: g++-5, TOOLSET: gcc-5, CONTAINER: "linux_gcc5"} GCC 4.9: {CXX: g++-4.9, TOOLSET: gcc-4.9, CONTAINER: "linux_gcc49"} GCC 4.8: {CXX: g++-4.8, TOOLSET: gcc-4.8, CONTAINER: "linux_gcc48"} + Clang 21: {CXX: clang++-21, TOOLSET: clang-21, CONTAINER: "linux_clang21"} + Clang 20: {CXX: clang++-20, TOOLSET: clang-20, CONTAINER: "linux_clang20"} Clang 19: {CXX: clang++-19, TOOLSET: clang-19, CONTAINER: "linux_clang19"} Clang 18: {CXX: clang++-18, TOOLSET: clang-18, CONTAINER: "linux_clang18"} Clang 17: {CXX: clang++-17, TOOLSET: clang-17, CONTAINER: "linux_clang17"} @@ -312,8 +317,8 @@ stages: - job: 'Windows' strategy: matrix: - # VS 2022: {TOOLSET: vc143, TEST_TOOLSET: msvc, VM_IMAGE: 'windows-2022'} - VS 2019: {TOOLSET: vc142, TEST_TOOLSET: msvc, VM_IMAGE: 'windows-2019'} + VS 2022: {TOOLSET: vc143, TEST_TOOLSET: msvc, VM_IMAGE: 'windows-2025'} + # VS 2019: {TOOLSET: vc142, TEST_TOOLSET: msvc, VM_IMAGE: 'windows-2019'} # MinGW 8.1.0: {TOOLSET: mingw, TEST_TOOLSET: gcc, VM_IMAGE: 'windows-2022'} pool: vmImage: $(VM_IMAGE) @@ -323,10 +328,12 @@ stages: - job: 'macOS' strategy: matrix: + Xcode 26.0.1: {XCODE_APP: /Applications/Xcode_26.0.1.app, VM_IMAGE: 'macOS-15'} + # Xcode 16.3: {XCODE_APP: /Applications/Xcode_16.3.app, VM_IMAGE: 'macOS-15'} Xcode 15.4: {XCODE_APP: /Applications/Xcode_15.4.app, VM_IMAGE: 'macOS-14'} - Xcode 14.3.1: {XCODE_APP: /Applications/Xcode_14.3.1.app, VM_IMAGE: 'macOS-13'} - Xcode 14.2: {XCODE_APP: /Applications/Xcode_14.2.app, VM_IMAGE: 'macOS-13'} - Xcode 14.1: {XCODE_APP: /Applications/Xcode_14.1.app, VM_IMAGE: 'macOS-13'} + # Xcode 14.3.1: {XCODE_APP: /Applications/Xcode_14.3.1.app, VM_IMAGE: 'macOS-13'} + # Xcode 14.2: {XCODE_APP: /Applications/Xcode_14.2.app, VM_IMAGE: 'macOS-13'} + # Xcode 14.1: {XCODE_APP: /Applications/Xcode_14.1.app, VM_IMAGE: 'macOS-13'} # Xcode 14.0.1: {XCODE_APP: /Applications/Xcode_14.0.1.app, VM_IMAGE: 'macOS-12'} # Xcode 13.4.1: {XCODE_APP: /Applications/Xcode_13.4.1.app, VM_IMAGE: 'macOS-12'} # Xcode 12.5.1: {XCODE_APP: /Applications/Xcode_12.5.1.app, VM_IMAGE: 'macOS-11'} @@ -445,26 +452,30 @@ stages: displayName: 'Release Linux' strategy: matrix: - 1.86.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.86.0, BOOST_VERSION_U: 1_86_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.85.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.85.0, BOOST_VERSION_U: 1_85_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + 1.90.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.90.0, BOOST_VERSION_U: 1_90_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.89.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.89.0, BOOST_VERSION_U: 1_89_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.88.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.88.0, BOOST_VERSION_U: 1_88_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + 1.87.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.87.0, BOOST_VERSION_U: 1_87_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.86.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.86.0, BOOST_VERSION_U: 1_86_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.85.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.85.0, BOOST_VERSION_U: 1_85_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} 1.84.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.84.0, BOOST_VERSION_U: 1_84_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.83.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.83.0, BOOST_VERSION_U: 1_83_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.82.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.82.0, BOOST_VERSION_U: 1_82_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.83.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.83.0, BOOST_VERSION_U: 1_83_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.82.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.82.0, BOOST_VERSION_U: 1_82_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} 1.81.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.81.0, BOOST_VERSION_U: 1_81_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.80.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.80.0, BOOST_VERSION_U: 1_80_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.79.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.79.0, BOOST_VERSION_U: 1_79_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.80.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.80.0, BOOST_VERSION_U: 1_80_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.79.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.79.0, BOOST_VERSION_U: 1_79_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} 1.78.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.78.0, BOOST_VERSION_U: 1_78_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.77.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.77.0, BOOST_VERSION_U: 1_77_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.76.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.76.0, BOOST_VERSION_U: 1_76_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.77.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.77.0, BOOST_VERSION_U: 1_77_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.76.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.76.0, BOOST_VERSION_U: 1_76_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} 1.75.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.75.0, BOOST_VERSION_U: 1_75_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.74.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.74.0, BOOST_VERSION_U: 1_74_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.73.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.73.0, BOOST_VERSION_U: 1_73_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.74.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.74.0, BOOST_VERSION_U: 1_74_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.73.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.73.0, BOOST_VERSION_U: 1_73_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} 1.72.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.72.0, BOOST_VERSION_U: 1_72_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.71.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.71.0, BOOST_VERSION_U: 1_71_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.70.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.70.0, BOOST_VERSION_U: 1_70_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.71.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.71.0, BOOST_VERSION_U: 1_71_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.70.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.70.0, BOOST_VERSION_U: 1_70_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} 1.69.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.69.0, BOOST_VERSION_U: 1_69_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.68.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.68.0, BOOST_VERSION_U: 1_68_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} - 1.67.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.67.0, BOOST_VERSION_U: 1_67_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.68.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.68.0, BOOST_VERSION_U: 1_68_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} + # 1.67.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.67.0, BOOST_VERSION_U: 1_67_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} 1.66.0 .. GCC ${{variables.gcc_latest}}: {BOOST_VERSION: 1.66.0, BOOST_VERSION_U: 1_66_0, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"} pool: vmImage: $(VM_IMAGE) @@ -497,26 +508,30 @@ stages: vmImage: "${{variables.macos_latest_vm}}" strategy: matrix: - 1.86.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.86.0, BOOST_VERSION_U: 1_86_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.85.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.85.0, BOOST_VERSION_U: 1_85_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + 1.90.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.90.0, BOOST_VERSION_U: 1_90_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.89.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.89.0, BOOST_VERSION_U: 1_89_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.88.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.88.0, BOOST_VERSION_U: 1_88_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + 1.87.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.87.0, BOOST_VERSION_U: 1_87_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.86.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.86.0, BOOST_VERSION_U: 1_86_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.85.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.85.0, BOOST_VERSION_U: 1_85_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} 1.84.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.84.0, BOOST_VERSION_U: 1_84_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.83.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.83.0, BOOST_VERSION_U: 1_83_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.82.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.82.0, BOOST_VERSION_U: 1_82_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.83.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.83.0, BOOST_VERSION_U: 1_83_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.82.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.82.0, BOOST_VERSION_U: 1_82_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} 1.81.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.81.0, BOOST_VERSION_U: 1_81_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.80.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.80.0, BOOST_VERSION_U: 1_80_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.79.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.79.0, BOOST_VERSION_U: 1_79_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.80.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.80.0, BOOST_VERSION_U: 1_80_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.79.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.79.0, BOOST_VERSION_U: 1_79_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} 1.78.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.78.0, BOOST_VERSION_U: 1_78_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.77.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.77.0, BOOST_VERSION_U: 1_77_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.76.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.76.0, BOOST_VERSION_U: 1_76_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.77.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.77.0, BOOST_VERSION_U: 1_77_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.76.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.76.0, BOOST_VERSION_U: 1_76_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} 1.75.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.75.0, BOOST_VERSION_U: 1_75_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.74.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.74.0, BOOST_VERSION_U: 1_74_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.73.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.73.0, BOOST_VERSION_U: 1_73_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.74.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.74.0, BOOST_VERSION_U: 1_74_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.73.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.73.0, BOOST_VERSION_U: 1_73_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} 1.72.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.72.0, BOOST_VERSION_U: 1_72_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.71.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.71.0, BOOST_VERSION_U: 1_71_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.70.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.70.0, BOOST_VERSION_U: 1_70_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.71.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.71.0, BOOST_VERSION_U: 1_71_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.70.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.70.0, BOOST_VERSION_U: 1_70_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} 1.69.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.69.0, BOOST_VERSION_U: 1_69_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.68.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.68.0, BOOST_VERSION_U: 1_68_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} - 1.67.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.67.0, BOOST_VERSION_U: 1_67_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.68.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.68.0, BOOST_VERSION_U: 1_68_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} + # 1.67.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.67.0, BOOST_VERSION_U: 1_67_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} 1.66.0 .. Xcode ${{variables.xc_latest}}: {BOOST_VERSION: 1.66.0, BOOST_VERSION_U: 1_66_0, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"} steps: - bash: | @@ -548,26 +563,30 @@ stages: vmImage: "${{variables.windows_latest_vm}}" strategy: matrix: - 1.86.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.86.0, BOOST_VERSION_U: 1_86_0, TOOLSET: "${{variables.vc_latest}}"} - 1.85.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.85.0, BOOST_VERSION_U: 1_85_0, TOOLSET: "${{variables.vc_latest}}"} + 1.90.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.90.0, BOOST_VERSION_U: 1_90_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.89.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.89.0, BOOST_VERSION_U: 1_89_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.88.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.88.0, BOOST_VERSION_U: 1_88_0, TOOLSET: "${{variables.vc_latest}}"} + 1.87.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.87.0, BOOST_VERSION_U: 1_87_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.86.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.86.0, BOOST_VERSION_U: 1_86_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.85.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.85.0, BOOST_VERSION_U: 1_85_0, TOOLSET: "${{variables.vc_latest}}"} 1.84.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.84.0, BOOST_VERSION_U: 1_84_0, TOOLSET: "${{variables.vc_latest}}"} - 1.83.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.83.0, BOOST_VERSION_U: 1_83_0, TOOLSET: "${{variables.vc_latest}}"} - 1.82.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.82.0, BOOST_VERSION_U: 1_82_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.83.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.83.0, BOOST_VERSION_U: 1_83_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.82.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.82.0, BOOST_VERSION_U: 1_82_0, TOOLSET: "${{variables.vc_latest}}"} 1.81.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.81.0, BOOST_VERSION_U: 1_81_0, TOOLSET: "${{variables.vc_latest}}"} - 1.80.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.80.0, BOOST_VERSION_U: 1_80_0, TOOLSET: "${{variables.vc_latest}}"} - 1.79.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.79.0, BOOST_VERSION_U: 1_79_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.80.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.80.0, BOOST_VERSION_U: 1_80_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.79.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.79.0, BOOST_VERSION_U: 1_79_0, TOOLSET: "${{variables.vc_latest}}"} 1.78.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.78.0, BOOST_VERSION_U: 1_78_0, TOOLSET: "${{variables.vc_latest}}"} - 1.77.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.77.0, BOOST_VERSION_U: 1_77_0, TOOLSET: "${{variables.vc_latest}}"} - 1.76.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.76.0, BOOST_VERSION_U: 1_76_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.77.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.77.0, BOOST_VERSION_U: 1_77_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.76.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.76.0, BOOST_VERSION_U: 1_76_0, TOOLSET: "${{variables.vc_latest}}"} 1.75.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.75.0, BOOST_VERSION_U: 1_75_0, TOOLSET: "${{variables.vc_latest}}"} - 1.74.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.74.0, BOOST_VERSION_U: 1_74_0, TOOLSET: "${{variables.vc_latest}}"} - 1.73.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.73.0, BOOST_VERSION_U: 1_73_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.74.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.74.0, BOOST_VERSION_U: 1_74_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.73.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.73.0, BOOST_VERSION_U: 1_73_0, TOOLSET: "${{variables.vc_latest}}"} 1.72.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.72.0, BOOST_VERSION_U: 1_72_0, TOOLSET: "${{variables.vc_latest}}"} - 1.71.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.71.0, BOOST_VERSION_U: 1_71_0, TOOLSET: "${{variables.vc_latest}}"} - 1.70.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.70.0, BOOST_VERSION_U: 1_70_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.71.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.71.0, BOOST_VERSION_U: 1_71_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.70.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.70.0, BOOST_VERSION_U: 1_70_0, TOOLSET: "${{variables.vc_latest}}"} 1.69.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.69.0, BOOST_VERSION_U: 1_69_0, TOOLSET: "${{variables.vc_latest}}"} - 1.68.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.68.0, BOOST_VERSION_U: 1_68_0, TOOLSET: "${{variables.vc_latest}}"} - 1.67.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.67.0, BOOST_VERSION_U: 1_67_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.68.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.68.0, BOOST_VERSION_U: 1_68_0, TOOLSET: "${{variables.vc_latest}}"} + # 1.67.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.67.0, BOOST_VERSION_U: 1_67_0, TOOLSET: "${{variables.vc_latest}}"} 1.66.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.66.0, BOOST_VERSION_U: 1_66_0, TOOLSET: "${{variables.vc_latest}}"} steps: - powershell: | diff --git a/doc/jamfile.jam b/doc/jamfile.jam index c4f15f373..1dfc0735d 100644 --- a/doc/jamfile.jam +++ b/doc/jamfile.jam @@ -54,6 +54,7 @@ html index : src/standalone.adoc : # "-a stylesheet=amber.css" # "-a stylesdir=$(STYLES_DIR)" # linkcss + src/tufte.css ; explicit index ; diff --git a/doc/src/appendix.adoc b/doc/src/appendix.adoc index 1a78ca6ef..9d98ecb7d 100644 --- a/doc/src/appendix.adoc +++ b/doc/src/appendix.adoc @@ -3,7 +3,8 @@ = Licenses In addition to B2 being licensed under the Boost Software License - Version 1.0, -B2 makes use of additional libraries that are differently licensed as follows. +B2 makes use of additional libraries and sources that are differently licensed +as follows. == MIT License @@ -31,3 +32,7 @@ SOFTWARE. https://github.com/nlohmann/json[JSON for Modern C++]:: Copyright (c) 2013-2022 Niels Lohmann + +https://github.com/edwardtufte/tufte-css[Tufte CSS]:: +Copyright (c) Dave Liepmann, Edward Tufte, et al. The documentation style is +based on this CSS. diff --git a/doc/src/history.adoc b/doc/src/history.adoc index bcfc0066f..c3397ef21 100644 --- a/doc/src/history.adoc +++ b/doc/src/history.adoc @@ -1,6 +1,59 @@ [[b2.history]] = History +== Version 5.4.0 + +This is the end of year release. Biggest new items are the detection of +Visual Studio 2026 (aka msvc145). + +* *New*: Add initial support for {CPP}-26 Contracts for GCC based toolsets + (like clang). + -- _René Ferdinand Rivera Morell_ +* *New*: Allow explicit target `triple` for `clang-linux` and `clang-darwin`. + -- _Dmitry Arkhipov_ +* *New*: Change documentation style to support light/dark user preference. + -- _René Ferdinand Rivera Morell_ +* *New*: Added the ability to escape the '$' character before '(' as "$$" which + will allow using the "$()" and "$(())" expressions of bash, sh, and other + shells. + -- _Ivan Kotov_ +* *New*: Added integration for vcpkg with distinct roots. + -- _Dmitry Arkhipov_ +* *New*: Add support for detecting and building with VS-2026 (AKA vs-18.0, + aka msvc 14.5). + -- _Miuna_, _Zangetsu_, _René Ferdinand Rivera Morell_ +* Fix invoking asciidoctor on Windows. + -- _René Ferdinand Rivera Morell_ +* Fix, propagate `dll-path` to shared libraries. + -- _Dmitry Arkhipov_ +* Fix mpi compiler detection to detect not just the first one (`mpi++`). + -- _Samuel Debionne_ +* Fix flag options, that are not registered as args, not being recognized. + Fixes `--show-libraries` in Boost build files. + -- _Dmitry Arkhipov_ +* Fix discovery and building with Python free-threaded variant. + -- _Zhang Wen_ +* Fix build issues with QNX compiolers. + -- _"fragarian"_ +* Add `libstdc++` to `stdlib` feature as the current naming for that std + library. + -- _Dmitry Arkhipov_ +* Fix building when targetting WASM64 with emscripten. + -- _Uilian Ries_ +* Fix resolution of subprojects of rooted projects. + -- _Dmitry Arkhipov_ +* Fix crash when using `-d9` to output module debug stats. + -- _René Ferdinand Rivera Morell_ + +== Version 5.3.3 + +* Fix `stdlib=libc++` feature being applied to compiles other than {CPP}. + -- _Dmitry Arkhipov_ +* Fix silently ignored argument parsing errors. + -- _Dmitry Arkhipov_ +* Fix not allowing "/" in paths for msvc version detection. + -- _chausner_ + == Version 5.3.2 Fix regression for handling of the `--command-database` option. The new command diff --git a/doc/src/overview.adoc b/doc/src/overview.adoc index 86026d81b..b3ac3cc77 100644 --- a/doc/src/overview.adoc +++ b/doc/src/overview.adoc @@ -369,7 +369,7 @@ searched. Any of these files may also be overridden link:#b2.reference.init.options.config[on the command line]. -TIP: You can use the `--debug-configuration` option to find which +NOTE: You can use the `--debug-configuration` option to find which configuration files are actually loaded. Usually, `user-config.jam` just defines the available compilers and @@ -392,7 +392,7 @@ using gcc ; will make the http://gcc.gnu.org[GCC] compiler available. -TIP: You can put `using ;` with no other argument in a Jamfile +NOTE: You can put `using ;` with no other argument in a Jamfile that needs the `tool`, provided that the `tool` supports this usage. In all other cases, the `using` rule should be in a configuration file. The general principle is that descriptions in Jamfile should be diff --git a/doc/src/reference.adoc b/doc/src/reference.adoc index 4ef51d478..76fb92ee3 100644 --- a/doc/src/reference.adoc +++ b/doc/src/reference.adoc @@ -286,6 +286,7 @@ include::../../src/tools/features/warnings-feature.jam[tag=doc] include::../../src/tools/features/translate-path-feature.jam[tag=doc] include::../../src/tools/features/lto-feature.jam[tag=doc] include::../../src/tools/features/response-file-feature.jam[tag=doc] +include::../../src/tools/features/contracts-feature.jam[tag=doc] [[b2.reference.tools]] == Builtin tools diff --git a/doc/src/standalone.adoc b/doc/src/standalone.adoc index 37d2ceb26..4affd4999 100644 --- a/doc/src/standalone.adoc +++ b/doc/src/standalone.adoc @@ -2,11 +2,12 @@ :copyright: Copyright 2018-2025 René Ferdinand Rivera Morell; Copyright 2006, 2014 Vladimir Prus :author: René Ferdinand Rivera Morell, Vladimir Prus, Steven Watanabe :toc: left -:toclevels: 2 +:toclevels: 1 :sectanchors: :sectnums: :nofooter: -:stylesheet: amber.css +// :stylesheet: amber.css +:stylesheet: tufte.css :source-language: jam :caution-caption: ⚑ :important-caption: ‼ diff --git a/doc/src/tasks.adoc b/doc/src/tasks.adoc index f081c4667..cb3879c25 100644 --- a/doc/src/tasks.adoc +++ b/doc/src/tasks.adoc @@ -26,7 +26,7 @@ another library that is created by B2. Generally, sources can include C and {CPP} files, object files and libraries. B2 will automatically try to convert targets of other types. -TIP: On Windows, if an application uses shared libraries, and both the +WARNING: On Windows, if an application uses shared libraries, and both the application and the libraries are built using B2, it is not possible to immediately run the application, because the `PATH` environment variable should include the path to the libraries. It means you have to either @@ -77,7 +77,7 @@ location. The difference between using the `file` feature and using a combination of the `name` and `search` features is that `file` is more precise. -[WARNING] +[TIP] ==== The value of the `search` feature is just added to the linker search path. When linking to multiple libraries, the paths specified by @@ -127,7 +127,7 @@ lib z ; lib png : z : png ; ---- -[NOTE] +[TIP] ==== When a library has a shared library as a source, or a static library has another static library as a source then any target linking to the first @@ -727,6 +727,10 @@ managers. Currently the supported ones are: * Conan (`conan`): currently supports the link:https://docs.conan.io/en/latest/reference/generators/b2.html[`b2 generator`]. +:leveloffset: +1 +include::../../src/tools/vcpkg.jam[tag=doc] +:leveloffset: -1 + [[b2.tasks.projectsearch]] == Searching For Projects @@ -866,5 +870,5 @@ The following fields are populated in the generated database: multiple variants at once this is required to differentiate between multiple compilations of the same source file. -NOTE: Only one command database file is generated per `b2` invocation. And each +WARNING: Only one command database file is generated per `b2` invocation. And each time it is generated it overwrites any previous such file. diff --git a/doc/src/tufte.css b/doc/src/tufte.css new file mode 100644 index 000000000..cced1bef7 --- /dev/null +++ b/doc/src/tufte.css @@ -0,0 +1,683 @@ +@charset "UTF-8"; + +/* Adapted from https://github.com/edwardtufte/tufte-css */ + +:root { + --color-accent: #fa9300; + --dark-bg-color: #151515; + --dark-fg-color: #ddd; + --dark-hr-color: #555; + --dark-th-color: #222; + --light-bg-color: #fffff8; + --light-fg-color: #111; + --light-hr-color: #aaa; + --light-th-color: #ddd; + + --font-family-regular: Palatino, "Palatino Linotype", "Palatino LT STD", + "Book Antiqua", Georgia, serif; + --font-family-code: Consolas, "Liberation Mono", Menlo, Courier, monospace; + + --font-size-base: 15px; + --font-size-h1: 3.2rem; + + --wide-margin-left: 12.5%; + --wide-max-width: 1400px; + + --narrow-margins: 8%; + + --indent-block-border-left: solid var(--color-accent) 0.2rem; + + color-scheme: light dark; +} + +html { + font-size: var(--font-size-base); + font-family: var(--font-family-regular); + counter-reset: sidenote-counter; + color: light-dark(var(--light-fg-color), var(--dark-fg-color)); + background-color: light-dark(var(--light-bg-color), var(--dark-bg-color)); +} + +body { + margin: 0 auto 0 auto; + padding-left: var(--wide-margin-left); + max-width: var(--wide-max-width); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 2rem; + margin-bottom: 1.4rem; + font-weight: 400; + font-style: italic; + line-height: 1; +} + +h1 { + margin-top: 4rem; + font-style: normal; + font-size: var(--font-size-h1); +} + +h2 { + font-size: calc(var(--font-size-h1) * 0.75); +} + +h3, +#toctitle { + font-size: calc(var(--font-size-h1) * 0.65); +} + +h4 { + font-size: calc(var(--font-size-h1) * 0.5); +} + +h5 { + font-size: calc(var(--font-size-h1) * 0.55); +} + +h6 { + font-size: calc(var(--font-size-h1) * 0.5); +} + +hr { + display: block; + height: 1px; + width: 55%; + border: 0; + border-top: 1px solid; + margin: 1rem 0; + padding: 0; + @media (prefers-color-scheme: light) { + border-top-color: var(--light-hr-color); + } + @media (prefers-color-scheme: dark) { + border-top-color: var(--dark-hr-color); + } +} + +table { + border-spacing: 0; + border-collapse: collapse; +} + +p.subtitle, +#header .details { + font-style: italic; + margin-top: 1rem; + margin-bottom: 1rem; + font-size: 1.3rem; + display: block; + line-height: 1; +} + +.numeral { + font-family: et-book-roman-old-style; +} + +article { + padding: 5rem 0rem; +} +#header { + padding-top: 5rem; +} + +section, +.sect1 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +p, +dl, +ol, +ul { + font-size: 1.4rem; + line-height: 2rem; +} + +p { + margin-top: 1.4rem; + margin-bottom: 1.4rem; + padding-right: 0; + vertical-align: baseline; +} + +div.epigraph { + margin: 5rem 0; +} + +div.epigraph > blockquote { + margin-top: 3rem; + margin-bottom: 3rem; +} + +div.epigraph > blockquote, +div.epigraph > blockquote > p, +div.sidebarblock .paragraph, +div.sidebarblock .paragraph > p, +div.admonitionblock .content { + font-style: italic; +} + +div.epigraph > blockquote > footer { + font-style: normal; +} + +div.epigraph > blockquote > footer > cite { + font-style: italic; +} +/* end chapter epigraphs styles */ + +blockquote { + font-size: 1.4rem; +} + +blockquote p { + width: 55%; + margin-right: 40px; +} + +blockquote footer { + width: 55%; + font-size: 1.1rem; + text-align: right; +} + +section > p, +section > footer, +section > table, +.sectionbody > .paragraph, +.sect2 > .paragraph, +.sect3 > .paragraph, +.sect4 > .paragraph, +.sect5 > .paragraph, +.sectionbody > .openblock, +.sect2 > .openblock, +.sect3 > .openblock, +.sect4 > .openblock, +.sect5 > .openblock, +.tip { + width: 55%; +} + +/* 50 + 5 == 55, to be the same width as paragraph */ +section > dl, +section > ol, +section > ul, +.sectionbody > .olist, +.sectionbody > .ulist, +.sectionbody > .dlist, +.sect2 > .olist, +.sect2 > .ulist, +.sect2 > .dlist, +.sect3 > .olist, +.sect3 > .ulist, +.sect3 > .dlist, +.sect4 > .olist, +.sect4 > .ulist, +.sect4 > .dlist, +.sect5 > .olist, +.sect5 > .ulist, +.sect5 > .dlist { + width: 50%; + /* -webkit-padding-start: 5%; */ + /* background-color: #555; */ +} + +dt:not(:first-child), +li:not(:first-child) { + margin-top: 0.25rem; +} + +figure { + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + max-width: 55%; + -webkit-margin-start: 0; + -webkit-margin-end: 0; + margin: 0 0 3em 0; +} + +figcaption { + float: right; + clear: right; + margin-top: 0; + margin-bottom: 0; + font-size: 1.1rem; + line-height: 1.6; + vertical-align: baseline; + position: relative; + max-width: 40%; +} + +figure.fullwidth figcaption { + margin-right: 24%; +} + +a:link, +a:visited { + color: inherit; + text-underline-offset: 0.1em; + text-decoration-thickness: 0.05em; +} + +/* Sidenotes, margin notes, figures, captions */ +img { + max-width: 100%; +} + +.sidenote, +.marginnote, +.sidebarblock, +#toc, +.note > table:not(dl table, ol table, ul table), +.warning > table:not(dl table, ol table, ul table), +.important > table:not(dl table, ol table, ul table) { + float: right; + clear: right; + margin-right: -60%; + width: 50%; + margin-top: 0.3rem; + margin-bottom: 0; + position: relative; +} + +.sidenote, +.marginnote, +.sidebarblock p, +#toc, +.note > table, +.warning > table, +.important > table, +.tip p { + font-size: 1.1rem; + line-height: 1.3; + vertical-align: baseline; +} + +.sidebarblock, +#toc, +.note > table:not(dl table, ol table, ul table), +.warning > table:not(dl table, ol table, ul table), +.important > table:not(dl table, ol table, ul table) { + margin-top: -3rem; + margin-right: 10%; + width: 30%; +} + +.sidebarblock { + margin-top: 0.5rem; +} + +.sidenote-number { + counter-increment: sidenote-counter; +} + +.sidenote-number:after, +.sidenote:before { + font-family: et-book-roman-old-style; + position: relative; + vertical-align: baseline; +} + +.sidenote-number:after { + content: counter(sidenote-counter); + font-size: 1rem; + top: -0.5rem; + left: 0.1rem; +} + +.sidenote:before { + content: counter(sidenote-counter) " "; + font-size: 1rem; + top: -0.5rem; +} + +blockquote .sidenote, +blockquote .marginnote { + margin-right: -82%; + min-width: 59%; + text-align: left; +} + +div.fullwidth, +table.fullwidth { + width: 100%; +} + +div.table-wrapper { + overflow-x: auto; + font-family: "Trebuchet MS", "Gill Sans", "Gill Sans MT", sans-serif; +} + +.sans { + font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif; + letter-spacing: 0.03em; +} + +code, +pre > code { + font-family: var(--font-family-code); + font-size: 0.9rem; + line-height: 1.42; + -webkit-text-size-adjust: 100%; /* Prevent adjustments of font size after orientation changes in iOS. See https://github.com/edwardtufte/tufte-css/issues/81#issuecomment-261953409 */ + font-style: normal; +} + +.sans > code { + font-size: 1.2rem; +} + +h1 > code, +h2 > code, +h3 > code, +h4 > code, +h5 > code, +h6 > code { + font-size: 0.8em; +} + +.marginnote > code, +.sidenote > code { + font-size: 1rem; +} + +/* pre > code, */ +.sect1 > * > .listingblock, +.sect1 > * > .literalblock, +.sect2 > .listingblock, +.sect2 > .literalblock, +.sect3 > .listingblock, +.sect3 > .literalblock, +.sect4 > .listingblock, +.sect4 > .literalblock, +.sect5 > .listingblock, +.sect5 > .literalblock { + width: 52.5%; +} + +/* pre > code, */ +.listingblock, +.literalblock { + font-size: 0.9rem; + margin-left: 2rem; + padding-left: 1rem; + display: block; + border-left: var(--indent-block-border-left); +} + +.listingblock > .content, +.literalblock > .content { + overflow-x: scroll; +} + +pre.fullwidth > code { + width: 90%; +} + +h1 code, +h2 code, +h3 code, +h4 code, +h5 code, +h6 code { + word-wrap: break-word; +} + +.sectionbody > table, +.sect2 > table, +.sect3 > table, +.sect4 > table, +.sect5 > table, +.fullwidth { + max-width: 90%; + clear: both; +} + +span.newthought { + font-variant: small-caps; + font-size: 1.2em; +} + +input.margin-toggle { + display: none; +} + +label.sidenote-number { + display: inline-block; + max-height: 2rem; /* should be less than or equal to paragraph line-height */ +} + +label.margin-toggle:not(.sidenote-number) { + display: none; +} + +@media (max-width: 760px) { + body { + width: calc(100% - var(--narrow-margins) - var(--narrow-margins)); + padding-left: var(--narrow-margins); + padding-right: var(--narrow-margins); + } + + hr, + section > p, + section > footer, + section > table, + #content .sectionbody > .paragraph > p, + #content .sectionbody > .paragraph > footer, + #content .sectionbody > .paragraph > table, + .sectionbody > .paragraph, + .sect2 > .paragraph, + .sect3 > .paragraph, + .sect4 > .paragraph, + .sect5 > .paragraph, + .sectionbody > .openblock, + .sect2 > .openblock, + .sect3 > .openblock, + .sect4 > .openblock, + .sect5 > .openblock, + .tip { + width: 100%; + } + + pre > code { + width: 97%; + } + + section > dl, + section > ol, + section > ul, + .sectionbody > .olist, + .sectionbody > .ulist, + .sectionbody > .dlist, + .sect2 > .olist, + .sect2 > .ulist, + .sect2 > .dlist, + .sect3 > .olist, + .sect3 > .ulist, + .sect3 > .dlist, + .sect4 > .olist, + .sect4 > .ulist, + .sect4 > .dlist, + .sect5 > .olist, + .sect5 > .ulist, + .sect5 > .dlist { + width: 90%; + } + + figure { + max-width: 90%; + } + + figcaption, + figure.fullwidth figcaption { + margin-right: 0%; + max-width: none; + } + + blockquote { + margin-left: 1.5em; + margin-right: 0em; + } + + blockquote p, + blockquote footer { + width: 100%; + } + + label.margin-toggle:not(.sidenote-number) { + display: inline; + } + + .sidenote, + .marginnote, + #toc { + display: none; + } + + .sidebarblock, + .admonitionblock > table:not(dl table, ol table, ul table), + .note > table:not(dl table, ol table, ul table), + .warning > table:not(dl table, ol table, ul table), + .important > table:not(dl table, ol table, ul table), + .margin-toggle:checked + .sidenote, + .margin-toggle:checked + .marginnote { + display: block; + float: left; + left: 1rem; + clear: both; + width: 95%; + margin: 1rem 2.5%; + position: relative; + } + + .sidebarblock, + .admonitionblock > table:not(dl table, ol table, ul table), + .note > table:not(dl table, ol table, ul table), + .warning > table:not(dl table, ol table, ul table), + .important > table:not(dl table, ol table, ul table) { + float: none; + left: 0; + width: 100%; + margin: 1rem 0; + } + + label { + cursor: pointer; + } + + div.table-wrapper { + width: 85%; + } + + img { + width: 100%; + } + + .sect1 > * > .listingblock, + .sect1 > * > .literalblock, + .sect2 > .listingblock, + .sect2 > .literalblock, + .sect3 > .listingblock, + .sect3 > .literalblock, + .sect4 > .listingblock, + .sect4 > .literalblock, + .sect5 > .listingblock, + .sect5 > .literalblock { + width: 100%; + } + + table code { + word-wrap: break-word; + } +} + +/* -------------------------------------------------------------------------- */ + +#header .details br { + display: none; +} + +#toc { + position: absolute; + width: 27%; + left: 60%; + margin-right: inherit; + padding-left: 5%; +} + +#toc ul { + font-size: 1.1rem; + line-height: 1.3; + list-style-type: none; + padding-left: 0.125em; +} + +#toc ul ul { + padding-left: 1em; +} + +a.anchor { + position: absolute; + z-index: 1001; + width: 1.5ex; + margin-left: -1.5ex; + display: block; + text-decoration: none !important; + visibility: hidden; + text-align: center; + font-weight: normal; +} + +a.anchor:before { + content: "\00A7"; + display: block; +} + +*:hover > a.anchor, +a.anchor:hover { + visibility: visible; +} + +.admonitionblock .icon { + font-weight: bold; + font-size: 2rem; + width: 2rem; + text-align: center; + color: var(--color-accent); + vertical-align: text-top; +} + +.admonitionblock td.content { + padding-left: 1rem; + border-left: var(--indent-block-border-left); +} +.admonitionblock .listingblock { + border-left: none !important; +} + +table p { + margin: 0 0 0.1rem 0; +} +table .valign-top { + vertical-align: top; +} +table .valign-middle { + vertical-align: -webkit-baseline-middle; +} +table th { + @media (prefers-color-scheme: light) { + background-color: var(--light-th-color); + } + @media (prefers-color-scheme: dark) { + background-color: var(--dark-th-color); + } +} diff --git a/doc/src/tutorial.adoc b/doc/src/tutorial.adoc index d86cc9179..abfbf46ed 100644 --- a/doc/src/tutorial.adoc +++ b/doc/src/tutorial.adoc @@ -264,7 +264,7 @@ While `app.cpp` refers to a regular source file, `../util/foo//bar` is a reference to another target: a library `bar` declared in the Jamfile at `../util/foo`. -TIP: Some other build system have special syntax for listing dependent +NOTE: Some other build system have special syntax for listing dependent libraries, for example `LIBS` variable. In B2, you just add the library to the list of sources. diff --git a/example/contracts/hello.cpp b/example/contracts/hello.cpp new file mode 100644 index 000000000..bcbb43fcf --- /dev/null +++ b/example/contracts/hello.cpp @@ -0,0 +1,21 @@ +// Copyright 2025 René Ferdinand Rivera Morel +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.bfgroup.xyz/b2/LICENSE.txt) + +// tag::source[] +#include +#include + +int f(const int x) pre(x != 0) post(r : r != x) +{ + return x + 1; +} + +int main() +{ + std::cout << "Hello!\n"; + f(1); + f(0); +} +// end::source[] diff --git a/example/contracts/jamroot.jam b/example/contracts/jamroot.jam new file mode 100644 index 000000000..039cf4343 --- /dev/null +++ b/example/contracts/jamroot.jam @@ -0,0 +1,14 @@ +# Copyright 2008 Jurko Gospodnetic +# Copyright 2025 René Ferdinand Rivera Morell +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt) + +project + : requirements + on + enforce + clang:libc++ + 23 + ; + +exe hello : hello.cpp ; diff --git a/example/contracts/readme.adoc b/example/contracts/readme.adoc new file mode 100644 index 000000000..c83e87f51 --- /dev/null +++ b/example/contracts/readme.adoc @@ -0,0 +1,47 @@ +//// +Copyright 2008 Jurko Gospodnetic +Copyright 2025 René Ferdinand Rivera Morell +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt) +//// + += Hello + +This example shows a very basic Boost Build project set up so it compiles a +single executable which makes use of contracts from a single source file: + +.`hello.cpp` +[source,cpp] +---- +include::../../example/contracts/hello.cpp[tag=source] +---- + +Our `jamroot.jam` is minimal and only specifies one `exe` target for the +program: + +.`jamroot.jam` +[source,jam] +---- +include::jamroot.jam[] +---- + +Building the example yields: + +[source,bash] +---- +> cd /example/hello +> b2 +...found 12 targets... +...updating 8 targets... +clang-linux.compile.c++ bin/clang-linux-22.0~contracts/debug/contracts-on-enforce/cxxstd-23-iso/stdlib-libc++/hello.o +clang-linux.link bin/clang-linux-22.0~contracts/debug/contracts-on-enforce/cxxstd-23-iso/stdlib-libc++/hello + +...updated 8 targets... +> LD_LIBRARY_PATH=/opt/clang-ericwf-contracts-trunk/lib/x86_64-unknown-linux-gnu/ bin/clang-linux-22.0~contracts/debug/contracts-on-enforce/cxxstd-23-iso/stdlib-libc++/hello +Hello! +hello.cpp:11: pre(x != 0) failed +libc++abi: terminating +Aborted (core dumped) LD_LIBRARY_PATH=/opt/clang-ericwf-contracts-trunk/lib/x86_64-unknown-linux-gnu/ bin/clang-linux-22.0~contracts/debug/contracts-on-enforce/cxxstd-23-iso/stdlib-libc++/hello +---- + +NOTE: The actual paths will depend on your configuration. diff --git a/notes/build_dir_option.txt b/notes/build_dir_option.txt deleted file mode 100644 index 0ebd3bef7..000000000 --- a/notes/build_dir_option.txt +++ /dev/null @@ -1,77 +0,0 @@ -Copyright 2005 Vladimir Prus -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - - -Summary -------- - -We need a --build-dir option that users building from read-only -medium can use to force building to some other location. Pretty much -every project need this functionality, so it's desirable to have it -out-of-the box, without explicit setup. - -Design ------- - -We can achieve the desired effect manually by adding something like this -to Jamroot: - - project .... : build-dir [ my-rule-to-compute-build-dir ] ; - -Where 'my-rule-to-compute-build-dir' would look at the --build-dir option. - -We need to automate this, but essentially, --build-dir will only affect -the 'build-dir' attribute of Jamroots. - -If Jamroot contains: - - project foo ; - -and --build-dir options' value if /tmp/build, then we'll act as if Jamroot -contained: - - project foo : build-dir /tmp/build/foo ; - -If the 'project' rule has explicit 'build-dir': - - project foo : build-dir bin.v2 ; - -then with the same value of --build-dir we'd act as if Jamroot contained: - - project foo : build-dir /tmp/build/foo/bin.v2 ; - -We can't drop "bin.v2" because it's quite possible that the name of build dir -have specific meaning. For example, it can be used to separate B2 V1 -and V2 build results. - -The --build-dir option has no effect if Jamroot does not define any project id. -Doing otherwise can lead to nasty problems if we're building two distinct -projects (that is with two different Jamroot). They'll get the same build -directory. Most likely, user will see the "duplicate target" error, which is -generally confusing. - -It is expected that any non-trivial project will have top-level "project" -invocation with non empty id, so the above limitation is not so drastic. -We'll emit a warning if Jamroot does not define project id, and --build-dir -is specified. - -Here's the exact behavior of the --build-dir option. If we're loading a -Jamfile (either root or non-root), that declare some project id and some -build-dir attribute, the following table gives the value of build-dir -that will actually be used. - -------------------------------------------------------------------------------- -Root? Id Build-dir attribute Resulting build dir -------------------------------------------------------------------------------- -yes none * --build-dir is ignored, with warning -yes 'foo' none /tmp/build/foo -yes 'foo' 'bin.v2' /tmp/build/foo/bin.v2 -yes 'foo' '/tmp/bar' Error [1] -no * none --build-dir has no effect, inherited - build dir is used -no * non-empty Error [2] -------------------------------------------------------------------------------- -[1] -- not clear what to do -[2] -- can be made to work, but non-empty build-dir -attribute in non-root Jamfile does not make much sense even without --build-dir diff --git a/notes/changes.txt b/notes/changes.txt deleted file mode 100644 index bb98661f1..000000000 --- a/notes/changes.txt +++ /dev/null @@ -1,317 +0,0 @@ -Copyright 2004-2007 Vladimir Prus -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -Milestone 13 (in development) - -Changes in this release: - -The following bugs were fixed: - - - gcc support did not work on HP-UX systems - -Milestone 12 (Oct 1, 2007) - -Changes in this release: - - - The Pathscale, PGI and mipspro compilers are now supported. - - Support for autoconfiguration of toolset based on command-line - toolset=xxxx request, and for default toolset - configuration as a fallback. - - Support for precompiled headers for gcc toolset, - and improvements for msvc. - - Mechanism for removing inherited requirements. - - The 'make' rule support specifying usage-requirements. - - New 'project.extension' rule for declaring standalone - projects. - - New 'conditional' convenience rule. - - New 'glob-tree' rule. - - The 'glob' rule accepts patterns to exclude. - - Inline targets are now marked explicit automatically. - - Toolsets can now implicitly add requirements to - all targets. - - New 'generate' rule. - - The executables produced by the 'run' rule are automatically - removed after run. - - The gcc toolset uses the version obtained by running - the compiler, if no explicit one is provided. - - The sun toolset now supports the 'address-model' feature, - and uses -KPIC for shared libraries. - - Free features on command line affect all targets, not - just 'directly requested' ones. - - -Documentation changes: - - - Installation instructions for Linux distributors. - - Configuration options for all supported C++ compilers - are now documented. - -The following bugs were fixed: - - - The 'cflags' and 'linkflags' now work on Darwin.o - - The intel toolset now works on Windows. - - Fix library search options for CodeWarriour toolset. - - The could cause duplicate - mkdir commands. - - Numerious fixes in Boost autolink support - - Numerious fixes in Boost.Python support. - - Indirect properties not evaluated in usage requirements. - - Generator that returns a property set but not target is - considered successful. - - On Darwin, when several compiler versions - are configured, -fcoalesce-templates is applied only to - versions that need it. - - -Milestone 11 (Jule 20, 2006) - -Changes in this release: - - - New C++ compilers: IBM xlf, HP aCC, HP CXX, Intel fortran compiler. - - New tools: Qt4 support, MS message compiler and IDL compiler. - - New main targets: 'notfile' and 'cast'. - - - Core changes: - - - Only one file required at top level of a project, named Jamroot. - - Jamfiles can now contain project-specific help messages. - - "Indirect conditional requirements" introduced - (http://tinyurl.com/mn3jp) - - Strip suffix in main target names when computing names of generated - files (URL) - - The 'source-location' project attribute can contain - several directories. - - Usage requirements are propagated not only direct dependents, - but to indirect dependents. - - - Command line option changes (see http://tinyurl.com/zbycz) - - New option --build-dir - - The --clean option cleans only target below the current directory, - not globally. - - New --clean-all option was added. - - New option --debug-building - - Running "bjam some_directory" works even if there's no Jamfile - in the current directory. - - - Toolset improvements: - - Assembling support with gcc, borland and msvc. - - Support amd64/ia64 cross-compiling with msvc. - - Improved, registry-based autodetection for msvc. - - Serialize execution of gcc.link actions - - Precompiled headers supported on MSVC - (Need documentation) - - - New features and - - The 'glob' rule accepts wildcards in directory names. - - The 'stage' rule was renamed to 'install' - (the old name still available for compatibility) - - The feature can accept user-defined function as value - (URL) - - The 'install' rule can install a directory hierarchy preserving relative - paths. - - The 'install' rule no longer allows to change library - name during install. - - The Jamfile referred via 'use-project' may declare project id different - from the one in 'use-project'. - - The 'using' rule now searches the directory of containing Jamfile. - - -The following bugs were fixed: - - - The feature was ignored for static linking - - Fix #include scanning for C files. - - Child projects were sometimes loaded before parent projects. - - Fix project references with absolute paths on Windows. - - The feature was ignored for 'install' targets. - - A generator having the same type in sources and targets was causing hang. - - Use 'icpc' command for Intel, fixing errors with 8.1 and higher. - - Generation of PS files with the FOP tool really produces .PS files. - - No dependency scanning was done for C files. - - The 'constant' and 'path-constant' rules did not accept multi-element - value. - - Don't pass -fcoalesce-templates to gcc on OSX 10.4 - - Fix static lib suffix on OSX. - - Fix rpath setting on Intel/Linux. - - The 'install' rule don't unnecessary scans #includes in installed - headers. - - -Developer visible changes: - - - Ability to customize type's prefix depending on build properties. - - Generator's 'run' method can return usage-requirements. - - Main target rule is automatically declared for each new target type. - - 'Link incompatible' feature attribute was removed - - Generators no longer bypass unhandled sources, they just ignore them. - - If there are several applicable generators, immediately report ambiguity. - Provide a way to explicitly resolve conflicts between generators. - - The 'flags' rule can match absence of feature. - - Great improvement in response files handling - - The 'toolset.flags' rules allows value-less feature to signify - absence of this feature (fix hack-hack). - - Automatically declare main target rule for each declared target type. - - When inheriting types, inherit generators for the base type, as opposed - to using various hacks to invoke base generators when needed. - - Improve diagnostic for "duplicate actual target" and generator ambiguity. - - -Milestone 10 (October 29, 2004) - -Changes in this release: - - Many toolsets were added: Intel, Metrowerks, Comeau, aCC, vacpp. - Documentation was converted to BoostBook and improved. - Performance was improved. - - - Toolsets initialization syntax is much more uniform. Compiler and linker - flags can now be specified. - - The algorithm for computing build properties was improved. Conditional - requirements can be chained, and a number of bugs were fixed. - - Specific order of properties can be specified. - - The main target rules can be called from everywhere, not necessary from - Jamfile. - - Check for "unused sources" removed. - - The feature affects only linking now. - - The feature now works only for libraries. - - Simpler syntax for "searched" libraries was added. - - New feature. - - - Unix: - The right order of static libraries on Unix is automatically - computed. - The feature is the default. - gcc: - The -fPIC option is passed when creating shared libraries. - Problems with distcc were solved. - Sun: - It's now possible to use the sun linker (as opposed to gnu), and - to compile C files. - Darwin: - Shared libraries are now supported. - MSVC: Before resource files compilation, the setup script is invoked. - Options deprecated in 8.0 are not longer used. - - -The following bugs were fixed: - - - The rule did not handle the property (!!!!!!) - - Don't add "bin" to the build directory explicitly specified by the user. - - Allow to select staged targets, - even with off. - - Includes for the form '# include " did not work. - - (Qt) Add paths to all dependent libs to uic command - line, which helps if the UI files uses plugins. - - Using xxx in requirements was broken. - - Error message printed when target can be found is much more clear. - - Inline targets in sources of 'stage' did not work. - - Don't produce 'independent target' warnings on Windows - - (gcc) The static did not work. - - (gcc) Suppress warnings from the 'ar' tool on some systems. - - (gcc) Don't try to set soname on NT. - -Developer visible changes: - - - Generator priorities are gone, explicit overrides are used. - - 'Active' features were removed - - Support for VMS paths was added. - -Thanks to Christopher Currie, Pedro Ferreira, Philipp Frauenfelder, -Andre Hentz, Jurgen Hunold, Toon Knapen, Johan Nilsson, Alexey Pakhunov, -Brock Peabody, Michael Stevens and Zbynek Winkler who contributed -code to this release. - - -Milestone 9.1 (Nov 6, 2003) - -The following bugs were fixed: - - - The 'unit-test' rule used to ignore properties. - - The gcc toolset used to ignore property. - -Milestone 9 (Nov 6, 2003) - -Changes in this release - - - Putting library in sources of other library now works even for static - linking, which makes expressing library->library dependency much - simpler. - - Performance was considerably improved. - - Regression testing framework now works on windows. - - The "alias" rule can have usage requirements and passes on usage - requirements of sources. - - The "stage" rule can traverse dependencies. - - Support for "def files" was implemented. - - Targets paths are now shorter. - - Darwin toolset was improved. - -The following bugs were fixed: - - - It was not possible to specify empty suffix for a target type derived - from other type. - - The stage rules used to generate incorrect suffix in some cases. - - It was possible to load Jamfile twice. - - The 'use-project' rule was broken when referring to a child project. - - Use of composite properties in requirements did not work. - -Developer visible changes: - - - New CALC builtin, which considerable improves performance. - - Source layout was reorganized. - - Handling of response file was simplified. - -Thanks to Pedro Ferreira, Kirill Lapshin, Andre Hentz, Paul Lin, -Jurgen Hunold, Christopher Currie, and Brock Peabody, who contributed to -this release. - -Milestone 8 (Oct 15, 2003) - -Changes in this release: - - - A regression testing framework was implemented. - - New feature was added for better handling - of dependencies to generated headers. - - The link-compatibility checks not longer cause projects to be skipped, - and issue warning, not error, for main targets. - - Algorithm for selecting main target alternative was improved. - - The feature was renamed to . - - Project root constants were made available in project root itself. - -The following bugs were fixed: - - - failure to recognize shared libraries with version as such - - the 'path-constant' rule was mishandling absolute paths on Windows. - - -Milestone 7 (Sep 11, 2003) - -Changes in this release: - - - Performance was improved. - - Support for Sun and Darwin toolsets was added. - - feature, which changes the name of target depending of build - variant, was implemented. - - Old-style targets-ids are no longer supported. - - New 'glob' rule allows to easily perform wildcard matching in Jamfile. - - Improve bison/flex support to understand C++. - -The following bugs were fixed: - - - bogus error on use of project default-build attribute with several - main target alternatives. - - broken toolset inheritance - - hard error after skipping a target due to incompatible requirements - - incorrect behaviour of a generator when producing several targets of - the same type - - errors on use of the 'project-root' rule in Jamfile context - - inability to require specific compiler version for a main target. - - incorrect behaviour of "bjam msvc" when msvc is configured with explicit - version. - -Thanks to Christopher Currie, Pedro Ferreira and Michael Stevens, who -contributed to this release. - - - - diff --git a/notes/release_procedure.txt b/notes/release_procedure.txt deleted file mode 100644 index 9ed95f1e6..000000000 --- a/notes/release_procedure.txt +++ /dev/null @@ -1,83 +0,0 @@ -Copyright 2003, 2005, 2006 Vladimir Prus -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - - - B2 V2 release procedure. - -[ Must be done from a Unix shell ] - -0. Look for all issues for current milestone in the tracker. Close the fixed one, - if not already closed. Move to a later milestone, or fix all the unfixed - ones. - - Make sure that "bjam --version" output is correct. Update version string if - needed. Update bjam version and the version check is necessary. - Check the download locations in "index.html". Check that "last modified" - string in index.html is correct. - -1. Make sure you don't have any local modification, and create SVN directory - - https://svn.boost.org/svn/boost/branches/build/Milestone_X - - Then, copy: - - https://svn.boost.org/svn/boost/trunk/tools/build - https://svn.boost.org/svn/boost/trunk/tools/jam - - to that directory. - -2. Run - - svn co https://svn.boost.org/svn/boost/branches/build/Milestone_X boost-build - -3. Go to "boost-build/build/v2" directory. - -4. Run "./roll.sh". This will create "boost-build.zip" and - "boost-build.tar.bz2" in parent directory, and also upload - new docs to sourceforge. - -5. Unpack "boost-build.tar.bz2", and build jam. - -6. Go to "test" and copy "test-config-example.jam" to "test-config.jam". - If you're not ghost, edit test-config.jam to specify all the right paths. - Run gcc tests: - - python test_all.py gcc --extras - -7. Build all projects in examples-v2, using the bjam binary created at step 4. - Note: "threading=multi" might be needed to build QT examples. - -8. Make SF release: - - - Go to - https://sourceforge.net/project/admin/editpackages.php?group_id=7586 - - - Create new B2 release. Name it 2.0-mXX - - - Upload the changelog. Be sure to turn the "Preserve my pre-formatted - text" checkbox. - - - Rename previously built packages to boost-build-2.0-mXX.tar.bz2 - and boost-build-2.0-mXX.zip. Upload them to the - /incoming directory on ftp://upload.sourceforge.net - - - Add those file to release, edit file properties. - - - In a separate browser, verify changelog is not damaged. - - - In a separate browser, Download the files and verify checksums. - - - In SF file release interface, send email notice. - -9. Announce the release, etc. - -10. Login to SF and update the current-release redirects in - /home/groups/b/bo/boost/htdocs/boost-build2/.htaccess. - -11. If any issues were found during release in this document or in - test-config-example.jam, commit those changes. The release need - not be redone, but changes must be committed. - -12. Set release date in changes.txt and commit. - diff --git a/src/build/ac.jam b/src/build/ac.jam index 5a1f5a86c..50e883cbb 100644 --- a/src/build/ac.jam +++ b/src/build/ac.jam @@ -205,9 +205,17 @@ class ac-library : basic-target else { local use-environment ; + local vcpkg-ps ; if ! $(self.library-name) && ! $(self.include-path) && ! $(self.library-path) { use-environment = true ; + local vcpkg-proj = [ project.target vcpkg : allow-missing ] ; + if $(vcpkg-proj) + { + vcpkg-ps = [ targets.generate-from-reference + /vcpkg//prefix : $(vcpkg-proj) : $(property-set) ] ; + } + } local libnames = $(self.library-name) ; if ! $(libnames) && $(use-environment) @@ -219,12 +227,20 @@ class ac-library : basic-target libnames ?= $(self.default-names) ; local include-path = $(self.include-path) ; + if ! $(include-path) && $(vcpkg-ps) + { + include-path = [ $(vcpkg-ps).get ] ; + } if ! $(include-path) && $(use-environment) { include-path = [ os.environ $(name:U)_INCLUDE ] ; } local library-path = $(self.library-path) ; + if ! $(library-path) && $(vcpkg-ps) + { + library-path = [ $(vcpkg-ps).get ] ; + } if ! $(library-path) && $(use-environment) { library-path = [ os.environ $(name:U)_LIBRARY_PATH ] ; diff --git a/src/build/project.jam b/src/build/project.jam index b19be1253..a4bb7a307 100644 --- a/src/build/project.jam +++ b/src/build/project.jam @@ -163,6 +163,7 @@ rule find ( name : current-location ) { name = [ NORMALIZE_PATH $(name) ] ; local project-module ; + local location ; # Try interpreting name as project id. if [ path.is-rooted $(name) ] @@ -195,14 +196,37 @@ rule find ( name : current-location ) load-used-projects $(caller-module) ; } } + else + { + local sub = [ path.basename $(name) ] ; + local root = [ path.parent $(name) ] ; + while $(root) != / + { + local m = $($(root).jamfile-module) ; + if $(m) + { + location = [ path.root $(sub) + [ attribute $(m) location ] ] ; + root = / ; + } + else + { + sub = [ path.join [ path.basename $(root) ] $(sub) ] ; + root = [ path.parent $(root) ] ; + } + } + } project-module = $($(name).jamfile-module) ; } } if ! $(project-module) { - local location = [ path.root [ path.make $(name) ] $(current-location) ] - ; + if ! $(location) + { + location = [ path.root [ path.make $(name) ] $(current-location) ] + ; + } # If no project is registered for the given location, try to load it. # First see if we have a Jamfile. If not, then see if we might have a diff --git a/src/build/version.jam b/src/build/version.jam index 071907022..516ab928e 100644 --- a/src/build/version.jam +++ b/src/build/version.jam @@ -9,8 +9,8 @@ import numbers ; # Mirror engine JAM_VERSION .major = 5 ; -.minor = 3 ; -.patch = 2 ; +.minor = 4 ; +.patch = 0 ; rule build ( ) diff --git a/src/engine/build.bat b/src/engine/build.bat index 69b65a07f..e57d25c7b 100644 --- a/src/engine/build.bat +++ b/src/engine/build.bat @@ -29,7 +29,7 @@ ECHO ### .\build.bat msvc ECHO ### ECHO ### Toolsets supported by this script are: borland, como, gcc, ECHO ### clang, clang-win, gcc-nocygwin, intel-win32, mingw, -ECHO ### vc12, vc14, vc141, vc142, vc143 +ECHO ### vc12, vc14, vc141, vc142, vc143, vc145 ECHO ### ECHO ### If you have Visual Studio 2017 installed you will need to either update ECHO ### the Visual Studio 2017 installer or run from VS 2017 Command Prompt diff --git a/src/engine/build.sh b/src/engine/build.sh index 65a366aa0..1938704a2 100755 --- a/src/engine/build.sh +++ b/src/engine/build.sh @@ -271,8 +271,8 @@ if test_true ${B2_HELP_OPT} ; then error_exit fi -# If we have a CXX but no B2_TOOLSET specified by the user we assume they meant -# "cxx" as the toolset. +# If user gave a --cxx option but no B2_TOOLSET specified by the user we assume +# they meant "cxx" as the toolset. if test "${B2_CXX_OPT}" != "" -a "${B2_TOOLSET}" = "" ; then B2_TOOLSET=cxx fi diff --git a/src/engine/config_toolset.bat b/src/engine/config_toolset.bat index 41bddc334..44449449b 100644 --- a/src/engine/config_toolset.bat +++ b/src/engine/config_toolset.bat @@ -12,6 +12,7 @@ if "_%B2_TOOLSET%_" == "_vc14_" call :Config_VC14 if "_%B2_TOOLSET%_" == "_vc141_" call :Config_VC141 if "_%B2_TOOLSET%_" == "_vc142_" call :Config_VC142 if "_%B2_TOOLSET%_" == "_vc143_" call :Config_VC143 +if "_%B2_TOOLSET%_" == "_vc145_" call :Config_VC145 if "_%B2_TOOLSET%_" == "_borland_" call :Config_BORLAND if "_%B2_TOOLSET%_" == "_como_" call :Config_COMO if "_%B2_TOOLSET%_" == "_gcc_" call :Config_GCC @@ -161,6 +162,28 @@ set "B2_CXX_LINK=/link kernel32.lib advapi32.lib user32.lib" set "_known_=1" goto :Embed_Minafest_Via_Link +:Config_VC145 +if not defined CXX ( set "CXX=cl" ) +call vswhere_usability_wrapper.cmd +REM Reset ERRORLEVEL since from now on it's all based on ENV vars +ver > nul 2> nul +if "_%B2_TOOLSET_ROOT%_" == "__" ( + if NOT "_%VS180COMNTOOLS%_" == "__" ( + set "B2_TOOLSET_ROOT=%VS180COMNTOOLS%..\..\VC\" + )) + +if "_%B2_ARCH%_" == "__" set B2_ARCH=%PROCESSOR_ARCHITECTURE% +set B2_BUILD_ARGS=%B2_BUILD_ARGS% %B2_ARCH% + +REM return to current directory as vsdevcmd_end.bat switches to %USERPROFILE%\Source if it exists. +pushd %CD% +if "_%VSINSTALLDIR%_" == "__" call :Call_If_Exists "%B2_TOOLSET_ROOT%Auxiliary\Build\vcvarsall.bat" %B2_BUILD_ARGS% +popd +set "B2_CXX="%CXX%" /nologo /MP /MT /TP /Feb2 /wd4996 /wd4675 /O2 /GL /EHsc /Zc:wchar_t /Gw" +set "B2_CXX_LINK=/link kernel32.lib advapi32.lib user32.lib" +set "_known_=1" +goto :Embed_Minafest_Via_Link + :Config_VCUNK if NOT "_%B2_TOOLSET%_" == "_vcunk_" goto Skip_VCUNK call vswhere_usability_wrapper.cmd diff --git a/src/engine/function.cpp b/src/engine/function.cpp index 3a8e91de6..0e78c979f 100644 --- a/src/engine/function.cpp +++ b/src/engine/function.cpp @@ -2363,6 +2363,20 @@ static int32_t try_parse_variable( char const * * s_, char const * * string, VAR_PARSE_GROUP * out ) { char const * s = *s_; + // escaping '$' with "$$" sequence when it needed (sequence of multiple "$$" before "$(" or '(') + if ( s[ 0 ] == '$' && s[ 1 ] == '$' ) + { + // count repeats of "$$" and checks that sequence used before '(' or "$(" (when escaping needed) + for(s += 2; s[ 0 ] == '$' && s[ 1 ] == '$'; s += 2); + if(s[ 0 ] == '(' || (s[ 0 ] == '$' && s[ 1 ] == '(')) { + // save escaped '$'s as half of found "$$" sequence + size_t repeats = (s - *s_) / 2; + var_parse_group_maybe_add_constant( out, *string, s - repeats ); + *string = s; + } + *s_ = s; + return 1; + } if ( s[ 0 ] == '$' && s[ 1 ] == '(' ) { var_parse_group_maybe_add_constant( out, *string, s ); diff --git a/src/engine/guess_toolset.bat b/src/engine/guess_toolset.bat index 6b3c6094e..5e8f2127d 100644 --- a/src/engine/guess_toolset.bat +++ b/src/engine/guess_toolset.bat @@ -33,6 +33,10 @@ REM Let vswhere tell us where msvc is at, if available. call :Clear_Error call vswhere_usability_wrapper.cmd call :Clear_Error +if NOT "_%VS180COMNTOOLS%_" == "__" ( + set "B2_TOOLSET=vc145" + set "B2_TOOLSET_ROOT=%VS180COMNTOOLS%..\..\VC\" + goto :eof) if NOT "_%VS170COMNTOOLS%_" == "__" ( set "B2_TOOLSET=vc143" set "B2_TOOLSET_ROOT=%VS170COMNTOOLS%..\..\VC\" diff --git a/src/engine/jam.cpp b/src/engine/jam.cpp index aac7c616d..b1811bbfb 100644 --- a/src/engine/jam.cpp +++ b/src/engine/jam.cpp @@ -313,8 +313,8 @@ int guarded_main(int argc, char * argv[]) "after which they are stopped."); cli |= lyra::opt( - [](const std::string & x) { - globs.max_buf = std::stoi(x) * 1024; /* convert to kb */ + [](int x) { + globs.max_buf = x * 1024; /* convert to kb */ }, "x") .name("-m") diff --git a/src/engine/lists.h b/src/engine/lists.h index 9ee635659..ab6dc05c9 100644 --- a/src/engine/lists.h +++ b/src/engine/lists.h @@ -657,6 +657,7 @@ inline list_ref & list_ref::operator+(T value) // <2> Adds a single value to the end of the list. The list is returned to allow for chaining. + end::reference[] */ inline list_ref & list_ref::push_back(OBJECT * value) { diff --git a/src/engine/mod_args.cpp b/src/engine/mod_args.cpp index 9d361b32c..dfe3f514a 100644 --- a/src/engine/mod_args.cpp +++ b/src/engine/mod_args.cpp @@ -127,12 +127,25 @@ lyra::cli & lyra_cli() { return args_reg::ref().cli; } void process_args(bool silent) { args_reg::ref().reparse(); - if (!silent && globs.display_help) + if (silent) + return; + + std::ostringstream out; + int return_code = EXITOK; + bool stop = false; + + if (!args_reg::ref().result->is_ok()) + { + stop = true; + return_code = EXITBAD; + out << "Error: " << args_reg::ref().result->message() << '\n'; + } + + if (stop || globs.display_help) { - std::ostringstream out; out << args_reg::ref().cli; err_puts(out.str().c_str()); - b2::clean_exit(EXITOK); + b2::clean_exit(return_code); } } diff --git a/src/engine/modules.cpp b/src/engine/modules.cpp index d250ee1bc..0586f3ecc 100644 --- a/src/engine/modules.cpp +++ b/src/engine/modules.cpp @@ -205,7 +205,7 @@ static void stat_module( void * xmodule, void * data ) if ( is_debug_mem() || is_debug_profile() ) { struct hash * class_info = (struct hash *)data; - if ( m->class_module ) + if ( m->class_module && m->class_module->name ) { int found; struct module_stats * ms = (struct module_stats *)hash_insert( class_info, m->class_module->name, &found ); diff --git a/src/engine/modules.h b/src/engine/modules.h index 724bdd68a..ea3f56b1a 100644 --- a/src/engine/modules.h +++ b/src/engine/modules.h @@ -22,16 +22,16 @@ typedef module_t * module_ptr; struct module_t { - OBJECT * name; - struct hash * rules; - struct hash * variables; - struct hash * variable_indices; - int num_fixed_variables; - LIST * * fixed_variables; - struct hash * imported_modules; - module_t * class_module; - struct hash * native_rules; - int user_module; + OBJECT * name = nullptr; + struct hash * rules = nullptr; + struct hash * variables = nullptr; + struct hash * variable_indices = nullptr; + int num_fixed_variables = 0; + LIST * * fixed_variables = nullptr; + struct hash * imported_modules = nullptr; + module_t * class_module = nullptr; + struct hash * native_rules = nullptr; + int user_module = 0; }; module_t * bindmodule( OBJECT * name ); diff --git a/src/engine/patchlevel.h b/src/engine/patchlevel.h index 7055da212..dd5c16fb7 100644 --- a/src/engine/patchlevel.h +++ b/src/engine/patchlevel.h @@ -13,5 +13,5 @@ https://www.bfgroup.xyz/b2/LICENSE.txt) */ #define VERSION_MAJOR 5 -#define VERSION_MINOR 3 -#define VERSION_PATCH 2 +#define VERSION_MINOR 4 +#define VERSION_PATCH 0 diff --git a/src/engine/value.h b/src/engine/value.h index 3a9d628df..ba9c3819c 100644 --- a/src/engine/value.h +++ b/src/engine/value.h @@ -121,6 +121,9 @@ struct value_ref inline value_ref(const std::string & s) : val(value::make(s.c_str())) {} + inline value_ref(const string_view & sv) + : val(value::make(sv)) + {} inline ~value_ref() { diff --git a/src/engine/variable.cpp b/src/engine/variable.cpp index 13bcbba54..7eea22166 100644 --- a/src/engine/variable.cpp +++ b/src/engine/variable.cpp @@ -40,6 +40,8 @@ #include "pathsys.h" #include "jam_strings.h" #include "output.h" +#include "strview.h" +#include "value.h" #include #include @@ -71,88 +73,66 @@ static void var_dump( OBJECT * symbol, LIST * value, const char * what ); * Otherwise, split the value at blanks. */ -void var_defines( struct module_t * module, const char * const * e, int preprocess ) +void var_defines(struct module_t * module, const char * const * e, int preprocess) { - string buf[ 1 ]; + for (; *e; ++e) + { + ::b2::string_view def(*e); + ::b2::string_view var(def.begin(), def.find('=')); + ::b2::string_view val(def.begin() + var.size() + 1); + b2::jam::variable jam_var { module, + std::string { var.begin(), var.end() }.c_str() }; + // std::printf(">> var_defines: *e = %s\n", *e); + // for (auto v : jam_var.get()) + // { + // std::printf(" '%s'\n", v->str()); + // } - string_new( buf ); + // No value to set var with. + if (var.size() == def.size()) continue; - for ( ; *e; ++e ) - { - const char * val; + // Skip pre-processing, to just set the raw value. + if (preprocess == 0) + { + jam_var = ::b2::list_ref { ::b2::value_ref { val } }; + continue; + } - if ( ( val = strchr( *e, '=' ) ) -#if defined( OS_MAC ) - /* On the mac (MPW), the var=val is actually var\0val */ - /* Think different. */ - || ( val = *e + strlen( *e ) ) -#endif - ) - { - LIST * l = L0; - int32_t const len = int32_t(strlen( val + 1 )); - int const quoted = ( val[ 1 ] == '"' ) && ( val[ len ] == '"' ) && - ( len > 1 ); + // Quoted values do not get separator-split. But do get unquoted. + if (val.size() >= 2 && val.front() == '"' && val.back() == '"') + { + jam_var = ::b2::list_ref { ::b2::value_ref { + val.substr(1, val.size() - 2) } }; + continue; + } - if ( quoted && preprocess ) - { - string_append_range( buf, val + 2, val + len ); - l = list_push_back( l, object_new( buf->value ) ); - string_truncate( buf, 0 ); - } - else - { - const char * p; - const char * pp; - char split = -#if defined( OPT_NO_EXTERNAL_VARIABLE_SPLIT ) - '\0' -#elif defined( OS_MAC ) - ',' -#else - ' ' -#endif - ; - - /* Split *PATH at :'s, not spaces. */ - if ( val - 4 >= *e ) - { - if ( !strncmp( val - 4, "PATH", 4 ) || - !strncmp( val - 4, "Path", 4 ) || - !strncmp( val - 4, "path", 4 ) ) - split = SPLITPATH; - } - - /* Do the split. */ - for - ( - pp = val + 1; - preprocess && ( ( p = strchr( pp, split ) ) != 0 ); - pp = p + 1 - ) - { - string_append_range( buf, pp, p ); - l = list_push_back( l, object_new( buf->value ) ); - string_truncate( buf, 0 ); - } - - l = list_push_back( l, object_new( pp ) ); - } - - /* Get name. */ - string_append_range( buf, *e, val ); - { - OBJECT * varname = object_new( buf->value ); - var_set( module, varname, l, VAR_SET ); - object_free( varname ); - } - string_truncate( buf, 0 ); - } - } - string_free( buf ); + // Split on separator, either space or path. + jam_var = ::b2::list_cref {}; + { + char split = ' '; + /* Split *PATH at :'s, not spaces. */ + if (var.ends_with("PATH") + || var.ends_with("Path" || var.ends_with("path"))) + split = SPLITPATH; + /* Do the split. */ + for (::b2::string_view::size_type p0 = 0; p0 < val.size();) + { + auto p1 = val.find(split, p0); + if (p1 == val.npos) + { + jam_var += ::b2::value_ref { val.substr(p0) }; + p0 = val.npos; + } + else + { + jam_var += ::b2::value_ref { val.substr(p0, p1 - p0) }; + p0 = p1 + 1; + } + } + } + } } - /* Last returned variable value saved so we may clear it in var_done(). */ static LIST * saved_var = L0; diff --git a/src/engine/variable.h b/src/engine/variable.h index d96ee2471..6cbc0edbb 100644 --- a/src/engine/variable.h +++ b/src/engine/variable.h @@ -71,6 +71,9 @@ struct variable inline variable(const std::string & m, const std::string & v) : variable(m.c_str(), v.c_str()) {} + inline variable(struct module_t * m, const std::string & v) + : variable(m, v.c_str()) + {} // Refer to variable in global/root module. inline explicit variable(const char * v) diff --git a/src/engine/vswhere_usability_wrapper.cmd b/src/engine/vswhere_usability_wrapper.cmd index 8759a6ac5..1f0132813 100644 --- a/src/engine/vswhere_usability_wrapper.cmd +++ b/src/engine/vswhere_usability_wrapper.cmd @@ -17,8 +17,8 @@ if errorlevel 1 goto :no-vswhere set VSWHERE_REQ=-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 set VSWHERE_PRP=-property installationPath -REM Visual Studio Unknown Version, Beyond 2022 -set VSWHERE_LMT=-version "[18.0,19.0)" +REM Visual Studio Unknown Version, Beyond 2026 +set VSWHERE_LMT=-version "[19.0,20.0)" set VSWHERE_PRERELEASE=-prerelease SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT% %VSWHERE_PRERELEASE% for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do ( @@ -30,6 +30,19 @@ for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do ( exit /B 0 ) +REM Visual Studio 2026 +set VSWHERE_LMT=-version "[18.0,19.0)" +set VSWHERE_PRERELEASE=-prerelease +SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT% %VSWHERE_PRERELEASE% +for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do ( + endlocal + echo Found with vswhere %%i + @rem comment out setting VCINSTALLDIR for Boost.build + @rem set "VCINSTALLDIR=%%i\VC\" + set "VS180COMNTOOLS=%%i\Common7\Tools\" + exit /B 0 +) + REM Visual Studio 2022 set VSWHERE_LMT=-version "[17.0,18.0)" set VSWHERE_PRERELEASE=-prerelease diff --git a/src/tools/asciidoctor.jam b/src/tools/asciidoctor.jam index 8bf173f5b..f8b73c744 100644 --- a/src/tools/asciidoctor.jam +++ b/src/tools/asciidoctor.jam @@ -147,7 +147,16 @@ rule init ( command * ) { local t = [ common.find-tool $(c) ] ; t ?= $(c) ; - ASCIIDOCTOR += $(t) ; + if [ MATCH "(\ )" : $(t) ] + { + # Ruby handles quotes weirdly. So we only add them if absolutely + # needed. + ASCIIDOCTOR += \"$(t)\" ; + } + else + { + ASCIIDOCTOR += $(t) ; + } } } @@ -217,5 +226,5 @@ feature.compose pdf : "-r asciidoctor-pdf" ; actions convert { - "$(ASCIIDOCTOR)" -o$(_)"$(<:D=)" -D$(_)"$(<:D)" -b$(_)"$(BACKEND)" -a$(_)"$(ATTRIBUTE)" -d$(_)"$(DOCTYPE)" $(FLAGS) "$(>)" + $(ASCIIDOCTOR) -o$(_)"$(<:D=)" -D$(_)"$(<:D)" -b$(_)"$(BACKEND)" -a$(_)"$(ATTRIBUTE)" -d$(_)"$(DOCTYPE)" $(FLAGS) "$(>)" } diff --git a/src/tools/clang-darwin.jam b/src/tools/clang-darwin.jam index b581e750d..07ef39476 100644 --- a/src/tools/clang-darwin.jam +++ b/src/tools/clang-darwin.jam @@ -50,7 +50,8 @@ rule init ( version ? : command * : options * ) : version $(version) ] ; common.handle-options clang-darwin : $(condition) : $(command) : $(options) ; - clang.init-flags clang-darwin : $(condition) : $(version) ; + clang.init-flags clang-darwin : $(condition) : $(version) : + [ feature.get-values : $(options) ] ; # - Archive builder. local archiver = [ feature.get-values : $(options) ] ; diff --git a/src/tools/clang-linux.jam b/src/tools/clang-linux.jam index ce270c584..3d6e34e67 100644 --- a/src/tools/clang-linux.jam +++ b/src/tools/clang-linux.jam @@ -13,7 +13,13 @@ = Clang (GCC frontend) The `clang-linux` module supports Clang with GCC frontend and has the same -options as link:#b2.reference.tools.compiler.gcc[`gcc`] toolset. +options as link:#b2.reference.tools.compiler.gcc[`gcc`] toolset, with the +addition of `` option. + +The value of that option is passed as the value of `--target=` flag, unless +provided as `none`. In that case the flag is not passed to the build +tools. If the option is not provided the build system may try to guess the +correct target triple. |# # end::doc[] @@ -68,7 +74,8 @@ rule init ( version ? : command * : options * ) { : version $(version) ] ; common.handle-options clang-linux : $(condition) : $(command) : $(options) ; - clang.init-flags clang-linux : $(condition) : $(version) ; + clang.init-flags clang-linux : $(condition) : $(version) : + [ feature.get-values : $(options) ] ; # Support for gcc root as the backend, this is mainly useful for clang/gcc on Windows # since on Linux gcc will be the default compiler already located on the PATH. @@ -167,8 +174,8 @@ toolset.flags clang-linux.compile OPTIONS on/full : -flto=full ; toolset.flags clang-linux.link OPTIONS on/full : -flto=full ; # stdlib selection -toolset.flags clang-linux.compile OPTIONS gnu gnu11 : -stdlib=libstdc++ ; -toolset.flags clang-linux.link OPTIONS gnu gnu11 : -stdlib=libstdc++ ; +toolset.flags clang-linux.compile.c++ OPTIONS gnu gnu11 libstdc++ : -stdlib=libstdc++ ; +toolset.flags clang-linux.link OPTIONS gnu gnu11 libstdc++ : -stdlib=libstdc++ ; -toolset.flags clang-linux.compile OPTIONS libc++ : -stdlib=libc++ ; +toolset.flags clang-linux.compile.c++ OPTIONS libc++ : -stdlib=libc++ ; toolset.flags clang-linux.link OPTIONS libc++ : -stdlib=libc++ ; diff --git a/src/tools/clang-win.jam b/src/tools/clang-win.jam index 0c1c415bf..8f2a18f6f 100644 --- a/src/tools/clang-win.jam +++ b/src/tools/clang-win.jam @@ -78,7 +78,8 @@ rule init ( version ? : command * : options * ) if ! $(command) { - errors.error "Cannot configure toolset clang-win: no 'clang-cl.exe' command found or given" ; + errors.error "Cannot configure toolset clang-win: no 'clang-cl.exe' command found or given." + "Searched in:" "$(ProgramFiles)\\LLVM\\bin" ; } local compiler = "\"$(command)\"" ; diff --git a/src/tools/clang.jam b/src/tools/clang.jam index fa5528b3e..b58aedb6b 100644 --- a/src/tools/clang.jam +++ b/src/tools/clang.jam @@ -92,20 +92,36 @@ local rule init-flags-cross ( toolset : condition * : architecture + : address-m case x86-32 : arch = i386 ; } - toolset.flags $(toolset) - OPTIONS $(condition)/$(target-os)/$(_architecture_)/$(_address-model_) - : "--target=$(arch)-$(vendor-sys)" - : unchecked ; + set-triple $(toolset) : + $(condition)/$(target-os)/$(_architecture_)/$(_address-model_) + : "$(arch)-$(vendor-sys)" + ; } } } -rule init-flags ( toolset : condition * : version ) +local rule set-triple ( toolset : condition : triple ) +{ + toolset.flags $(toolset) OPTIONS $(condition) : --target=$(triple) + : unchecked ; +} + +rule init-flags ( toolset : condition * : version : triple ? ) { init-cxxstd-flags $(toolset) : $(condition) : $(version) ; - init-flags-cross $(toolset) : $(condition) : arm x86 : 64 : darwin ; - init-flags-cross $(toolset) : $(condition) : arm x86 : 64 32 : linux ; + if ! $(triple) + { + init-flags-cross $(toolset) : $(condition) : arm x86 : 64 : darwin ; + init-flags-cross $(toolset) : $(condition) : arm x86 : 64 32 : linux ; + } + else + { + if $(triple) != none + { + set-triple $(toolset) : $(condition) : $(triple) ; + } + } # This is a temporary solution for doing combined architecture builds on macOS. toolset.flags $(toolset) diff --git a/src/tools/embarcadero.jam b/src/tools/embarcadero.jam index 2baf29e7c..5a561ebb5 100644 --- a/src/tools/embarcadero.jam +++ b/src/tools/embarcadero.jam @@ -150,6 +150,7 @@ toolset.inherit-flags embarcadero shared multi multi/windows + libstdc++ gnu gnu11 libc++ diff --git a/src/tools/emscripten.jam b/src/tools/emscripten.jam index 0ed289fae..fb08272de 100644 --- a/src/tools/emscripten.jam +++ b/src/tools/emscripten.jam @@ -186,3 +186,7 @@ toolset.flags emscripten.link OPTIONS full : --closure 2 ; # things for old fastcomp backend which was removed in 2.0.0 (08/10/2020) toolset.flags emscripten.link OPTIONS on : --llvm-lto 1 ; toolset.flags emscripten.link OPTIONS full : --llvm-lto 3 ; + +# Memory64/wasm64 support +toolset.flags emscripten.compile OPTIONS 64 : -sMEMORY64=1 ; +toolset.flags emscripten.link OPTIONS 64 : -sMEMORY64=1 ; diff --git a/src/tools/features/contracts-feature.jam b/src/tools/features/contracts-feature.jam new file mode 100644 index 000000000..97268bba8 --- /dev/null +++ b/src/tools/features/contracts-feature.jam @@ -0,0 +1,48 @@ +# Copyright 2025 René Ferdinand Rivera Morel +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at +# https://www.bfgroup.xyz/b2/LICENSE.txt) + +import feature ; + +#| tag::doc[] + +[[b2.builtin.features.contracts]]`contracts`:: +*Allowed values:* `on`. ++ +Enables use of experimental use of {CPP}-26 Contracts (P2900). Enabling +contracts has additional requirements when using them with at least clang. See +https://contracts.efcs.ca/ for details. For B2 the requirements amount to +needing to use `clang:libc++` and `23`. + +|# # end::doc[] + +feature.feature contracts + : on + : optional propagated link-incompatible ; + +#| tag::doc[] + +[[b2.builtin.features.contracts-sematic]]`contracts-semantic`:: +*Subfeature of* `contracts` ++ +*Allowed values:* `enforce', 'quick_enforce', 'observe', 'ignore`. ++ +Specifies the contract checking semantic for the translation unit. The default +is `enforce` for which contract checks are evaluated with violations resulting +in error termination. ++ +`enforce`::: Contract assertions are not evaluated (contracts are disabled). +`quick_enforce`::: Contract assertions are evaluated but violations do not + terminate the program. +`observe`::: Contract assertions are evaluated and violations terminate the + program. +`ignore`::: Like enforce, but uses optimized evaluation that may skip some + checks. + +|# # end::doc[] + +feature.subfeature contracts + : semantic + : enforce quick_enforce observe ignore + : ; diff --git a/src/tools/features/cxxstd-feature.jam b/src/tools/features/cxxstd-feature.jam index 2ab531459..9737cfeae 100644 --- a/src/tools/features/cxxstd-feature.jam +++ b/src/tools/features/cxxstd-feature.jam @@ -19,8 +19,8 @@ up to the released standard version. Those are included following the GNU nomenclature as `0x`, `1y`, `1z`, `2a`, `2b` and `2c`. Depending on the compiler `latest` would map to one of those. -NOTE: This is an `optional` feature. Hence when not specified the compiler -default behaviour is used. +TIP: This is an `optional` feature. Hence when not specified the compiler +default behavior is used. NOTE: Please consult the toolset specific documentation for which `cxxstd` is supported. diff --git a/src/tools/features/stdlib-feature.jam b/src/tools/features/stdlib-feature.jam index c97e91798..b0a99b9e4 100644 --- a/src/tools/features/stdlib-feature.jam +++ b/src/tools/features/stdlib-feature.jam @@ -8,14 +8,16 @@ import feature ; #| tag::doc[] [[b2.builtin.features.stdlib]]`stdlib`:: -*Allowed values*: `native`, `gnu`, `gnu11`, `libc++`, `sun-stlport`, `apache`. +*Allowed values*: `native`, `libstdc++`, `gnu`, `gnu11`, `libc++`, +`sun-stlport`, `apache`. + Specifies C++ standard library to link to and in some cases the library ABI to use: + `native`::: Use compiler's default. -`gnu`::: Use GNU Standard Library (a.k.a. pass:[libstdc++]) with the old ABI. -`gnu11`::: Use GNU Standard Library with the new ABI. +`libstdc++`::: Use GNU Standard Library (a.k.a. pass:[libstdc++]). +`gnu`::: Use GNU Standard Library and explicitly enable the old ABI. +`gnu11`::: Use GNU Standard Library and explicitly enable the new ABI. `libc++`::: Use LLVM pass:[libc++]. `sun-stlport`::: Use the STLport implementation of the standard library provided with the Solaris Studio compiler. @@ -25,5 +27,5 @@ use: |# # end::doc[] feature.feature stdlib - : native gnu gnu11 libc++ sun-stlport apache + : native libstdc++ gnu gnu11 libc++ sun-stlport apache : propagated composite ; diff --git a/src/tools/gcc.jam b/src/tools/gcc.jam index 2b6caed41..acf02ce26 100644 --- a/src/tools/gcc.jam +++ b/src/tools/gcc.jam @@ -1,6 +1,6 @@ # Copyright 2021 Nikita Kniazev # Copyright 2001 David Abrahams -# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2025 René Ferdinand Rivera Morell # Copyright 2002-2003 Vladimir Prus # Copyright 2005 Reece H. Dunn # Copyright 2006 Ilya Sokolov @@ -716,6 +716,13 @@ toolset.flags gcc.link OPTIONS on/fat : -flto ; toolset.flags gcc.compile.c++ DEFINES gnu : _GLIBCXX_USE_CXX11_ABI=0 ; toolset.flags gcc.compile.c++ DEFINES gnu11 : _GLIBCXX_USE_CXX11_ABI=1 ; +# Contracts +toolset.flags gcc.compile.c++ OPTIONS on : -fcontracts ; +toolset.flags gcc.compile.c++ OPTIONS on/ignore : -fcontract-evaluation-semantic=ignore ; +toolset.flags gcc.compile.c++ OPTIONS on/observe : -fcontract-evaluation-semantic=observe ; +toolset.flags gcc.compile.c++ OPTIONS on/enforce : -fcontract-evaluation-semantic=enforce ; +toolset.flags gcc.compile.c++ OPTIONS on/quick_enforce : -fcontract-evaluation-semantic=quick_enforce ; + ### ### User free feature options. ### @@ -1070,7 +1077,7 @@ actions link bind LIBRARIES actions link.dll bind LIBRARIES { - "$(CONFIG_COMMAND)" @($(<[1]:T).rsp:O=FC:<=@":>=":E=-L"$(LINKPATH)" -Wl,$(RPATH_OPTION)$(SPACE)-Wl,$(RPATH) -Wl,$(IMPLIB_OPTION:E=--out-implib),"$(<[2]:T)" -o "$(<[1]:T)" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,"$(SONAME_PREFIX:E=)$(<[1]:D=)" $(SHARED_OPTION:E=-shared) $(START-GROUP) "$(>:T)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)) + "$(CONFIG_COMMAND)" @($(<[1]:T).rsp:O=FC:<=@":>=":E=-L"$(LINKPATH)" -Wl,$(RPATH_OPTION)$(SPACE)-Wl,$(RPATH) -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -Wl,$(IMPLIB_OPTION:E=--out-implib),"$(<[2]:T)" -o "$(<[1]:T)" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,"$(SONAME_PREFIX:E=)$(<[1]:D=)" $(SHARED_OPTION:E=-shared) $(START-GROUP) "$(>:T)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)) } ### @@ -1285,10 +1292,10 @@ cpu-flags gcc OPTIONS : s390x : z13 : -march=z13 ; cpu-flags gcc OPTIONS : s390x : z14 : -march=z14 ; cpu-flags gcc OPTIONS : s390x : z15 : -march=z15 ; # ARM -cpu-flags gcc OPTIONS : arm : cortex-a9+vfpv3 : -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard ; +cpu-flags gcc OPTIONS : arm : cortex-a9+vfpv3 : -mcpu=cortex-a9 -mfpu=vfpv3 ; cpu-flags gcc OPTIONS : arm : cortex-a53 : -mcpu=cortex-a53 ; cpu-flags gcc OPTIONS : arm : cortex-r5 : -mcpu=cortex-r5 ; -cpu-flags gcc OPTIONS : arm : cortex-r5+vfpv3-d16 : -mcpu=cortex-r5 -mfpu=vfpv3-d16 -mfloat-abi=hard ; +cpu-flags gcc OPTIONS : arm : cortex-r5+vfpv3-d16 : -mcpu=cortex-r5 -mfpu=vfpv3-d16 ; # AIX variant of RS/6000 & PowerPC toolset.flags gcc AROPTIONS 64/aix : "-X64" ; diff --git a/src/tools/generators/linking-generator.jam b/src/tools/generators/linking-generator.jam index 5c3f1a997..797c7222e 100644 --- a/src/tools/generators/linking-generator.jam +++ b/src/tools/generators/linking-generator.jam @@ -65,8 +65,12 @@ class linking-generator : generator # Pros: do not need to relink libraries when installing. # Cons: "standalone" libraries (plugins, python extensions) can not # hardcode paths to dependent libraries. + local target-type = $(self.target-types[1]) ; if [ $(property-set).get ] = true - && [ type.is-derived $(self.target-types[1]) EXE ] + && ( + [ type.is-derived $(target-type) EXE ] + || [ type.is-derived $(target-type) SHARED_LIB ] + ) { local xdll-path = [ $(property-set).get ] ; extra += $(xdll-path) $(extra-xdll-paths) ; diff --git a/src/tools/mpi.jam b/src/tools/mpi.jam index f65c19f44..d95fdd0a2 100644 --- a/src/tools/mpi.jam +++ b/src/tools/mpi.jam @@ -335,24 +335,24 @@ rule init ( mpicxx ? : options * : mpirun-with-options * ) if ! $(options) { # Try to auto-detect options based on the wrapper compiler - local command = [ common.get-invocation-command mpi : mpic++ : $(mpicxx) ] ; + local command = [ common.get-invocation-command-nodefault mpi : mpic++ : $(mpicxx) ] ; if ! $(mpicxx) && ! $(command) { # Try "mpiCC", which is used by MPICH - command = [ common.get-invocation-command mpi : mpiCC ] ; + command = [ common.get-invocation-command-nodefault mpi : mpiCC ] ; } if ! $(mpicxx) && ! $(command) { - # Try "mpicxx", which is used by OpenMPI and MPICH2 - command = [ common.get-invocation-command mpi : mpicxx ] ; + # Try "mpicxx", which is used by OpenMPI, MPICH2 and Intel MPI + command = [ common.get-invocation-command-nodefault mpi : mpicxx ] ; } if ! $(mpicxx) && ! $(command) { # Try "CC", which is used by Cray - command = [ common.get-invocation-command mpi : CC ] ; + command = [ common.get-invocation-command-nodefault mpi : CC ] ; } local result ; @@ -391,12 +391,13 @@ rule init ( mpicxx ? : options * : mpirun-with-options * ) result = [ SHELL "$(command) -showme" ] ; } - # Look for MPICH - else if [ safe-shell-command "$(command) -show" ] + # Look for MPICH or Intel MPI + else if [ safe-shell-command "$(command) -compile_info" ] && + [ safe-shell-command "$(command) -link_info" ] { if $(.debug-configuration) { - ECHO "Found MPICH wrapper compiler: $(command)" ; + ECHO "Found MPICH or Intel MPI wrapper compiler: $(command)" ; } compile_flags = [ SHELL "$(command) -compile_info" ] ; link_flags = [ SHELL "$(command) -link_info" ] ; diff --git a/src/tools/msvc.jam b/src/tools/msvc.jam index b6276bbf4..c92d7681c 100644 --- a/src/tools/msvc.jam +++ b/src/tools/msvc.jam @@ -23,6 +23,7 @@ https://docs.microsoft.com/en-us/cpp/[Microsoft Visual C++] command-line tools on Microsoft Windows. The supported products and versions of command line tools are listed below: +* Visual Studio 2026-14.5 * Visual Studio 2022-14.3 * Visual Studio 2019-14.2 * Visual Studio 2017—14.1 @@ -1154,7 +1155,15 @@ local rule generate-setup-cmd ( version : command : parent : options * : cpu : g } else { - if [ MATCH "(14.[34])" : $(version) ] + if [ MATCH "(14.5)" : $(version) ] + { + if $(.debug-configuration) + { + ECHO "notice: [generate-setup-cmd] $(version) is 14.5" ; + } + parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ; + } + else if [ MATCH "(14.[34])" : $(version) ] { if $(.debug-configuration) { @@ -1340,15 +1349,19 @@ local rule configure-really ( version ? : options * ) # version from the path. # FIXME: We currently detect both Microsoft Visual Studio 9.0 and # 9.0express as 9.0 here. - if [ MATCH "(MSVC\\\\14.[34])" : $(command) ] + if [ MATCH "(MSVC(\\/|\\\\)14.5)" : $(command) ] + { + version = 14.5 ; + } + else if [ MATCH "(MSVC(\\/|\\\\)14.[34])" : $(command) ] { version = 14.3 ; } - else if [ MATCH "(MSVC\\\\14.2)" : $(command) ] + else if [ MATCH "(MSVC(\\/|\\\\)14.2)" : $(command) ] { version = 14.2 ; } - else if [ MATCH "(MSVC\\\\14.1)" : $(command) ] + else if [ MATCH "(MSVC(\\/|\\\\)14.1)" : $(command) ] { version = 14.1 ; } @@ -1767,17 +1780,21 @@ local rule default-path ( version ) # And fortunately, forward slashes do also work in native Windows. local vswhere = "$(root)/Microsoft Visual Studio/Installer/vswhere.exe" ; # The check for $(root) is to avoid a segmentation fault if not found. - if $(version) in 14.1 14.2 14.3 default && $(root) && [ path.exists $(vswhere) ] + if $(version) in 14.1 14.2 14.3 14.5 default && $(root) && [ path.exists $(vswhere) ] { local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ; local prop = "-property installationPath" ; local limit ; - if $(version) = 14.3 + if $(version) = 14.5 + { + limit = "-version \"[18.0,19.0)\" -prerelease" ; + } + else if $(version) = 14.3 || $(version) = "default" { limit = "-version \"[17.0,18.0)\" -prerelease" ; } - else if $(version) = 14.2 || $(version) = "default" + else if $(version) = 14.2 { limit = "-version \"[16.0,17.0)\"" ; } @@ -2197,7 +2214,7 @@ for local arch in [ MATCH "^\\.cpus-on-(.*)" : [ VARNAMES $(__name__) ] ] armv7 armv7s ; # Known toolset versions, in order of preference. -.known-versions = 14.3 14.2 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1 +.known-versions = 14.5 14.3 14.2 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ; # Version aliases. @@ -2231,25 +2248,30 @@ for local arch in [ MATCH "^\\.cpus-on-(.*)" : [ VARNAMES $(__name__) ] ] # path will be checked instead. .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003/bin" ; .version-7.1toolkit-env = VCToolkitInstallDir ; + # Visual Studio 2017 doesn't use a registry at all. And the suggested methods # of discovery involve having a compiled program. So as a fallback we search # paths for VS2017 (aka msvc >= 14.1). .version-14.1-path = "../../VC/Tools/MSVC/*/bin/Host*/*" - "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*" - ; + "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*" ; .version-14.1-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ; + .version-14.2-path = "../../VC/Tools/MSVC/*/bin/Host*/*" - "Microsoft Visual Studio/2019/*/VC/Tools/MSVC/*/bin/Host*/*" - ; + "Microsoft Visual Studio/2019/*/VC/Tools/MSVC/*/bin/Host*/*" ; .version-14.2-env = VS160COMNTOOLS ProgramFiles ProgramFiles(x86) ; + .version-14.3-path = "../../VC/Tools/MSVC/*/bin/Host*/*" - "Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/bin/Host*/*" - ; + "Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/bin/Host*/*" ; .version-14.3-env = VS170COMNTOOLS ProgramFiles ProgramFiles(x86) ; +.version-14.5-path = + "../../VC/Tools/MSVC/*/bin/Host*/*" + "Microsoft Visual Studio/18/*/VC/Tools/MSVC/14.5*/bin/Host*/*" ; +.version-14.5-env = VS180COMNTOOLS ProgramFiles ProgramFiles(x86) ; + # And finally trigger the actual Boost Build toolset registration. register-toolset ; diff --git a/src/tools/pkg-config.jam b/src/tools/pkg-config.jam index 8ddb66d83..1e973bb64 100644 --- a/src/tools/pkg-config.jam +++ b/src/tools/pkg-config.jam @@ -13,7 +13,9 @@ import feature ; import os ; import param ; import project ; +import property-set ; import regex ; +import set ; import sequence ; import string ; import targets ; @@ -41,7 +43,7 @@ section <>. |# # end::doc[] -feature.feature pkg-config : : propagated ; +feature.feature pkg-config : : optional propagated ; #| tag::doc[] @@ -74,11 +76,10 @@ feature.feature pkg-config-define : : free ; Main target rule that imports a *pkg-config* package. When its consumer targets are built, *pkg-config* command will be invoked with arguments that depend on -current property set. The features that have an effect are: +the current property set. The features that have an effect are: * ``: adds a `--define-variable` argument; * ``: adds `--static` argument when `static`; -* ``: adds `--static` argument when `static`; * ``: specifies package name (target name is used instead if the property is not present); * ``: specifies package version range, can be used multiple times and @@ -96,7 +97,8 @@ pkg-config.import my-package |# # end::doc[] -rule import +# will be re-exported as 'import' +local rule do-import ( target-name : sources * : requirements * @@ -127,7 +129,7 @@ with the `using` rule: [source, jam] ---- -using pkg-config : [config] : [command] ... : [ options ] ... ; +using pkg-config : [config] : [command] ... : [ options ] ... : [condition] ... ; ---- @@ -137,39 +139,62 @@ using pkg-config : [config] : [command] ... : [ options ] ... ; is given, first `PKG_CONFIG` environment variable is checked, and if its empty the string `pkg-config` is used. * `options`: options that modify `pkg-config` behavior. Allowed options are: - * ``: sets `PKG_CONFIG_PATH` environment variable; + ** ``: sets `PKG_CONFIG_PATH` environment variable; multiple occurences are allowed. - * ``: sets `PKG_CONFIG_LIBDIR` environment variable; + ** ``: sets `PKG_CONFIG_LIBDIR` environment variable; multiple occurences are allowed. - * ``: sets `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS` + ** ``: sets `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS` environment variable; multiple occurences are allowed. - * ``: sets `PKG_CONFIG_ALLOW_SYSTEM_LIBS` + ** ``: sets `PKG_CONFIG_ALLOW_SYSTEM_LIBS` environment variable; multiple occurences are allowed. - * ``: sets `PKG_CONFIG_SYSROOT_DIR` environment variable; + ** ``: sets `PKG_CONFIG_SYSROOT_DIR` environment variable; multiple occurences are allowed. - * ``: adds a variable definition argument to command invocation; + ** ``: adds a variable definition argument to command invocation; multiple occurences are allowed. +* `condition`: properties that distinguish this configuration. |# # end::doc[] -rule init ( config ? : command * : options * ) +rule init ( config ? : command * : options * : condition * ) { + if ! $(.initialized) + { + .initialized = true ; + + project.initialize $(__name__) ; + project $(__name__) ; + + # project.initialize would have replaced import rule in this module, so + # we have to resort to this + IMPORT $(__name__) : do-import : $(__name__) : import ; + EXPORT $(__name__) : import ; + } + if ! $(config) { config = [ default-config ] ; - if ( $(config) in [ $(.configs).all ] ) - && ! ( $(command) || $(options) ) + if $(config) in [ $(.configs).used ] { - return ; + config = ; } } + if ! $(config) && ! $(condition) + { + return ; + } local tool = [ os.environ PKG_CONFIG ] ; tool ?= pkg-config ; command = [ common.get-invocation-command pkg-config : $(tool) : $(command) ] ; - configure $(config) : $(command) : $(options) ; + local condition = [ property-set.create $(condition) ] ; + local base = [ $(condition).base ] ; + local conditional = [ $(condition).conditional ] ; + condition = [ property-set.create + [ set.difference $(base) : $(conditional) ] ] ; + + configure $(config) : $(command) : $(options) : $(condition) ; $(.configs).use $(config) ; } @@ -231,7 +256,7 @@ class pkg-config-target : alias-target-class rule construct ( name : sources * : property-set ) { - local config = [ $(property-set).get ] ; + local config = [ get-config $(property-set) ] ; local args = [ common-arguments $(name) : $(property-set) ] ; return [ property-set.create @@ -242,7 +267,7 @@ class pkg-config-target : alias-target-class rule version ( property-set ) { - local config = [ $(property-set).get ] ; + local config = [ get-config $(property-set) ] ; local args = [ common-arguments [ name ] : $(property-set) ] ; local version = [ pkg-config.run $(config) : --modversion $(args) ] ; return [ regex.split $(version) "\\." ] ; @@ -308,16 +333,103 @@ class pkg-config-target : alias-target-class local flags = [ pkg-config.run $(config) : --cflags $(args) ] ; return $(flags) ; } + + local rule get-config ( property-set ) + { + local result = [ $(property-set).get ] ; + if $(result) + { + return $(result) ; + } + + result = [ select-configuration $(property-set) ] ; + if ! $(result) + { + echo "error: No best pkg-config configuration for" + [ $(property-set).raw ] ; + select-configuration $(property-set) : trace ; + return [ pkg-config.default-config ] ; + } + else + { + return $(result) ; + } + } + + local rule select-configuration ( property-set : trace ? ) + { + local best-config ; + local best-condition ; + local ambiguous ; + local request = [ $(property-set).raw ] ; + local configs = [ pkg-config.get-configs ] ; + local used-configs = [ $(configs).used ] ; + while $(used-configs) && ! $(ambiguous) + { + local config = $(used-configs[1]) ; + local condition = [ $(configs).get $(config) : condition ] ; + local condition = [ feature.expand-subfeatures + [ $(condition).raw ] : unchecked ] ; + if $(condition) in $(request) + { + if $(trace) + { + echo " matched:" $(condition:E=(empty)) ; + } + if ! $(best-config) + { + best-config = $(config) ; + best-condition = $(condition) ; + } + else + { + if $(condition) = $(best-condition) + { + ambiguous = true ; + } + else if $(condition) in $(best-condition) + { + # Do nothing, this alternative is worse + } + else if $(best-condition) in $(condition) + { + best-config = $(config) ; + best-condition = $(condition) ; + } + else + { + ambiguous = true ; + } + } + } + else + { + if $(trace) + { + echo " no match:" $(condition:E=(empty)) ; + } + } + used-configs = $(used-configs[2-]) ; + } + + if $(ambiguous) + { + return ; + } + else + { + return $(best-config) ; + } + } } - -local rule default-config ( ) +rule default-config ( ) { return default ; } -local rule configure ( config : command + : options * ) +local rule configure ( config : command + : options * : condition ) { $(.configs).register $(config) ; @@ -380,6 +492,7 @@ local rule configure ( config : command + : options * ) : command : "$(path)$(libdir)$(sysroot)$(allow-cflags)$(allow-libs)$(command:J= )" ; + $(.configs).set $(config) : condition : $(condition) ; feature.extend pkg-config : $(config) ; } @@ -410,6 +523,10 @@ local rule non-empty ( string ) .configs = [ new configurations ] ; +rule get-configs ( ) +{ + return $(.configs) ; +} #| tag::doc[] @@ -441,8 +558,16 @@ project ---- Thanks to the fact, that `project-config`, `user-config` and `site-config` -modules are parents of jamroot module, you can put it in any of those files.o +modules are parents of jamroot module, you can put it in any of those files. +Alternatively, you can use the condition argument during initialization, and +achieve the same thing without project requirements: + +[source, jam] +---- +using pkg-config : A : : path/to/collection/A : A-os A-arch ; +using pkg-config : B : : path/to/collection/B : B-os B-arch ; +---- === Choosing the package name based on the property set @@ -468,7 +593,7 @@ rule infer-name ( properties * ) } ---- -The `common.format-name` rule can be very useful in this situation. +The rule `common.format-name` can be very useful in such situations. === Modify usage requirements based on package version or variable diff --git a/src/tools/python.jam b/src/tools/python.jam index 745551324..dceeed530 100644 --- a/src/tools/python.jam +++ b/src/tools/python.jam @@ -561,6 +561,11 @@ local rule compute-default-paths ( target-os : version ? : prefix ? : else { local default-include-path = $(prefix)/include/python$(version) ; + if ! [ path.exists $(default-include-path) ] && [ path.exists $(default-include-path)t ] + { + default-include-path = $(default-include-path)t ; + } + if ! [ path.exists $(default-include-path) ] && [ path.exists $(default-include-path)m ] { default-include-path = $(default-include-path)m ; diff --git a/src/tools/qcc.jam b/src/tools/qcc.jam index 1603f5b24..fea3dfade 100644 --- a/src/tools/qcc.jam +++ b/src/tools/qcc.jam @@ -13,6 +13,7 @@ import errors ; import feature ; import generators ; import os ; +import pch ; import property ; import regex ; import set ; @@ -123,7 +124,7 @@ toolset.flags qcc.compile OPTIONS shared : -shared ; toolset.flags qcc.compile.c++ TEMPLATE_DEPTH ; -rule compile.c++ +rule compile.c++ ( targets * : sources * : properties * ) { # Here we want to raise the template-depth parameter value to something # higher than the default value of 17. Note that we could do this using the @@ -137,7 +138,7 @@ rule compile.c++ local template-depth = [ on $(1) return $(TEMPLATE_DEPTH) ] ; if ! $(template-depth) { - TEMPLATE_DEPTH on $(1) = 128 ; + TEMPLATE_DEPTH on $(1) = 256 ; } check-target-platform $(1) ; @@ -153,7 +154,7 @@ actions compile.c++ "$(CONFIG_COMMAND)" $(QCC-TARGET-PLATFORM) -Wc,-ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" } -rule compile.c +rule compile.c ( targets * : sources * : properties * ) { check-target-platform $(1) ; diff --git a/src/tools/vcpkg.jam b/src/tools/vcpkg.jam new file mode 100644 index 000000000..3b5ab6e29 --- /dev/null +++ b/src/tools/vcpkg.jam @@ -0,0 +1,393 @@ +#| +Copyright 2023 Dmitry Arkhipov (grisumbras@yandex.ru) +Distributed under the Boost Software License, Version 1.0. (See +accompanying file LICENSE.txt or copy at +https://www.bfgroup.xyz/b2/LICENSE.txt) +|# + +import errors ; +import feature ; +import msvc ; +import os ; +import path ; +import project ; +import property ; +import property-set ; +import targets ; + +import "class" : new ; + +#| tag::doc[] + +[[b2.tasks.packagemanagers.vcpkg]] += vcpkg support +https://learn.microsoft.com/vcpkg[vcpkg] is a cross-platform package manager +for C and {CPP} developed by Microsoft. vcpkg provides first-class support +for CMake and MSBuild build systems, but you can still use packages installed +by vcpkg in b2 either as link:#b2.tutorial.prebuilt[prebuilt libraries], +with the help of link:#_pkg_config[pkg-config] tool, or if the package provides +a link:#b2.extending.toolset_modules[toolset module]. In-built toolset modules +(e.g. `openssl` are already integrated with this module). + +The module declares the project `/vcpkg` with a main target `/vcpkg//prefix`. +The target can be used as a dependency to add its `` and `` +usage requirements. + +[source, jam] +---- +lib sqlite3 : /vcpkg//prefix ; +---- + +|# # end::doc[] + +if --debug-configuration in [ modules.peek : ARGV ] +{ + .debug = true ; +} + +#| tag::doc[] + + +== Initialization +To enable vcpkg integration you need to declare it in a configuration file +with the help of `using` rule: + +[source, jam] +---- +using vcpkg : [root] : [options] ... : [ condition ] ... ; +---- + +* `root`: vcpkg installation root. + +* `options`: options that specify the location of vcpkg package installation + tree. Allowed options are: + + ** ``: directory with header files; + ** ``: directory with library binaries; + ** ``: installation prefix for the triplet; + ** ``: the triplet to use. + +* `condition`: properties that distinguish this configuration. + +If options contain neither `` nor ``, they are set to +`include` and `lib` subdirectories of ``. + +If options do not contain ``, it is set to `root/`. + +If `root` is empty, it is set to `installed` subdirectory of the directory +pointed to by `VCPKG_ROOT` environment variable if it is not empty. Otherwise, +https://learn.microsoft.com/vcpkg/concepts/manifest-mode[Manisfest mode] is +assumed, and `vcpkg.json` file is searched for in the current directory and its +parents. If the file is found, then `root` is set to `vcpkg_installed` +subdirectory of its parent directory. + +If options do not contain ``, it is set to the value of +`VCPKG_DEFAULT_TRIPLET` environment variable if it is not empty. Otherwise, +if there is exactly one triplet subdirectory of `root` directory, then its +name is used. + +If `condition` does not contain a property of ``, and `options` do not +contain ``, then two versions are configured: one for +`release` that sets `` to `/lib`, and another for +`debug` that sets `` to `/debug/lib`. + +Finally, if `options` contain none of ``, ``, ``, and +`` and `requirements` are empty, appropriate configurations for +several default triplets provided by vcpkg are made. + +|# # end::doc[] + +rule init ( root ? : options * : condition * ) +{ + local incdir = [ feature.get-values : $(options) ] ; + local libdir = [ feature.get-values : $(options) ] ; + local prefix = [ feature.get-values : $(options) ] ; + local triplet = [ feature.get-values : $(options) ] ; + + if ( ( $(root) || $(triplet) ) && ( $(prefix) || $(incdir) || $(libdir) ) ) + || ( $(prefix) && ( $(incdir) || $(libdir) ) ) + || ( $(incdir) && ! $(libdir) ) + || ( $(libdir) && ! $(incdir) ) + { + errors.user-error "incompatible options for vcpkg:" $(options) ; + } + + local kind = predefined-triplets ; + if $(prefix) || $(incdir) || $(libdir) || $(triplet) || $(condition) + { + kind = specific-triplet ; + } + + if ! $(.initialized) + { + .initialized = true ; + + project.initialize $(__name__) ; + project $(__name__) ; + } + else + { + if ! $(options) && ! $(condition) + { + kind = ; + } + } + + local project = [ project.target $(__name__) ] ; + + switch $(kind) + { + case predefined-triplets : + configure-predefined $(project) : $(root) ; + case specific-triplet : + configure-specific $(project) : $(root) : $(triplet) : $(prefix) + : $(incdir) : $(libdir) : $(condition) ; + } +} + +local rule configure-predefined ( project : root ? ) +{ + if ! $(root) + { + root = [ deduce-root ] ; + } + + # arm-neon-android, arm6-android, arm64ec-windows, wasm32-emscripten, + # all xbox, mingw, and -release triplets are skipped + + # Linux + configure-specific $(project) : $(root) : x64-linux : : : + : linux 64 x86 static shared ; + configure-specific $(project) : $(root) : x64-linux-dynamic : : : + : linux 64 x86 shared shared ; + + configure-specific $(project) : $(root) : x86-linux : : : + : linux 32 x86 static shared ; + + configure-specific $(project) : $(root) : arm-linux : : : + : linux 32 arm static shared ; + + configure-specific $(project) : $(root) : arm64-linux : : : + : linux 64 arm static shared ; + + configure-specific $(project) : $(root) : ppc64le-linux : : : + : linux 64 power static shared ; + + configure-specific $(project) : $(root) : riscv32-linux : : : + : linux 32 riscv static shared ; + + configure-specific $(project) : $(root) : riscv64-linux : : : + : linux 64 riscv static shared ; + + configure-specific $(project) : $(root) : s390x-linux : : : + : linux 64 s390x static shared ; + + # Windows + configure-specific $(project) : $(root) : x64-windows : : : + : windows 64 x86 shared shared desktop ; + configure-specific $(project) : $(root) : x64-windows-static : : : + : windows 64 x86 static static desktop ; + configure-specific $(project) : $(root) : x64-windows-static-md : : : + : windows 64 x86 static shared desktop ; + + configure-specific $(project) : $(root) : x86-windows : : : + : windows 32 x86 shared shared desktop ; + configure-specific $(project) : $(root) : x86-windows-static-md : : : + : windows 32 x86 static shared desktop ; + configure-specific $(project) : $(root) : x86-windows-static : : : + : windows 32 x86 static static desktop ; + + configure-specific $(project) : $(root) : arm64-windows : : : + : windows 64 arm shared shared desktop ; + configure-specific $(project) : $(root) : arm64-windows-static-md : : : + : windows 64 arm static shared desktop ; + configure-specific $(project) : $(root) : arm64-windows-static : : : + : windows 64 arm static static desktop ; + + configure-specific $(project) : $(root) : arm-windows : : : + : windows 32 arm shared shared desktop ; + configure-specific $(project) : $(root) : arm-windows-static : : : + : windows 32 arm static static desktop ; + + # WindowsStore + configure-specific $(project) : $(root) : x64-uwp : : : + : windows 64 x86 shared shared store ; + configure-specific $(project) : $(root) : x64-uwp-static-md : : : + : windows 64 x86 static shared store ; + + configure-specific $(project) : $(root) : x86-uwp : : : + : windows 32 x86 shared shared store ; + configure-specific $(project) : $(root) : x86-uwp-static-md : : : + : windows 32 x86 static shared store ; + + configure-specific $(project) : $(root) : arm64-uwp : : : + : windows 64 arm shared shared store ; + configure-specific $(project) : $(root) : arm64-uwp-static-md : : : + : windows 64 arm static shared store ; + + configure-specific $(project) : $(root) : arm-uwp : : : + : windows 32 arm shared shared store ; + configure-specific $(project) : $(root) : arm-uwp-static-md : : : + : windows 32 arm static shared store ; + + # OSX + configure-specific $(project) : $(root) : x64-osx : : : + : darwin 64 x86 static shared ; + configure-specific $(project) : $(root) : x64-osx-dynamic : : : + : darwin 64 x86 shared shared ; + + configure-specific $(project) : $(root) : arm64-osx-dynamic : : : + : darwin 64 arm shared shared ; + configure-specific $(project) : $(root) : arm64-osx : : : + : darwin 64 arm static shared ; + + # Android + configure-specific $(project) : $(root) : x64-android : : : + : android 64 x86 static static ; + + configure-specific $(project) : $(root) : x86-android : : : + : android 32 x86 static static ; + + configure-specific $(project) : $(root) : arm64-android : : : + : android 64 arm static static ; + + configure-specific $(project) : $(root) : arm-android : : : + : android 32 arm static static ; + + # iPhone + configure-specific $(project) : $(root) : arm-ios : : : + : iphone 32 arm static shared ; + + configure-specific $(project) : $(root) : arm64-ios : : : + : iphone 64 arm static shared ; + + configure-specific $(project) : $(root) : x64-ios : : : + : iphone 64 x86 static shared ; + + configure-specific $(project) : $(root) : x86-ios : : : + : iphone 32 x86 static shared ; + + # FreeBSD + configure-specific $(project) : $(root) : x64-freebsd : : : + : freebsd 64 x86 static shared ; + + configure-specific $(project) : $(root) : x86-freebsd : : : + : freebsd 32 x86 static shared ; + + # OpenBSD + configure-specific $(project) : $(root) : x64-openbsd : : : + : openbsd 64 x86 static shared ; + +} + +local rule configure-specific ( project : root ? : triplet ? : prefix ? + : incdir ? : libdir ? : condition + ) +{ + local with-debug ; + if ! $(incdir) || ! $(libdir) + { + if ! $(prefix) + { + prefix = [ deduce-prefix $(root) : $(triplet) ] ; + } + incdir ?= [ path.join $(prefix) include ] ; + libdir ?= [ path.join $(prefix) lib ] ; + if ! [ property.select : $(condition) ] + { + with-debug = true ; + } + } + + if $(with-debug) + { + declare-target $(project) : $(incdir) : $(libdir) + : $(condition) release ; + declare-target $(project) : $(incdir) + : [ path.join $(prefix) debug/lib ] + : $(condition) debug ; + } + else + { + declare-target $(project) : $(incdir) : $(libdir) : $(condition) ; + } +} + +local rule declare-target ( project : incdir : libdir : condition * ) +{ + if $(.debug) + { + echo "notice: [vcpkg] configuring with" $(incdir) + $(libdir) ; + } + + targets.main-target-alternative + [ new alias-target-class prefix + : $(project) + : + : [ property-set.create $(condition) ] + : + : [ property-set.create $(incdir) $(libdir) ] + ] ; + + local pkg-config-libdir = [ path.join $(libdir) pkgconfig ] ; + using pkg-config : [ property-set.create $(condition) ] : + : $(pkg-config-libdir) : $(condition) ; +} + +local rule deduce-prefix ( root ? : triplet ? ) +{ + if ! $(root) + { + root = [ deduce-root ] ; + } + + triplet ?= [ os.environ VCPKG_DEFAULT_TRIPLET ] ; + if ! $(triplet) && $(root) + { + local ignored = [ path.join $(root) vcpkg ] ; + for local p in [ path.glob $(root) : * ] + { + if $(p) != $(ignored) + { + triplet += $(p:B) ; + } + } + if $(triplet[2]) + { + triplet = ; + } + } + + if ! $(root) || ! $(triplet) + { + errors.user-error "could not initialize vcpkg module:" + "vcpkg installation could not be deduced" ; + } + + return [ path.join $(root) $(triplet) ] ; +} + +local rule deduce-root ( ) +{ + # attempt to locate vcpkg installation using environment variable + local root = [ os.environ VCPKG_ROOT ] ; + if $(root) + { + root = [ path.join [ path.make $(root) ] installed ] ; + } + else + { + # check if Manifest mode is used + local roots = . [ path.all-parents . ] ; + while $(roots) && ! $(root) + { + if [ path.glob $(roots[1]) : vcpkg.json ] + { + root = $(roots[1])/vcpkg_installed ; + } + roots = $(roots[2-]) ; + } + } + + return $(root) ; +} diff --git a/src/util/option.jam b/src/util/option.jam index 2626b9b48..a2c2065d1 100644 --- a/src/util/option.jam +++ b/src/util/option.jam @@ -23,6 +23,14 @@ rule get ( name : default-value ? : implied-value ? ) if ! $(m) && ! [ args.has-arg $(name) ] { m = [ MATCH --$(name)=(.*) : [ modules.peek : ARGV ] ] ; + if ! $(m) + { + m = [ MATCH (--$(name)) : [ modules.peek : ARGV ] ] ; + if $(m) + { + m = true ; + } + } } if $(m) && $(m) != true { diff --git a/test/escaping_dollar_before_round_bracket.py b/test/escaping_dollar_before_round_bracket.py new file mode 100755 index 000000000..1ad451246 --- /dev/null +++ b/test/escaping_dollar_before_round_bracket.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +# Copyright Ivan Kotov 2025. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at +# https://www.bfgroup.xyz/b2/LICENSE.txt) + +# Regression test. When Jamfile contained "using whatever ; " and the 'whatever' +# module declared a project, then all targets in Jamfile were considered to be +# declared in the project associated with 'whatever', not with the Jamfile. + +import BoostBuild + +t = BoostBuild.Tester(use_test_config=False) + +t.write("jamroot.jam", """\ + +rule test { + value = zero ; + echo $(value) ; + echo $$(value) ; + echo $$$(value) ; + echo $$$$(value) ; + echo $$$$ ; +} + +test a.test ; + +""") + +t.run_build_system(stdout="""zero +$(value) +$zero +$$(value) +$$$$ +...found 1 target... +""") + +t.cleanup() diff --git a/test/project_sub_resolution.py b/test/project_sub_resolution.py new file mode 100755 index 000000000..f4c69159a --- /dev/null +++ b/test/project_sub_resolution.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +# Copyright 2025 Dmitry Arkhipov +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt) + +# Test that subprojects of a project with rooted id can be resolved. + +import BoostBuild + +t = BoostBuild.Tester(use_test_config=False) + +t.write("jamroot.jam", """ +project /A ; +alias x ; +alias y : /A/B/C//c ; +alias z : /A/B//b ; +""") + +t.write("B/build.jam", "alias b ;") + +t.write("B/C/build.jam", "alias c ;") + +t.run_build_system() + +t.cleanup() diff --git a/test/test_all.py b/test/test_all.py index 8542efacb..8bfa81ea9 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +# Copyright 2025 René Ferdinand Rivera Morell # Copyright 2002-2005 Dave Abrahams. # Copyright 2002-2006 Vladimir Prus. # Distributed under the Boost Software License, Version 1.0. @@ -16,6 +17,8 @@ import os.path import time import signal import sys +import threading +import inspect xml = "--xml" in sys.argv toolset = BoostBuild.get_toolset() @@ -23,8 +26,17 @@ toolset = BoostBuild.get_toolset() # Clear environment for testing. # -for s in ("BOOST_ROOT", "BOOST_BUILD_PATH", "JAM_TOOLSET", "BCCROOT", - "MSVCDir", "MSVC", "MSVCNT", "MINGW", "watcom"): +for s in ( + "BOOST_ROOT", + "BOOST_BUILD_PATH", + "JAM_TOOLSET", + "BCCROOT", + "MSVCDir", + "MSVC", + "MSVCNT", + "MINGW", + "watcom", +): try: del os.environ[s] except: @@ -36,18 +48,32 @@ BoostBuild.set_defer_annotations(1) def iterfutures(futures): while futures: done, futures = concurrent.futures.wait( - futures,return_when=concurrent.futures.FIRST_COMPLETED) + futures, return_when=concurrent.futures.FIRST_COMPLETED + ) for future in done: yield future, futures def run_test(test): + def early_exit(): + # Signal timeout by SIGILL in interpreter thread. + signal.raise_signal(signal.SIGILL) + + def sig_handle(sig, frame): + # Translate the SIGILL to an exception to stop with an apropos error. + raise TimeoutError() + + # Timer for the 5 minute limit for each test. + timeout = threading.Timer(5 * 60, early_exit) + timeout.start() + signal.signal(signal.SIGILL, sig_handle) ts = time.perf_counter() exc = None try: __import__(test) except BaseException as e: exc = e + timeout.cancel() annotations = BoostBuild.annotations.copy() BoostBuild.annotations.clear() return test, time.perf_counter() - ts, exc, annotations @@ -74,7 +100,16 @@ def run_tests(critical_tests, other_tests): cancelled = False max_workers = 1 if "--not-parallel" in sys.argv else None - executor = concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) + exc_args = {} + exc_args["max_workers"] = max_workers + if ( + "max_tasks_per_child" + in inspect.signature(concurrent.futures.ProcessPoolExecutor).parameters.keys() + ): + # Limit to 1-to-1 processing to allow for timeout canceling at the + # process level. + exc_args["max_tasks_per_child"] = 1 + executor = concurrent.futures.ProcessPoolExecutor(**exc_args) def handler(sig, frame): cancelled = True @@ -96,10 +131,10 @@ def run_tests(critical_tests, other_tests): s = "%%-%ds :" % max_test_name_len % test if isatty: s = "\r{}".format(s) - print(s, end='') + print(s, end="") passed = 0 - ts = float('nan') + ts = float("nan") try: test, ts, exc, annotations = future.result() BoostBuild.annotations += annotations @@ -123,8 +158,10 @@ def run_tests(critical_tests, other_tests): except: exc_type, exc_value, exc_tb = sys.exc_info() try: - BoostBuild.annotation("failure - unhandled exception", "%s - " - "%s" % (exc_type.__name__, exc_value)) + BoostBuild.annotation( + "failure - unhandled exception", + "%s - " "%s" % (exc_type.__name__, exc_value), + ) BoostBuild.annotate_stack_trace(exc_tb) finally: # Explicitly clear a hard-to-garbage-collect traceback @@ -149,33 +186,47 @@ def run_tests(critical_tests, other_tests): if not xml: if passed: - print("PASSED {:>5.0f}ms".format(ts*1000)) + print("PASSED {:>5.0f}ms".format(ts * 1000)) else: - print("FAILED {:>5.0f}ms".format(ts*1000)) + print("FAILED {:>5.0f}ms".format(ts * 1000)) BoostBuild.flush_annotations() if isatty: - msg = ", ".join(futures[future] for future in pending if future.running()) + msg = ", ".join( + futures[future] for future in pending if future.running() + ) if msg: - msg = "[{}/{}] {}".format(len(futures) - len(pending),len(futures),msg) + msg = "[{}/{}] {}".format( + len(futures) - len(pending), len(futures), msg + ) max_len = max_test_name_len + len(" :PASSED 12345ms") if len(msg) > max_len: - msg = msg[:max_len - 3] + "..." - print(msg, end='') + msg = msg[: max_len - 3] + "..." + print(msg, end="") else: rs = "succeed" if not passed: rs = "fail" - print(''' + print( + """ -''' % (test, toolset, "tools/build/v2/test/" + test + ".py", - "boost/bin.v2/boost.build.tests/" + toolset + "/" + test, rs)) +""" + % ( + test, + toolset, + "tools/build/v2/test/" + test + ".py", + "boost/bin.v2/boost.build.tests/" + toolset + "/" + test, + rs, + ) + ) if not passed: BoostBuild.flush_annotations(1) - print(''' + print( + """ -''') +""" + ) sys.stdout.flush() # Makes testing under emacs more entertaining. BoostBuild.clear_annotations() @@ -184,17 +235,22 @@ def run_tests(critical_tests, other_tests): open("test_results.txt", "w").close() if not xml: - print(''' + print( + """ === Test summary === PASS: {} FAIL: {} TIME: {:.0f}s - '''.format(pass_count,failures_count,time.perf_counter() - start_ts)) + """.format( + pass_count, failures_count, time.perf_counter() - start_ts + ) + ) # exit with failure with failures if cancelled or failures_count > 0: sys.exit(1) + def last_failed_test(): "Returns the name of the last failed test or None." try: @@ -210,14 +266,23 @@ def last_failed_test(): def reorder_tests(tests, first_test): try: n = tests.index(first_test) - return [first_test] + tests[:n] + tests[n + 1:] + return [first_test] + tests[:n] + tests[n + 1 :] except ValueError: return tests -critical_tests = ["docs", "unit_tests", "module_actions", "core_d12", - "core_typecheck", "core_delete_module", "core_language", "core_arguments", - "core_varnames", "core_import_module"] +critical_tests = [ + "docs", + "unit_tests", + "module_actions", + "core_d12", + "core_typecheck", + "core_delete_module", + "core_language", + "core_arguments", + "core_varnames", + "core_import_module", +] # We want to collect debug information about the test site before running any # of the tests, but only when not running the tests interactively. Then the @@ -227,170 +292,173 @@ critical_tests = ["docs", "unit_tests", "module_actions", "core_d12", if xml: critical_tests.insert(0, "collect_debug_info") -tests = ["abs_workdir", - "absolute_sources", - "alias", - "alternatives", - "always", - "assert", - "bad_dirname", - "build_dir", - "build_file", - "build_hooks", - "build_no", - "builtin_echo", - "builtin_exit", - "builtin_glob", - "builtin_readlink", - "builtin_split_by_characters", - "bzip2", - "c_file", - "chain", - "clean", - "cli_property_expansion", - "command_line_properties", - "composite", - "conditionals", - "conditionals2", - "conditionals3", - "conditionals4", - "conditionals_multiple", - "configuration", - "configure", - "copy_time", - "core_action_output", - "core_action_status", - "core_actions_quietly", - "core_at_file", - "core_bindrule", - "core_dependencies", - "core_syntax_error_exit_status", - "core_fail_expected", - "core_jamshell", - "core_modifiers", - "core_multifile_actions", - "core_nt_cmd_line", - "core_option_d2", - "core_option_l", - "core_option_n", - "core_parallel_actions", - "core_parallel_multifile_actions_1", - "core_parallel_multifile_actions_2", - "core_scanner", - "core_source_line_tracking", - "core_update_now", - "core_variables_in_actions", - "custom_generator", - "debugger", -# Newly broken? -# "debugger-mi", - "default_build", - "default_features", - "default_toolset", - "dependency_property", - "dependency_test", - "disambiguation", - "dll_path", - "double_loading", - "duplicate", - "example_libraries", - "example_make", - "exit_status", - "expansion", - "explicit", - "feature_cxxflags", - "feature_implicit_dependency", - "feature_relevant", - "feature_suppress_import_lib", - "file_types", - "flags", - "generator_selection", - "generators_test", - "grep", - "implicit_dependency", - "indirect_conditional", - "inherit_toolset", - "inherited_dependency", - "inline", - "install_build_no", - "lang_asm", - "libjpeg", - "liblzma", - "libpng", - "libtiff", - "libzstd", - "lib_source_property", - "lib_zlib", - "library_chain", - "library_property", - "link", - "load_order", - "loop", - "make_rule", - "message", - "ndebug", - "no_type", - "notfile", - "ordered_include", -# FIXME: Disabled due to bug in B2 -# "ordered_properties", - "out_of_tree", - "package", - "param", - "path_features", - "path_specials", - "prebuilt", - "preprocessor", - "print", - "project_dependencies", - "project_glob", - "project_id", - "project_root_constants", - "project_root_rule", - "project_test3", - "project_test4", - "property_expansion", -# FIXME: Disabled due lack of qt5 detection -# "qt5", - "rebuilds", - "relative_sources", - "remove_requirement", - "rescan_header", - "resolution", - "rootless", - "scanner_causing_rebuilds", - "searched_lib", - "skipping", - "sort_rule", - "source_locations", - "source_order", - "stage", - "standalone", - "static_and_shared_library", - "suffix", - "tag", - "test_rc", - "test1", - "test2", - "testing", - "timedata", - "toolset_clang_darwin", - "toolset_clang_linux", - "toolset_clang_vxworks", - "toolset_darwin", - "toolset_defaults", - "toolset_gcc", - "toolset_intel_darwin", - "toolset_msvc", - "toolset_requirements", - "transitive_skip", - "unit_test", - "unused", - "use_requirements", - "using", - "wrapper", - "wrong_project", - ] +tests = [ + "abs_workdir", + "absolute_sources", + "alias", + "alternatives", + "always", + "assert", + "bad_dirname", + "build_dir", + "build_file", + "build_hooks", + "build_no", + "builtin_echo", + "builtin_exit", + "builtin_glob", + "builtin_readlink", + "builtin_split_by_characters", + "bzip2", + "c_file", + "chain", + "clean", + "cli_property_expansion", + "command_line_properties", + "composite", + "conditionals", + "conditionals2", + "conditionals3", + "conditionals4", + "conditionals_multiple", + "configuration", + "configure", + "copy_time", + "core_action_output", + "core_action_status", + "core_actions_quietly", + "core_at_file", + "core_bindrule", + "core_dependencies", + "core_syntax_error_exit_status", + "core_fail_expected", + "core_jamshell", + "core_modifiers", + "core_multifile_actions", + "core_nt_cmd_line", + "core_option_d2", + "core_option_l", + "core_option_n", + "core_parallel_actions", + "core_parallel_multifile_actions_1", + "core_parallel_multifile_actions_2", + "core_scanner", + "core_source_line_tracking", + "core_update_now", + "core_variables_in_actions", + "custom_generator", + "debugger", + # Newly broken? + # "debugger-mi", + "default_build", + "default_features", + "default_toolset", + "dependency_property", + "dependency_test", + "disambiguation", + "dll_path", + "double_loading", + "duplicate", + "escaping_dollar_before_round_bracket", + "example_libraries", + "example_make", + "exit_status", + "expansion", + "explicit", + "feature_cxxflags", + "feature_implicit_dependency", + "feature_relevant", + "feature_suppress_import_lib", + "file_types", + "flags", + "generator_selection", + "generators_test", + "grep", + "implicit_dependency", + "indirect_conditional", + "inherit_toolset", + "inherited_dependency", + "inline", + "install_build_no", + "lang_asm", + "libjpeg", + "liblzma", + "libpng", + "libtiff", + "libzstd", + "lib_source_property", + "lib_zlib", + "library_chain", + "library_property", + "link", + "load_order", + "loop", + "make_rule", + "message", + "ndebug", + "no_type", + "notfile", + "ordered_include", + # FIXME: Disabled due to bug in B2 + # "ordered_properties", + "out_of_tree", + "package", + "param", + "path_features", + "path_specials", + "prebuilt", + "preprocessor", + "print", + "project_dependencies", + "project_glob", + "project_id", + "project_sub_resolution", + "project_root_constants", + "project_root_rule", + "project_test3", + "project_test4", + "property_expansion", + # FIXME: Disabled due lack of qt5 detection + # "qt5", + "rebuilds", + "relative_sources", + "remove_requirement", + "rescan_header", + "resolution", + "rootless", + "scanner_causing_rebuilds", + "searched_lib", + "skipping", + "sort_rule", + "source_locations", + "source_order", + "stage", + "standalone", + "static_and_shared_library", + "suffix", + "tag", + "test_rc", + "test1", + "test2", + "testing", + "timedata", + "toolset_clang_darwin", + "toolset_clang_linux", + "toolset_clang_vxworks", + "toolset_darwin", + "toolset_defaults", + "toolset_gcc", + "toolset_intel_darwin", + "toolset_msvc", + "toolset_requirements", + "transitive_skip", + "unit_test", + "unused", + "use_requirements", + "using", + "wrapper", + "wrong_project", +] if os.name == "posix": tests.append("symlink") @@ -408,7 +476,11 @@ if toolset.startswith("gcc") and os.name != "nt": # assumes otherwise. Hence enable it only when not on Windows. tests.append("gcc_runtime") -if toolset.startswith("clang") or toolset.startswith("gcc") or toolset.startswith("msvc"): +if ( + toolset.startswith("clang") + or toolset.startswith("gcc") + or toolset.startswith("msvc") +): if not sys.platform.startswith("freebsd"): tests.append("pch") tests.append("feature_force_include") @@ -418,7 +490,7 @@ if toolset.startswith("clang") and "-win" not in toolset or "darwin" in toolset: tests.append("lang_objc") # Disable on OSX as it doesn't seem to work for unknown reasons. -if sys.platform != 'darwin': +if sys.platform != "darwin": tests.append("builtin_glob_archive") if "--extras" in sys.argv: