1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-08 23:36:34 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
CRTLinkage: dynamic
LibraryLinkage: dynamic
PolicyEmptyPackage: enabled

View File

@@ -0,0 +1,8 @@
Package: boost-build
Version: 1.79.0
Depends: boost-uninstall
Architecture: x64-windows
Multi-Arch: same
Abi: ae2e04240d11929b681e289a0f6dd881454523061c007bfce13fdb89700330de
Description: Boost.Build
Type: Port

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,174 @@
{
"$schema": "https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json",
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"documentNamespace": "https://spdx.org/spdxdocs/boost-build-x64-windows-1.79.0-0bec2e08-f730-4141-8167-5af5bcc4803d",
"name": "boost-build:x64-windows@1.79.0 ae2e04240d11929b681e289a0f6dd881454523061c007bfce13fdb89700330de",
"creationInfo": {
"creators": [
"Tool: vcpkg-9268e366206712e38102b28dbd1617697a99ff2e"
],
"created": "2022-07-23T08:22:39Z"
},
"relationships": [
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "GENERATES",
"relatedSpdxElement": "SPDXRef-binary"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-0"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-1"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-2"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-3"
},
{
"spdxElementId": "SPDXRef-binary",
"relationshipType": "GENERATED_FROM",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-0",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-2",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-3",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-3",
"relationshipType": "DEPENDENCY_MANIFEST_OF",
"relatedSpdxElement": "SPDXRef-port"
}
],
"packages": [
{
"name": "boost-build",
"SPDXID": "SPDXRef-port",
"versionInfo": "1.79.0",
"downloadLocation": "NOASSERTION",
"homepage": "https://github.com/boostorg/build",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"description": "Boost.Build",
"comment": "This is the port (recipe) consumed by vcpkg."
},
{
"name": "boost-build:x64-windows",
"SPDXID": "SPDXRef-binary",
"versionInfo": "ae2e04240d11929b681e289a0f6dd881454523061c007bfce13fdb89700330de",
"downloadLocation": "NONE",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"comment": "This is a binary package built by vcpkg."
},
{
"SPDXID": "SPDXRef-resource-1",
"name": "boostorg/build",
"downloadLocation": "git+https://github.com/boostorg/build@boost-${BOOST_VERSION}",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA512",
"checksumValue": "638f2883b9c49265d5566eadc8c93d16cb351edeb941110bad8a17871ea7d53df8eb13c80aaefb94f354b71a22454958af1ecb9a441686dbaa9631e33682a9f2"
}
]
},
{
"SPDXID": "SPDXRef-resource-2",
"name": "boost_LICENSE_1_0.txt",
"packageFileName": "boost_LICENSE_1_0.txt",
"downloadLocation": "https://raw.githubusercontent.com/boostorg/boost/boost-${BOOST_VERSION}/LICENSE_1_0.txt",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA512",
"checksumValue": "d6078467835dba8932314c1c1e945569a64b065474d7aced27c9a7acc391d52e9f234138ed9f1aa9cd576f25f12f557e0b733c14891d42c16ecdc4a7bd4d60b8"
}
]
}
],
"files": [
{
"fileName": "./0001-don-t-skip-install-targets.patch",
"SPDXID": "SPDXRef-file-0",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "d69a07ef3fcd52f6381e6cfcb54933eee8706537b9d71acd03bc330646cbcc3b"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"fileName": "./0002-fix-get-version.patch",
"SPDXID": "SPDXRef-file-1",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "108dd64121413cd2d56ede83507d31532c1688cf10d49a3f10fba16b88956e56"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"fileName": "./portfile.cmake",
"SPDXID": "SPDXRef-file-2",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "86262459f5154dcdfc81317d9d5ac15a11e214aed11e0cdc3c7ad190b70a64e4"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"fileName": "./vcpkg.json",
"SPDXID": "SPDXRef-file-3",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "666468a88acb531a9dfd2f06a6703ecf2be5d7fea3614559bc8e6f41a0e1007a"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
}
]
}

View File

@@ -0,0 +1,16 @@
0001-don-t-skip-install-targets.patch d69a07ef3fcd52f6381e6cfcb54933eee8706537b9d71acd03bc330646cbcc3b
0002-fix-get-version.patch 108dd64121413cd2d56ede83507d31532c1688cf10d49a3f10fba16b88956e56
boost-uninstall 23fa13839dbf6e1bb98b1e52a4439f3f2e336098c5070f520396b8d962807e66
cmake 3.23.2
features core
portfile.cmake 86262459f5154dcdfc81317d9d5ac15a11e214aed11e0cdc3c7ad190b70a64e4
ports.cmake 366c60b768113102408b32ac1d7c7b48ef7d30a477af2a220ecc222d9ffa3166
post_build_checks 2
powershell 7.2.5
triplet x64-windows
triplet_abi 4556164a2cd3dd6f4742101eabb46def7e71b6e5856faa88e5d005aac12a803c-c0600b35e024ce0485ed253ef5419f3686f7257cfb58cb6a24febcb600fc4b4c-27ebd443f77a6c449168adfa6ce8def60cf46e88
vcpkg.json 666468a88acb531a9dfd2f06a6703ecf2be5d7fea3614559bc8e6f41a0e1007a
vcpkg_download_distfile 02c14236080ff726edf494f67e52cef6682a6cdb911c2b741b1a2e8ef4829eaf
vcpkg_execute_required_process 7eefd86717c97c8019995bc96d126837bd4c67ab91cd3ec8135e628fc51bfc97
vcpkg_from_git 0aab20e34e84d52ba4763f009e539bfa8f418c41c918c8cf700156f1a8551a10
vcpkg_from_github b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f

View File

@@ -0,0 +1,22 @@
steps:
- bash: |
set -e
uname -a
./.ci/linux-cxx-install.sh
displayName: Install
- bash: |
set -e
cd src/engine
set PATH=${PATH};${CXX_PATH}
./build.sh ${TOOLSET}
./b2 -v
cd ../..
./src/engine/b2 -a address-sanitizer=on toolset=${TOOLSET} b2
displayName: Build
- bash: |
set -e
export B2=`ls -1 ${PWD}/.build/*/debug/address-sanitizer-on/cxxstd-11-iso/b2`
cd test
python test_all.py ${TOOLSET}
cd ..
displayName: Test

View File

@@ -0,0 +1,35 @@
steps:
- bash: |
set -e
uname -a
./.ci/linux-cxx-install.sh
displayName: Install
- bash: |
set -e
cd src/engine
set PATH=${PATH};${CXX_PATH}
./build.sh ${TOOLSET}
./b2 -v
cd ../..
displayName: Build
- bash: |
set -e
cd test
python test_all.py ${TOOLSET}
cd ..
displayName: Test
- bash: |
set -e
./src/engine/b2 b2 warnings-as-errors=on variant=debug,release address-model=32,64 toolset=${TOOLSET}
displayName: "No Warnings"
- bash: |
set -e
./bootstrap.sh ${TOOLSET}
./b2 --prefix=$HOME/temp/.b2 install toolset=${TOOLSET}
rm ./b2
export PATH=$HOME/temp/.b2/bin:$PATH
cd $HOME
touch build.jam
b2 -v
b2 -n --debug-configuration toolset=${TOOLSET}
displayName: Bootstrap

View File

@@ -0,0 +1,41 @@
steps:
- bash: |
set -e
uname -a
sudo xcode-select -switch ${XCODE_APP}
which clang++
displayName: Install
- bash: |
set -e
cd src/engine
./build.sh ${TOOLSET} --cxx=${CXX}
./b2 -v
cd ../..
displayName: Build
- bash: |
set -e
CXX_PATH=`which ${CXX}`
cd test
echo "using ${TEST_TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam
python test_all.py ${TEST_TOOLSET}
cd ..
displayName: Test
- bash: |
set -e
CXX_PATH=`which ${CXX}`
echo "using ${TEST_TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam
./src/engine/b2 b2 warnings-as-errors=on variant=debug,release address-model=32,64 toolset=${TEST_TOOLSET}
displayName: "No Warnings"
- bash: |
set -e
CXX_PATH=`which ${CXX}`
echo "using ${TEST_TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam
./bootstrap.sh ${TOOLSET}
./b2 --prefix=$HOME/temp/.b2 install ${TEST_TOOLSET}
rm ./b2
export PATH=$HOME/temp/.b2/bin:$PATH
cd $HOME
touch build.jam
b2 -v
b2 -n --debug-configuration
displayName: Bootstrap

View File

@@ -0,0 +1,34 @@
steps:
- powershell: |
cd src/engine
$env:path += ';' + $env:CXX_PATH
cmd /c build.bat $env:TOOLSET
./b2.exe -v
cd ../..
displayName: Build
- powershell: |
$env:HOME = $env:HOMEDRIVE + $env:HOMEPATH
cd test
echo "using" $env:TEST_TOOLSET ":" ":" $env:CXX ";" > ${env:HOME}/user-config.jam
python test_all.py $env:TEST_TOOLSET
cd ..
displayName: Test
- powershell: |
$env:HOME = $env:HOMEDRIVE + $env:HOMEPATH
$env:path += ';' + $env:CXX_PATH
echo "using" $env:TEST_TOOLSET ":" ":" $env:CXX ";" > ${env:HOME}/user-config.jam
./src/engine/b2.exe --debug-configuration b2 warnings-as-errors=on variant=debug,release toolset=$env:TEST_TOOLSET
displayName: "No Warnings"
- powershell: |
$env:HOME = $env:HOMEDRIVE + $env:HOMEPATH
$env:path += ';' + $env:CXX_PATH
echo "using" $env:TEST_TOOLSET ":" ":" $env:CXX ";" > ${env:HOME}/user-config.jam
./bootstrap.bat $env:TOOLSET
./b2.exe --debug-configuration --prefix=${env:HOME}/temp/.b2 install toolset=$env:TEST_TOOLSET
Remove-Item ./b2.exe
$env:path += $env:HOME + '/temp/.b2/bin' + ';' + $env:PATH
cd $env:HOME
echo $null >> build.jam
b2 -v
b2 -n --debug-configuration
displayName: Bootstrap

View File

@@ -0,0 +1,45 @@
#!/bin/sh
# Usage:
# LLVM_OS: LLVM OS release to obtain clang binaries. Only needed for clang install.
# LLVM_VER: The LLVM toolset version to point the repo at.
# PACKAGES: Compiler packages to install.
if command -v sudo ; then
SUDO="sudo -E"
fi
OS_ISSUE=`cat /etc/issue | head -n1 | cut -d " " -f1`
echo ">>>>> OS Issue: ${OS_ISSUE}"
PACKAGES=${PACKAGES:-build-essential}
set -e
echo ">>>>>"
echo ">>>>> APT: UPDATE.."
echo ">>>>>"
${SUDO} apt-get -o Acquire::Retries=3 update
echo ">>>>>"
echo ">>>>> APT: REPO.."
echo ">>>>>"
${SUDO} apt-get -o Acquire::Retries=3 -y install software-properties-common
if test "${OS_ISSUE}" = "Ubuntu" ; then
${SUDO} apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
fi
if test -n "${LLVM_OS}" ; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
${SUDO} apt-add-repository "deb http://apt.llvm.org/${LLVM_OS}/ llvm-toolchain-${LLVM_OS}-${LLVM_VER} main"
fi
echo ">>>>>"
echo ">>>>> APT: UPDATE.."
echo ">>>>>"
${SUDO} apt-get -o Acquire::Retries=3 update
echo ">>>>>"
echo ">>>>> APT: INSTALL ${PACKAGES}.."
echo ">>>>>"
${SUDO} apt-get -o Acquire::Retries=3 -yq --no-install-suggests --no-install-recommends install ${PACKAGES}
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE.txt)
#
# Copyright Rene Rivera 2020.

View File

@@ -0,0 +1,45 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE.txt)
#
# Copyright René Ferdinand Rivera Morell 2020-2021.
freebsd_task:
# All the GCC's and Clang's currently supported by FreeBSD ports.
matrix:
- { name: 'FreeBSD, GCC 11', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++11', PACKAGE: 'gcc11-devel' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, GCC 10', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++10', PACKAGE: 'gcc10-devel' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, GCC 9', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++9', PACKAGE: 'gcc9-devel' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, GCC 8', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++8', PACKAGE: 'gcc8' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
# - { name: 'FreeBSD, GCC 7', env: { TOOLSET: gcc, TEST_TOOLSET: gcc, CXX: 'g++7', PACKAGE: 'gcc7' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, Clang 12', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++12', PACKAGE: 'devel/llvm12' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, Clang 11', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++11', PACKAGE: 'devel/llvm11' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, Clang 10', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++10', PACKAGE: 'devel/llvm10' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, Clang 9', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++90', PACKAGE: 'devel/llvm90' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, Clang 8', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++80', PACKAGE: 'devel/llvm80' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
- { name: 'FreeBSD, Clang 7', env: { TOOLSET: clang, TEST_TOOLSET: clang, CXX: 'clang++70', PACKAGE: 'devel/llvm70' }, freebsd_instance: { image_family: 'freebsd-13-0' } }
# To install with ports we need to initialize the package manager. To avoid
# confirmation prompts we need to set an env var.
install_script: [
"uname -a",
"env ASSUME_ALWAYS_YES=YES pkg bootstrap",
"env ASSUME_ALWAYS_YES=YES pkg install ${PACKAGE}",
"env ASSUME_ALWAYS_YES=YES pkg install python3"
]
# Build the engine.
build_script: [
"set -e",
"cd src/engine",
"./build.sh --cxx=${CXX} ${TOOLSET}",
"./b2 -v",
"cd ../.."
]
# Run the core tests.
test_script: [
"set -e",
"CXX_PATH=`which ${CXX}`",
"cd test",
"echo \"using ${TEST_TOOLSET} : : ${CXX_PATH} ;\" > ${HOME}/user-config.jam",
"python3 test_all.py ${TEST_TOOLSET}",
"cd ..",
]

View File

@@ -0,0 +1,15 @@
# Copyright 2018 Rene Rivera
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or http://www.boost.org/LICENSE_1_0.txt)
root = true
[*]
charset = utf-8
indent_size = 4
indent_style = space
tab_width = 4
trim_trailing_whitespace = true
[*.yml]
indent_size = 2

View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text eol=crlf svneol=crlf#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text eol=crlf svneol=crlf#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

View File

@@ -0,0 +1,11 @@
---
name: Feature Request
about: Create an issue that requests a feature or other improvement
title: ''
labels: enhancement
assignees: ''
---
Thank you for your contributions. Main development of B2 has moved to
https://github.com/bfgroup/b2

View File

@@ -0,0 +1,11 @@
---
name: Problem Report
about: Report a bug, something does not work as it supposed to
title: ''
labels: bug
assignees: ''
---
Thank you for your contributions. Main development of B2 has moved to
https://github.com/bfgroup/b2

View File

@@ -0,0 +1,2 @@
Thank you for your contributions. Main development of B2 has moved to
https://github.com/bfgroup/b2

View File

@@ -0,0 +1,32 @@
name: 'Repo Lockdown'
on:
issues:
types: opened
pull_request_target:
types: opened
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/repo-lockdown@v2
with:
log-output: true
skip-closed-issue-comment: true
issue-labels: 'transition'
issue-comment: >
Thank you for your contributions. Main development of B2 has moved to
https://github.com/bfgroup/b2
Please consider following up at https://github.com/bfgroup/b2/issues
skip-closed-pr-comment: true
pr-labels: 'transition'
pr-comment: >
Thank you for your contributions. Main development of B2 has moved to
https://github.com/bfgroup/b2
Please consider following up at https://github.com/bfgroup/b2/pulls

View File

@@ -0,0 +1,80 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE.txt)
#
# Copyright René Ferdinand Rivera Morell 2020-2021.
on:
push:
branches: [ 'main', 'release' ]
paths-ignore: [
'.circleci/**',
'.cirrus.yml',
'.drone.star',
'.semaphore/**',
'.travis.yml',
'appveyor.yml',
'azure-pipelines.yml' ]
jobs:
qemu-multiarch-linux:
strategy:
fail-fast: false
matrix:
include:
- { name: 'Ubuntu 20.04 Focal (armhf)', image: 'multiarch/ubuntu-debootstrap:armhf-focal', cxx: 'g++', toolset: 'gcc' }
- { name: 'Ubuntu 20.04 Focal (arm64)', image: 'multiarch/ubuntu-debootstrap:arm64-focal', cxx: 'g++', toolset: 'gcc' }
- { name: 'Ubuntu 20.04 Focal (ppc64el)', image: 'multiarch/ubuntu-debootstrap:ppc64el-focal', cxx: 'g++', toolset: 'gcc' }
- { name: 'Debian 11 Bullseye (armhf)', image: 'multiarch/debian-debootstrap:armhf-bullseye', cxx: 'g++', toolset: 'gcc' }
name: ${{ matrix.name }}
runs-on: ubuntu-latest
env:
CXX: ${{ matrix.cxx }}
CXXFLAGS: ${{ matrix.cxxflags }}
PACKAGES: ${{ matrix.packages }}
LLVM_OS: ${{ matrix.llvm_os }}
LLVM_VER: ${{ matrix.llvm_ver }}
TOOLSET: ${{ matrix.toolset }}
steps:
- name: 'Checkout'
uses: actions/checkout@master
- name: 'Install'
run: |
sudo apt-get -o Acquire::Retries=3 update
sudo apt-get -o Acquire::Retries=3 -y install qemu-user-static
docker pull "${{ matrix.image }}"
- name: 'Setup'
run: |
env | grep -v '^#' | xargs > docker-run-action.env
- name: 'Info'
run: |
echo ">>>>> ENV:"
cat docker-run-action.env
echo ">>>>> WORKDIR: ${{ github.workspace }}"
ls -laF ${{ github.workspace }}
- name: 'Run'
uses: addnab/docker-run-action@v3
with:
image: ${{ matrix.image }}
options: -v ${{ github.workspace }}:${{ github.workspace }} -w ${{ github.workspace }} --env-file docker-run-action.env
run: |
set -e
uname -a
echo ">>>>>"
echo ">>>>> Install.."
echo ">>>>>"
./.ci/linux-cxx-install.sh
echo ">>>>>"
echo ">>>>> Build.."
echo ">>>>>"
cd src/engine
export "PATH=${PATH};${CXX_PATH}"
./build.sh ${TOOLSET}
./b2 -v
cd ../..
echo ">>>>>"
echo ">>>>> Test.."
echo ">>>>>"
cd test
python3 test_all.py ${TOOLSET}
cd ..

View File

@@ -0,0 +1,23 @@
*.code-workspace
*.py[co]
/.vscode
/doc/bin
/doc/html
/b2
/bjam
/b2.exe
/bjam.exe
/.build
/bootstrap.log
/test/test_results.txt
/project-config.jam
/src/engine/b2
/src/engine/b2.exe
infer-out
build.log
/example/named-install-dirs/bar
/example/named-install-dirs/foo
/example/named-install-dirs/q
/example/gettext/messages
/example/**/bin
/test/file.jam

View File

@@ -0,0 +1,174 @@
// Copyright 2019-2020 Rene Rivera
// Copyright 2003, 2006 Vladimir Prus
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
= B2 contributor guidelines
B2 is an open-source project. This means that we welcome and appreciate
all contributions -- be it ideas, bug reports, or patches. This document
contains guidelines which helps to assure that development goes on smoothly, and
changes are made quickly.
The guidelines are not mandatory, and you can decide for yourself which one to
follow. But note, the 10 mins that you spare writing a comment, for example,
might lead to significantly longer delay for everyone.
== Additional resources include
=== The issue tracker
https://github.com/bfgroup/b2/issues
=== Discussion forums
https://github.com/bfgroup/b2/discussions
== BUGS and PATCHES
Both bugs and patches can be submitted to the GitHub tracker.
When reporting a bug, please try to provide the following information:
* What you did.
* A minimal reproducible test case is very much appreciated.
* Shell script with some annotations is much better than verbose
description of the problem.
* A regression test is the best (see test/test_system.html).
* What you got.
* What you expected.
* What version of B2 did you use. If possible, please try to test with the
main branch state.
When submitting a patch, please:
* Make a single patch for a single logical change
* Follow the policies and coding conventions below
* Send patches as pull requests to the main branch
* Provide a good PR message together with the patch
The purpose of message serves to communicate what was changed, and *why*.
Without a good message, you might spend a lot of time later, wondering where
a strange piece of code came from and why it was necessary.
The good message mentions each changed file and each rule/method, saying
what happened to it, and why. Consider, the following log message
----
Better direct request handling.
* new/build-request.jam
(directly-requested-properties-adjuster): Redo.
* new/targets.jam
(main-target.generate-really): Adjust properties here.
* new/virtual-target.jam
(register-actual-name): New rule.
(virtual-target.actualize-no-scanner): Call the above, to detected bugs,
where two virtual target correspond to one Jam target name.
----
The messages for the last two files are good. They tell what was changed.
The change to the first file is clearly under-commented.
It's okay to use terse messages for uninteresting changes, like ones induced
by interface changes elsewhere.
== POLICIES
=== Testing
All serious changes must be tested. New rules must be tested by the module where
they are declared. The test system (link:test/test_system.html[test/test_system.html])
should be used to verify user-observable behavior.
=== Documentation
It turns out that it's hard to have too much comments, but it's easy to have too
little. Please prepend each rule with a comment saying what the rule does and
what arguments mean. Stop for a minute and consider if the comment makes sense
for anybody else, and completely describes what the rules does. Generic phrases
like "adjusts properties" are really not enough.
When applicable, make changes to the user documentation as well.
== CODING CONVENTIONS
1. All names of rules and variables are lowercase with "-" to separate
words.
+
----
rule call-me-ishmael ( ) ...
----
2. Names with dots in them are "intended globals". Ordinary globals use a
dot prefix:
+
----
.foobar
$(.foobar)
----
3. Pseudofunctions or associations are <parameter>.<property>:
+
----
$(argument).name = hello ;
$($(argument).name)
----
4. Class attribute names are prefixed with "self.":
+
----
self.x
$(self.x)
----
5. Builtin rules are called via their ALL_UPPERCASE_NAMES:
+
----
DEPENDS $(target) : $(sources) ;
----
6. Opening and closing braces go on separate lines:
+
----
if $(a)
{
#
}
else
{
#
}
----
== ENGINE
Developing in the `b2` engine, the C++ part, requires two steps to be
effective: building the "stable" engine, and developing the
"in-progress" engine.
What is the "stable" engine is up to you. It only refers to a build of the
engine you know is at a good working state. When you are at a point the
source is stable you can run `bootstrap.sh/bat` from the root. That will
create the `b2` executable at the root. You can then use this version to run
regular B2 builds as needed both within the B2 tree and in other projects.
The "in-progress" engine is whatever build you happen to be testing at the
moment. There are two ways to build this be engine. You can either
(a) run `b2 b2` at the root, or (b) run `build.sh/bat` in `src/engine`.
Using (a) will place, by default, a fully debuggable `b2` in the `.build`
directories. You can run that one from a debugger with full symbols and
stepping features. This should be the first choice in developing in the
engine.
After using (a) to implement functionality you can use (b) to fully test
that functionality. The engine built from (b) is fully optimized and
is the one used, by default, by the test system when running in the `test`
directory. Before submitting patches it's required to build this way and
run the tests in at least one toolset version (but preferably at least two).

View File

@@ -0,0 +1,267 @@
# Copyright 2019 Rene Rivera
# Copyright 2017 Steven Watanabe
# Copyright 2016 Vladimir Prus
# Copyright 2017 Edward Diener
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
import "class" : new ;
import bison ;
import errors ;
import feature ;
import indirect ;
import os ;
# import package ;
import path ;
import set ;
import stage : add-install-dir ;
import toolset ;
import type ;
import virtual-target ;
path-constant SELF : . ;
project b2
: build-dir .build
: requirements
<cxxstd>11
<toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS=1
<toolset>msvc:<define>_CRT_NONSTDC_NO_DEPRECATE=1
;
#|
Build the engine and its dependencies outside of the simple core build scripts.
This allows us to keep the core build scripts as simple as possible. And lets
us support more functionality for development of the engine core.
|#
#|
Define custom yyacc tool.
|#
feature.feature yyacc : : dependency free ;
toolset.flags yyacc TOOL <yyacc> ;
exe yyacc
: src/engine/yyacc.cpp
: ;
explicit yyacc ;
rule yyacc-gen ( project name : property-set : sources * )
{
local relevant = [ toolset.relevant $(__name__).yyacc ] ;
local a = [ new action $(sources[1]) : $(__name__).yyacc : [ $(property-set).add $(relevant) ] ] ;
local targets ;
for local n in $(name:S=).y $(name:S=)tab.h
{
targets += [ virtual-target.register
[ new file-target $(n) exact : [ type.type $(n) ]
: $(project) : $(a)
] ] ;
}
return $(targets) ;
}
actions yyacc bind TOOL
{
"$(TOOL)" "$(<)" "$(>)"
}
generate jamgram.y
: src/engine/jamgram.yy
: <generating-rule>@yyacc-gen
<location>src/engine
<yyacc>yyacc <dependency>yyacc
;
explicit jamgram.y ;
#|
Define grammar translation with Bison.
|#
BISON = [ os.environ BISON ] ;
BISON ?= bison ;
local BISON_IN_PATH = [ path.glob [ os.executable-path ] : $(BISON[1]) $(BISON[1]).* ] ;
rule grammar ( target : source : properties * )
{
# LOCATE on $(target) = $(source:D) ;
BISON on $(target) = $(BISON) ;
}
actions grammar
{
"$(BISON)" --yacc --defines -o "$(<[1])" "$(>)"
}
if $(BISON_IN_PATH)
{
make jamgram.cpp
: src/engine/jamgram.y
: @grammar
: <dependency>jamgram.y
<location>src/engine ;
}
else
{
errors.warning "Bison generator program '$(BISON:J= )' not found. Skipping grammar build." ;
alias jamgram.cpp
: src/engine/jamgram.cpp ;
}
explicit jamgram.cpp ;
#|
Define the b2 executable. Sources are based on platform.
TODO: Make platform specific source be no-ops when not needed.
|#
local python-exe = [ MATCH --with-python=(.*) : [ modules.peek : ARGV ] ] ;
local python-include ;
local python-ldlib ;
if $(python-exe)
{
python-include = [ SHELL
"$(python-exe) -c \"import sysconfig; print(sysconfig.get_path('include'));\""
: strip-eol ] ;
python-libdir = [ SHELL
"$(python-exe) -c \"import sysconfig; import os.path; print(sysconfig.get_config_var('LIBDIR'));\""
: strip-eol ] ;
python-ldlib = [ MATCH ".*(python.*)" : [ SHELL
"$(python-exe) -c \"import sysconfig; import os.path; print(sysconfig.get_config_var('LIBRARY'));\""
: strip-eol ] ] ;
python-ldlib = $(python-ldlib:S=) ;
lib python
:
: <name>$(python-ldlib) <search>$(python-libdir)
:
: <include>$(python-include) <define>HAVE_PYTHON ;
}
else
{
alias python ;
}
obj jamgram.obj
: jamgram.cpp
: <toolset>gcc:<cxxflags>-Wno-free-nonheap-object
;
explicit jamgram.obj ;
local b2_src =
[ glob src/engine/*.cpp src/engine/modules/*.cpp :
src/engine/*nt.cpp src/engine/*unix.cpp src/engine/*vms.cpp
src/engine/yyacc.cpp src/engine/mkjambase.cpp
src/engine/check_*.cpp
src/engine/jamgram.cpp
] ;
local b2_src_nt = [ glob src/engine/*nt.cpp ] ;
local b2_src_unix = [ glob src/engine/*unix.cpp ] ;
local b2_src_vms = [ glob src/engine/*vms.cpp ] ;
local unix_os = [ set.difference [ feature.values <target-os> ] : windows vms ] ;
exe b2
: $(b2_src)
jamgram.obj
python
: <target-os>windows:<source>$(b2_src_nt)
<target-os>vms:<source>$(b2_src_vms)
<target-os>$(unix_os):<source>$(b2_src_unix)
<toolset>msvc:<find-static-library>kernel32
<toolset>msvc:<find-static-library>advapi32
<toolset>msvc:<find-static-library>user32
;
explicit b2 ;
#|
Installation of the engine, build, and example files.
|#
feature.feature b2-install-layout : standard portable : incidental propagated ;
add-install-dir b2prefix-standard : : prefix ;
add-install-dir b2bindir-standard : : bindir ;
add-install-dir b2coredir-standard : boost-build/src : datarootdir ;
add-install-dir b2examplesdir-standard : boost-build/examples : datarootdir ;
add-install-dir b2prefix-portable : : prefix ;
add-install-dir b2bindir-portable : : b2prefix-portable ;
add-install-dir b2coredir-portable : .b2 : b2prefix-portable ;
add-install-dir b2examplesdir-portable : .b2/examples : b2prefix-portable ;
local ext = "" ;
if [ os.on-windows ] || [ os.on-vms ]
{
ext = ".exe" ;
}
install b2-engine
: $(SELF)/src/engine/b2$(ext)
: <b2-install-layout>standard:<location>(b2bindir-standard)
<b2-install-layout>portable:<location>(b2bindir-portable)
;
explicit b2-engine ;
local examples ;
for local e in [ glob-tree-ex $(SELF)/example : * : . .svn ]
{
if [ CHECK_IF_FILE [ path.native $(e) ] ]
{
examples += $(e) ;
}
}
install b2-examples
: # What to install
$(examples)
: # What is the root of the directory
<install-source-root>example
# Which subdir of $prefix/share
<b2-install-layout>standard:<location>(b2examplesdir-standard)
<b2-install-layout>portable:<location>(b2examplesdir-portable)
;
explicit b2-examples ;
local .core-sources =
$(SELF)/src/build-system.jam
[ path.glob-tree $(SELF)/src/build : *.jam ]
[ path.glob-tree $(SELF)/src/contrib : *.jam ]
[ path.glob-tree $(SELF)/src/kernel : *.jam ]
[ path.glob-tree $(SELF)/src/options : *.jam ]
[ path.glob-tree $(SELF)/src/util : *.jam ]
[ path.glob-tree $(SELF)/src/tools : *.jam *.xml *.xsl *.doxyfile *.hpp doxproc.py ]
;
if $(python-exe)
{
.core-sources +=
[ path.glob-tree $(SELF)/src/build : *.py ]
[ path.glob-tree $(SELF)/src/contrib : *.py ]
[ path.glob-tree $(SELF)/src/kernel : *.py ]
[ path.glob-tree $(SELF)/src/options : *.py ]
[ path.glob-tree $(SELF)/src/util : *.py ]
[ path.glob-tree $(SELF)/src/tools : *.py : doxproc.py ]
;
}
install b2-core
: # What to install
$(.core-sources)
: # What is the root of the directory
<install-source-root>src
# Which subdir of $prefix/share
<b2-install-layout>standard:<location>(b2coredir-standard)
<b2-install-layout>portable:<location>(b2coredir-portable)
;
explicit b2-core ;
#|
Only install example files when requested to avoid bloating install footprint.
|#
if --with-examples in [ modules.peek : ARGV ]
{
alias install : b2-engine b2-core b2-examples ;
}
else
{
alias install : b2-engine b2-core ;
}
explicit install ;

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,40 @@
= B2
B2 makes it easy to build C++ projects, everywhere.
image:https://img.shields.io/badge/license-BSL%201.0-blue.svg["Boost Software License 1.0", link="LICENSE.txt"]
image:https://img.shields.io/github/languages/code-size/bfgroup/b2.svg["GitHub code size in bytes", link="https://github.com/bfgroup/b2"]
== License
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE.txt or copy at https://www.bfgroup.xyz/b2/LICENSE.txt)
== Testing
Continuously tested on:
* FreeBSD Clang 7, 8, 9, 10, 11, 12
* FreeBSD GCC 8, 9, 10, 11
* Linux Clang 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
* Linux GCC 5, 6, 7, 8, 9, 10, 11
* macOS Xcode 10.0, 10.1, 10.2, 10.2.1, 11.2.1, 11.3, 11.3.1, 11.4.1, 11.5, 11.6, 11.7, 12.0.1, 12.1.1, 12.2, 12.3, 12.4, 12.5.1, 13.0
* Windows MinGW 8.1.0
* Windows VS 2013, 2015, 2017, 2019, 2022
* Cygwin 3.1.7 x64
image:https://img.shields.io/azure-devops/build/bfgroup/3a4e7a7e-c1b4-4e2f-9199-f52918ea06c6/3/release.svg?label=release&logo=azuredevops["Linux/Windows/macOS: release", link="https://dev.azure.com/bfgroup/B2"]
image:https://img.shields.io/azure-devops/build/bfgroup/3a4e7a7e-c1b4-4e2f-9199-f52918ea06c6/3/main.svg?label=main&logo=azuredevops["Linux/Windows/macOS: main", link="https://dev.azure.com/bfgroup/B2"]
image:https://img.shields.io/appveyor/build/bfgroup/b2?logo=appveyor["Windows", link="https://ci.appveyor.com/project/bfgroup/b2"]
image:https://api.cirrus-ci.com/github/bfgroup/b2.svg?branch=release["FreeBSD: release", link="https://cirrus-ci.com/github/bfgroup/b2/release"]
image:https://api.cirrus-ci.com/github/bfgroup/b2.svg?branch=main["FreeBSD: main", link="https://cirrus-ci.com/github/bfgroup/b2/main"]
NOTE: A C+\+11 capable compiler is needed to build the `b2` engine. But using
the `b2` engine and build system does not require C++11.
== More
See the link:https://www.bfgroup.xyz/b2/[website] for more information.
See the link:CONTRIBUTING.adoc[guidelines for contributing] if you would like
to get involved in the development.

View File

@@ -0,0 +1,71 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Copyright Rene Ferdinand Rivera Morell 2015-2020.
branches:
only:
- /main/
- /release/
- /feature\/.*/
environment:
matrix:
- job_name: 'Visual Studio 2015, Test'
job_group: 'Test'
TOOLSET: vc14
TEST_TOOLSET: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- job_name: 'Visual Studio 2013, Test'
job_group: 'Test'
TOOLSET: vc12
TEST_TOOLSET: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- job_name: 'Cygwin 3.1.7 x64, Test'
job_group: 'TestCygwin'
TOOLSET: gcc
TEST_TOOLSET: gcc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
B2_CXX_PATH: C:/cygwin64/bin
B2_CXX: C:/cygwin64/bin/g++.exe
build_script:
- cmd: |
cd src/engine
set PATH=%B2_CXX_PATH%;%PATH%
- cmd: |
./build.bat %TOOLSET%
- cmd: |
cd ../..
src\engine\b2.exe -v
before_test:
- cmd: |
set HOME=%HOMEDRIVE%%HOMEPATH%
echo using %TEST_TOOLSET% : : %B2_CXX% ; > "%HOME%/user-config.jam"
for:
- matrix:
only:
- job_group: 'Test'
test_script:
- cmd: |
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TEST"
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
cd test
python test_all.py %TEST_TOOLSET%
cd ..
- cmd: |
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NO WARNINGS"
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
src\engine\b2.exe --debug-configuration b2 warnings-as-errors=on variant=debug,release address-model=32,64 toolset=%TEST_TOOLSET%
- cmd: |
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> BOOTSTRAP"
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
bootstrap.bat %TOOLSET%
b2.exe --debug-configuration --prefix=./.b2 install toolset=%TEST_TOOLSET%

View File

@@ -0,0 +1,430 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Copyright Rene Ferdinand Rivera Morell 2015-2021.
trigger:
branches:
include:
- main
- release
- feature/*
paths:
exclude:
- .circleci/*
- .cirrus.yml
- .drone.star
- .github/workflows/*
- .semaphore/*
- .travis.yml
- appveyor.yml
pr:
branches:
include:
- main
paths:
exclude:
- appveyor.yml
variables:
- { name: linux_latest_vm, value: 'ubuntu-20.04' }
- { name: linux_latest_os, value: 'focal' }
- { name: windows_latest_vm, value: 'windows-2019' }
- { name: clang_latest, value: '13' }
- { name: gcc_latest, value: '11' }
- { name: vc_latest, value: 'vc142' }
- { name: vs_latest, value: '2019' }
- { name: xc_latest, value: '12.5.1' }
- { name: macos_latest_vm, value: 'macOS-11' }
stages:
- stage: Core
jobs:
- job: 'Linux_Default_Build'
strategy:
matrix:
Clang ${{variables.clang_latest}}: {TOOLSET: "clang-${{variables.clang_latest}}", PACKAGES: "clang-${{variables.clang_latest}}", LLVM_OS: "${{variables.linux_latest_os}}", LLVM_VER: "${{variables.clang_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"}
pool:
vmImage: $(VM_IMAGE)
steps:
- bash: |
set -e
uname -a
./.ci/linux-cxx-install.sh
displayName: Install
- bash: |
set -e
./src/engine/build.sh --verbose
displayName: Build
- job: 'Linux_Clang_Only_Build'
strategy:
matrix:
Clang ${{variables.clang_latest}}: {TOOLSET: "clang-${{variables.clang_latest}}", PACKAGES: "clang-${{variables.clang_latest}}", LLVM_OS: "${{variables.linux_latest_os}}", LLVM_VER: "${{variables.clang_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"}
pool:
vmImage: $(VM_IMAGE)
steps:
- bash: |
set -e
uname -a
./.ci/linux-cxx-install.sh
sudo apt remove gcc g++
displayName: Install
- bash: |
set -e
./src/engine/build.sh --verbose
displayName: Build
- job: 'Linux_Latest'
strategy:
matrix:
GCC ${{variables.gcc_latest}}: {TOOLSET: "gcc-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}", VM_IMAGE: "${{variables.linux_latest_vm}}"}
Clang ${{variables.clang_latest}}: {TOOLSET: "clang-${{variables.clang_latest}}", PACKAGES: "clang-${{variables.clang_latest}}", LLVM_OS: "${{variables.linux_latest_os}}", LLVM_VER: 13, VM_IMAGE: "${{variables.linux_latest_vm}}"}
pool:
vmImage: $(VM_IMAGE)
steps:
- template: .ci/azp-linux-test.yml
- job: 'Windows_Latest'
strategy:
matrix:
VS ${{variables.vs_latest}}: {TOOLSET: "${{variables.vc_latest}}", TEST_TOOLSET: msvc, VM_IMAGE: "${{variables.windows_latest_vm}}"}
pool:
vmImage: $(VM_IMAGE)
steps:
- template: .ci/azp-windows-test.yml
- job: 'macOS'
strategy:
matrix:
Xcode ${{variables.xc_latest}}: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app", VM_IMAGE: "${{variables.macos_latest_vm}}"}
pool:
vmImage: $(VM_IMAGE)
steps:
- template: .ci/azp-macos-test.yml
- job: 'Linux_ASAN'
strategy:
matrix:
Clang ${{variables.clang_latest}}: {TOOLSET: "clang-${{variables.clang_latest}}", PACKAGES: "clang-${{variables.clang_latest}}", LLVM_OS: "${{variables.linux_latest_os}}", LLVM_VER: 13, VM_IMAGE: "${{variables.linux_latest_vm}}"}
pool:
vmImage: $(VM_IMAGE)
continueOnError: 'true'
steps:
- template: .ci/azp-linux-asan-test.yml
- stage: Compilers
dependsOn: [Core]
jobs:
- job: 'Linux'
strategy:
matrix:
GCC 10: {TOOLSET: gcc-10, PACKAGES: g++-10, VM_IMAGE: 'ubuntu-20.04'}
GCC 9: {TOOLSET: gcc-9, PACKAGES: g++-9, VM_IMAGE: 'ubuntu-18.04'}
GCC 8: {TOOLSET: gcc-8, PACKAGES: g++-8, VM_IMAGE: 'ubuntu-18.04'}
GCC 7: {TOOLSET: gcc-7, PACKAGES: g++-7, VM_IMAGE: 'ubuntu-18.04'}
GCC 6: {TOOLSET: gcc-6, PACKAGES: g++-6, VM_IMAGE: 'ubuntu-18.04'}
GCC 5: {TOOLSET: gcc-5, PACKAGES: g++-5, VM_IMAGE: 'ubuntu-18.04'}
Clang 12: {TOOLSET: clang-12, PACKAGES: clang-12, LLVM_OS: focal, LLVM_VER: 12, VM_IMAGE: 'ubuntu-20.04'}
Clang 11: {TOOLSET: clang-11, PACKAGES: clang-11, LLVM_OS: focal, LLVM_VER: 11, VM_IMAGE: 'ubuntu-20.04'}
Clang 10: {TOOLSET: clang-10, PACKAGES: clang-10, LLVM_OS: bionic, LLVM_VER: 10, VM_IMAGE: 'ubuntu-18.04'}
Clang 9: {TOOLSET: clang-9, PACKAGES: clang-9, LLVM_OS: bionic, LLVM_VER: 9, VM_IMAGE: 'ubuntu-18.04'}
Clang 8: {TOOLSET: clang-8, PACKAGES: clang-8, LLVM_OS: bionic, LLVM_VER: 8, VM_IMAGE: 'ubuntu-18.04'}
Clang 7: {TOOLSET: clang-7, PACKAGES: clang-7, LLVM_OS: bionic, LLVM_VER: 7, VM_IMAGE: 'ubuntu-18.04'}
Clang 6: {TOOLSET: clang-6.0, PACKAGES: clang-6.0, LLVM_OS: bionic, LLVM_VER: 6.0, VM_IMAGE: 'ubuntu-18.04'}
Clang 5: {TOOLSET: clang-5.0, PACKAGES: clang-5.0, LLVM_OS: bionic, LLVM_VER: 5.0, VM_IMAGE: 'ubuntu-18.04'}
Clang 4: {TOOLSET: clang-4.0, PACKAGES: clang-4.0, LLVM_OS: xenial, LLVM_VER: 4.0, VM_IMAGE: 'ubuntu-18.04'}
pool:
vmImage: $(VM_IMAGE)
steps:
- template: .ci/azp-linux-test.yml
- job: 'Windows'
strategy:
matrix:
VS 2022: {TOOLSET: vc143, TEST_TOOLSET: msvc, VM_IMAGE: 'windows-2022'}
VS 2017: {TOOLSET: vc141, TEST_TOOLSET: msvc, VM_IMAGE: 'vs2017-win2016'}
MinGW 8.1.0: {TOOLSET: mingw, TEST_TOOLSET: gcc, VM_IMAGE: 'vs2017-win2016'}
pool:
vmImage: $(VM_IMAGE)
steps:
- template: .ci/azp-windows-test.yml
- job: 'macOS'
strategy:
matrix:
Xcode 13.0: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_13.0.app, VM_IMAGE: 'macOS-11'}
Xcode 12.4: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_12.4.app, VM_IMAGE: 'macOS-11'}
Xcode 12.3: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_12.3.app, VM_IMAGE: 'macOS-10.15'}
Xcode 12.2: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_12.2.app, VM_IMAGE: 'macOS-10.15'}
Xcode 12.1.1: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_12.1.1.app, VM_IMAGE: 'macOS-10.15'}
Xcode 12.0.1: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_12.0.1.app, VM_IMAGE: 'macOS-10.15'}
Xcode 11.7: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_11.7.app, VM_IMAGE: 'macOS-10.15'}
Xcode 11.6: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_11.6.app, VM_IMAGE: 'macOS-10.15'}
Xcode 11.5: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_11.5.app, VM_IMAGE: 'macOS-10.15'}
Xcode 11.4.1: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_11.4.1.app, VM_IMAGE: 'macOS-10.15'}
Xcode 11.3.1: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_11.3.1.app, VM_IMAGE: 'macOS-10.15'}
Xcode 11.3: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_11.3.app, VM_IMAGE: 'macOS-10.15'}
Xcode 11.2.1: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_11.2.1.app, VM_IMAGE: 'macOS-10.15'}
Xcode 10.2.1: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_10.2.1.app, VM_IMAGE: 'macOS-10.14'}
Xcode 10.2: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_10.2.app, VM_IMAGE: 'macOS-10.14'}
Xcode 10.1: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_10.1.app, VM_IMAGE: 'macOS-10.14'}
Xcode 10.0: {TOOLSET: clang, TEST_TOOLSET: clang, CXX: clang++, XCODE_APP: /Applications/Xcode_10.app, VM_IMAGE: 'macOS-10.14'}
pool:
vmImage: $(VM_IMAGE)
steps:
- template: .ci/azp-macos-test.yml
- stage: Boost_Dev
dependsOn: [Core]
jobs:
- job: 'Dev_Linux'
displayName: 'Dev Linux'
pool:
vmImage: 'ubuntu-latest'
strategy:
matrix:
Master .. GCC ${{variables.gcc_latest}}: {BOOST_BRANCH: master, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}"}
Master .. Clang ${{variables.clang_latest}}: {BOOST_BRANCH: master, TOOLSET: clang, CXX: "clang++-${{variables.clang_latest}}", PACKAGES: "clang-${{variables.clang_latest}}", LLVM_OS: "${{variables.linux_latest_os}}", LLVM_VER: "${{variables.clang_latest}}"}
Develop .. GCC ${{variables.gcc_latest}}: {BOOST_BRANCH: develop, TOOLSET: gcc, CXX: "g++-${{variables.gcc_latest}}", PACKAGES: "g++-${{variables.gcc_latest}}"}
Develop .. Clang ${{variables.clang_latest}}: {BOOST_BRANCH: develop, TOOLSET: clang, CXX: "clang++-${{variables.clang_latest}}", PACKAGES: "clang-${{variables.clang_latest}}", LLVM_OS: "${{variables.linux_latest_os}}", LLVM_VER: "${{variables.clang_latest}}"}
steps:
- bash: |
set -e
uname -a
./.ci/linux-cxx-install.sh
displayName: Install
- bash: |
set -e
cd src/engine
./build.sh ${TOOLSET} --cxx=${CXX}
./b2 -v
displayName: Build
- bash: |
set -e
pushd ${HOME}
git clone --recursive https://github.com/boostorg/boost.git
cd boost
git checkout ${BOOST_BRANCH}
CXX_PATH=`which ${CXX}`
echo "using ${TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam
"${BUILD_SOURCESDIRECTORY}/src/engine/b2" "--boost-build=${BUILD_SOURCESDIRECTORY}/src" --debug-configuration --build-type=complete --layout=versioned -n -d1 toolset=${TOOLSET} install
popd
displayName: Test
- job: 'Dev_macOS'
displayName: 'Dev macOS'
pool:
vmImage: "${{variables.macos_latest_vm}}"
strategy:
matrix:
Master .. Xcode ${{variables.xc_latest}}: {BOOST_BRANCH: master, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"}
Develop .. Xcode ${{variables.xc_latest}}: {BOOST_BRANCH: develop, TOOLSET: clang, CXX: clang++, XCODE_APP: "/Applications/Xcode_${{variables.xc_latest}}.app"}
steps:
- bash: |
set -e
uname -a
sudo xcode-select -switch ${XCODE_APP}
which clang++
displayName: Install
- bash: |
set -e
cd src/engine
./build.sh ${TOOLSET} --cxx=${CXX}
./b2 -v
displayName: Build
- bash: |
set -e
pushd ${HOME}
git clone --recursive https://github.com/boostorg/boost.git
cd boost
git checkout ${BOOST_BRANCH}
CXX_PATH=`which ${CXX}`
echo "using ${TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam
"${BUILD_SOURCESDIRECTORY}/src/engine/b2" "--boost-build=${BUILD_SOURCESDIRECTORY}/src" --debug-configuration --build-type=complete --layout=versioned -n -d1 toolset=${TOOLSET} install
popd
displayName: Test
- job: 'Dev_Windows'
displayName: 'Dev Windows'
pool:
vmImage: "${{variables.windows_latest_vm}}"
strategy:
matrix:
Master .. VS ${{variables.vs_latest}}: {BOOST_BRANCH: master, TOOLSET: "${{variables.vc_latest}}"}
Develop .. VS ${{variables.vs_latest}}: {BOOST_BRANCH: develop, TOOLSET: "${{variables.vc_latest}}"}
steps:
- powershell: |
cd src/engine
$env:path += ';' + ${env:CXX_PATH}
cmd /c build.bat ${env:TOOLSET}
./b2.exe -v
cd ../..
displayName: Build
- powershell: |
$env:HOME = "$env:HOMEDRIVE" + "$env:HOMEPATH"
cd "${env:HOME}"
git clone --recursive https://github.com/boostorg/boost.git
cd boost
$OriginalErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference= 'silentlycontinue'
git checkout "${env:BOOST_BRANCH}"
$ErrorActionPreference = $OriginalErrorActionPreference
echo "using" "msvc" ";" > "${env:HOME}/user-config.jam"
& "${env:BUILD_SOURCESDIRECTORY}\src\engine\b2.exe" "--boost-build=${env:BUILD_SOURCESDIRECTORY}/src" --debug-configuration --build-type=complete --layout=versioned -n -d1 toolset=msvc install
displayName: Test
- stage: Boost_Release
dependsOn: [Boost_Dev]
jobs:
- job: 'Release_Linux'
displayName: 'Release Linux'
pool:
vmImage: 'ubuntu-latest'
strategy:
matrix:
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
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}}"}
steps:
- bash: |
set -e
uname -a
./.ci/linux-cxx-install.sh
displayName: Install
- bash: |
set -e
cd src/engine
./build.sh ${TOOLSET} --cxx=${CXX}
./b2 -v
displayName: Build
- bash: |
set -e
pushd ${HOME}
git clone -b boost-${BOOST_VERSION} --single-branch --recurse-submodules https://github.com/boostorg/boost.git boost_${BOOST_VERSION_U}
cd boost_${BOOST_VERSION_U}
CXX_PATH=`which ${CXX}`
echo "using ${TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam
"${BUILD_SOURCESDIRECTORY}/src/engine/b2" "--boost-build=${BUILD_SOURCESDIRECTORY}/src" --debug-configuration --build-type=complete --layout=versioned -n -d1 toolset=${TOOLSET} install
popd
displayName: Test
- job: 'Release_macOS'
displayName: 'Release macOS'
pool:
vmImage: "${{variables.macos_latest_vm}}"
strategy:
matrix:
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.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.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.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: |
set -e
uname -a
sudo xcode-select -switch ${XCODE_APP}
which clang++
displayName: Install
- bash: |
set -e
cd src/engine
./build.sh ${TOOLSET} --cxx=${CXX}
./b2 -v
displayName: Build
- bash: |
set -e
pushd ${HOME}
git clone -b boost-${BOOST_VERSION} --single-branch --recurse-submodules https://github.com/boostorg/boost.git boost_${BOOST_VERSION_U}
cd boost_${BOOST_VERSION_U}
CXX_PATH=`which ${CXX}`
echo "using ${TOOLSET} : : ${CXX_PATH} ;" > ${HOME}/user-config.jam
"${BUILD_SOURCESDIRECTORY}/src/engine/b2" "--boost-build=${BUILD_SOURCESDIRECTORY}/src" --debug-configuration --build-type=complete --layout=versioned -n -d1 toolset=${TOOLSET} install
popd
displayName: Test
- job: 'Release_Windows'
displayName: 'Release Windows'
pool:
vmImage: "${{variables.windows_latest_vm}}"
strategy:
matrix:
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.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.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.66.0 .. VS ${{variables.vs_latest}}: {BOOST_VERSION: 1.66.0, BOOST_VERSION_U: 1_66_0, TOOLSET: "${{variables.vc_latest}}"}
steps:
- powershell: |
cd src/engine
$env:path += ';' + ${env:CXX_PATH}
cmd /c build.bat ${env:TOOLSET}
./b2.exe -v
cd ../..
displayName: Build
- powershell: |
$env:HOME = "$env:HOMEDRIVE" + "$env:HOMEPATH"
cd "${env:HOME}"
git clone -b boost-${env:BOOST_VERSION} --single-branch --recurse-submodules https://github.com/boostorg/boost.git boost_${env:BOOST_VERSION_U}
cd "boost_${env:BOOST_VERSION_U}"
echo "using" "msvc" ";" > "${env:HOME}/user-config.jam"
& "${env:BUILD_SOURCESDIRECTORY}\src\engine\b2.exe" "--boost-build=${env:BUILD_SOURCESDIRECTORY}/src" --debug-configuration --build-type=complete --layout=versioned -n -d1 toolset=msvc install
displayName: Test
- stage: Website_Update
dependsOn: [Core]
displayName: 'Website Update'
condition: in(variables['Build.SourceBranch'], 'refs/heads/main', 'refs/heads/release')
jobs:
- job: Documentation
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
- task: UseRubyVersion@0
- bash: |
pip install --user Pygments
pip install --user "https://github.com/bfgroup/jam_pygments/archive/master.zip"
gem install asciidoctor
gem install pygments.rb
echo "using asciidoctor ;" >> project-config.jam
./bootstrap.sh
pushd doc
../b2 --website-doc-dir=manual/$(Build.SourceBranchName) website
displayName: 'Build & Publish'
env:
GH_TOKEN: $(GitHubToken)

View File

@@ -0,0 +1,8 @@
# Copyright 2001, 2002 Dave Abrahams
# Copyright 2002 Rene Rivera
# Copyright 2003 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
boost-build src/kernel ;

View File

@@ -0,0 +1,671 @@
# Boost.Build support specific for the Boost C++ Libraries.
# Copyright Vladimir Prus 2002-2010.
# Copyright Dave Abrahams 2005-2006.
# Copyright Rene Rivera 2005-2007.
# Copyright Douglas Gregor 2005.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import "class" : new ;
import common ;
import configure ;
import build-system ;
import generate ;
import modules ;
import option ;
import os ;
import package ;
import path ;
import project ;
import regex ;
import sequence ;
import set ;
import targets ;
import feature ;
import property ;
import version : version-less ;
##############################################################################
#
# 0. General setup. Parse options, check them.
#
##############################################################################
BOOST_ROOT = [ modules.binding $(__name__) ] ;
BOOST_ROOT = $(BOOST_ROOT:D) ;
rule set-version ( version )
{
BOOST_VERSION = $(version) ;
local version-tag =
[ MATCH "^([^.]+)[.]([^.]+)[.]([^.]+)" : $(BOOST_VERSION) ] ;
if $(version-tag[3]) = 0
{
version-tag = $(version-tag[1-2]) ;
}
BOOST_VERSION_TAG = $(version-tag:J=_) ;
}
# Option to choose how many variants to build. The default is "minimal".
build-type = [ option.get build-type ] ;
build-type ?= minimal ;
if ! ( $(build-type) in complete minimal )
{
EXIT The value of the --build-type option should be either 'complete' or
'minimal' ;
}
# What kind of layout are we doing?
layout = [ option.get layout : "" ] ;
layout = [ MATCH (versioned|tagged|system)(-(.+))? : $(layout) ] ;
if $(layout[3])
{
layout-version = $(layout[3]) ;
layout = $(layout[1]) ;
if [ version-less [ regex.split $(layout-version) "[.]" ] : 1 66 ]
{
layout-version = 1.40 ;
}
else if [ version-less [ regex.split $(layout-version) "[.]" ] : 1 69 ]
{
layout-version = 1.66 ;
}
}
layout-version ?= 1.69 ;
# On Windows, we used versioned layout by default in order to be compatible with
# autolink. On other systems, we use system layout which is what every other
# program uses. Note that the Windows check is static, and will not be affected
# by specific build properties used.
if ! $(layout)
{
if [ os.name ] = NT
{
layout = versioned ;
}
else
{
layout = system ;
}
}
layout-$(layout) = true ;
if $(layout) = system && $(build-type) = complete
{
ECHO error\: Cannot use --layout=system with --build-type complete. ;
ECHO error\: Please use either --layout=versioned or --layout=tagged ;
ECHO error\: if you wish to build multiple variants. ;
if [ os.name ] != NT
{
ECHO error\: Note that --layout=system is used by default on Unix
starting with Boost 1.40. ;
}
EXIT ;
}
# Possible stage only location.
stage-locate = [ option.get stagedir ] ;
if $(stage-locate)
{
stage-locate = [ path.root [ path.make $(stage-locate) ] [ path.pwd ] ] ;
}
else
{
stage-locate = $(BOOST_ROOT)/stage ;
}
BOOST_STAGE_LOCATE = $(stage-locate) ;
# Custom build ID.
build-id = [ option.get buildid ] ;
if $(build-id)
{
BUILD_ID = [ regex.replace $(build-id) "[*\\/:.\"\' ]" _ ] ;
}
# Python build id (for Python libraries only).
python-id = [ option.get "python-buildid" ] ;
if $(python-id)
{
PYTHON_ID = [ regex.replace $(python-id) "[*\\/:.\"\']" _ ] ;
}
if $(layout) = versioned
{
switch $(layout-version)
{
case 1.40 :
.format-name-args =
<base> <toolset> <threading> <runtime> ;
case 1.66 :
.format-name-args =
<base> <toolset> <threading> <runtime> <arch-and-model> ;
case 1.69 :
.format-name-args =
<base> <toolset> <threading> <runtime> <arch-and-model> ;
}
}
else if $(layout) = tagged
{
switch $(layout-version)
{
case 1.40 :
.format-name-args =
<base> <threading> <runtime> ;
case 1.66 :
.format-name-args =
<base> <threading> <runtime> ;
case 1.69 :
.format-name-args =
<base> <threading> <runtime> <arch-and-model> ;
}
}
else if $(layout) = system
{
.format-name-args = <base> ;
}
else
{
.format-name-error = true ;
}
################################################################################
#
# 1. 'tag' function adding decorations suitable to the properties if versioned
# or tagged layout is requested. Called from Jamroot.
#
################################################################################
rule tag ( name : type ? : property-set )
{
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
local args = $(.format-name-args) ;
if $(layout) = versioned
{
args += -$(BOOST_VERSION_TAG) ;
}
local result = [ common.format-name
$(args) -$(BUILD_ID)
: $(name) : $(type) : $(property-set) ] ;
if $(.format-name-error)
{
EXIT error\: invalid layout '$(layout:E=)' ;
}
# Optionally add version suffix. On NT, library with version suffix will
# not be recognized by linkers. On CYGWIN, we get strage duplicate
# symbol errors when library is generated with version suffix. On OSX,
# version suffix is not needed -- the linker expects the
# libFoo.1.2.3.dylib format. AIX linkers do not accept version suffixes
# either. Pgi compilers can not accept a library with version suffix.
if $(type) = SHARED_LIB &&
! [ $(property-set).get <target-os> ] in windows cygwin darwin aix android &&
! [ $(property-set).get <toolset> ] in pgi
{
result = $(result).$(BOOST_VERSION) ;
}
return $(result) ;
}
}
# Specialized tag function to use for libraries linking to Python.
# Appends value of --python-buildid if provided.
rule python-tag ( name : type ? : property-set )
{
local result = $(name) ;
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
# Add Python version suffix
local version = [ $(property-set).get <python> ] ;
local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)" : $(version) ] ;
local suffix = $(major-minor:J="") ;
if $(suffix)
{
result = $(result)$(suffix) ;
}
# Add PYTHON_ID if supplied
if $(PYTHON_ID)
{
result = $(result)-$(PYTHON_ID) ;
}
}
# forward to the boost tagging rule
return [ tag $(result) : $(type) : $(property-set) ] ;
}
################################################################################
#
# 2. Declare targets that build and install all libraries. Specifically:
#
# - 'stage-proper' that puts all libraries in stage/lib
# - 'install-proper' that install libraries and headers to system location
#
################################################################################
rule declare_install_and_stage_proper_targets ( libraries * )
{
local p = [ project.current ] ;
alias install-proper : libs/$(libraries)/build//install ;
$(p).mark-target-as-explicit install-proper ;
alias stage-proper : libs/$(libraries)/build//stage ;
$(p).mark-target-as-explicit stage-proper ;
}
################################################################################
#
# 3. Declare top-level targets 'stage' and 'install'. These examine the
# --build-type option and, in case it is 'complete', build the 'install-proper'
# and 'stage-proper' targets with a number of property sets.
#
################################################################################
rule emit-shared-static-warning ( )
{
if ! $(.shared-static-warning-emitted)
{
ECHO "" ;
ECHO "warning: The configuration link=shared, runtime-link=static is disabled" ;
ECHO "warning: by default as being too dangerous to use, and will not be built." ;
ECHO "warning: To enable it, use --allow-shared-static." ;
ECHO "" ;
.shared-static-warning-emitted = 1 ;
}
}
class top-level-target : alias-target-class
{
import modules ;
import boostcpp ;
rule __init__ ( name : project : sources * : requirements *
: default-build * : usage-requirements * )
{
alias-target-class.__init__ $(name) : $(project) : $(sources) :
$(requirements) : $(default-build) : $(usage-requirements) ;
self.build-type = [ modules.peek boostcpp : build-type ] ;
# On Linux, we build the release variant by default, since few users
# will ever want to debug C++ Boost libraries, and there is no ABI
# incompatibility between debug and release variants. We build shared
# and static libraries since that is what most packages seem to provide
# (.so in libfoo and .a in libfoo-dev).
self.minimal-properties = [ property-set.create <variant>release
<threading>multi <link>shared <link>static <runtime-link>shared ] ;
# On Windows, new IDE projects use:
#
# runtime-link=dynamic, threading=multi, variant=(debug|release)
#
# and in addition, C++ Boost's autolink defaults to static linking.
self.minimal-properties-win = [ property-set.create <variant>debug
<variant>release <threading>multi <link>static <runtime-link>shared
<address-model>32 <address-model>64 ] ;
self.complete-properties = [ property-set.create
<variant>debug <variant>release
<threading>multi
<link>shared <link>static
<runtime-link>shared <runtime-link>static ] ;
self.complete-properties-win = [ property-set.create
<variant>debug <variant>release
<threading>multi
<link>shared <link>static
<runtime-link>shared <runtime-link>static
<address-model>32 <address-model>64 ] ;
}
rule generate ( property-set )
{
modules.poke : top-level-targets : [ modules.peek : top-level-targets ]
$(self.name) ;
local os = [ $(property-set).get <target-os> ] ;
# Because we completely override the parent's 'generate' we need to
# check for default feature values ourselves.
if ! $(os)
{
os = [ feature.defaults <target-os> ] ;
os = $(os:G=) ;
}
local build-type-set ;
if $(self.build-type) = minimal
{
if $(os) = windows
{
build-type-set = $(self.minimal-properties-win) ;
}
else
{
build-type-set = $(self.minimal-properties) ;
}
}
else if $(self.build-type) = complete
{
if $(os) = windows
{
build-type-set = $(self.complete-properties-win) ;
}
else
{
build-type-set = $(self.complete-properties) ;
}
}
else
{
import errors ;
errors.error "Unknown build type" ;
}
if $(build-type-set)
{
local expanded = [ targets.apply-default-build $(property-set)
: $(build-type-set) ] ;
# Filter inappopriate combinations.
local filtered ;
local skipped ;
local argv = [ modules.peek : ARGV ] ;
for local p in $(expanded)
{
# See comment in handle-static-runtime regarding this logic.
if [ $(p).get <link> ] = shared
&& [ $(p).get <runtime-link> ] = static
&& [ $(p).get <toolset> ] != cw
&& ! --allow-shared-static in $(argv)
{
# Skip this.
skipped += $(p) ;
}
else
{
filtered += $(p) ;
}
}
if $(expanded) = $(skipped)
{
boostcpp.emit-shared-static-warning ;
}
return [ build-multiple $(filtered) ] ;
}
}
rule build-multiple ( property-sets * )
{
local usage-requirements = [ property-set.empty ] ;
local result ;
for local p in $(property-sets)
{
local r = [ alias-target-class.generate $(p) ] ;
if $(r)
{
usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
result += $(r[2-]) ;
}
}
return $(usage-requirements) [ sequence.unique $(result) ] ;
}
}
rule declare_top_level_targets ( libraries * )
{
declare_install_and_stage_proper_targets $(libraries) ;
targets.create-metatarget top-level-target : [ project.current ]
: install
: install-proper
;
targets.create-metatarget top-level-target : [ project.current ]
: stage
: stage-proper headers
;
p = [ project.current ] ;
$(p).mark-target-as-explicit install stage ;
# This target is built by default, and will forward to 'stage' after
# producing some explanations.
targets.create-metatarget top-level-target : [ project.current ]
: forward
: explain stage
;
}
################################################################################
#
# 4. Add hook to report configuration before the build, and confirmation with
# setup instructions after the build.
#
################################################################################
message explain : "\nBuilding the Boost C++ Libraries.\n\n" ;
local p = [ project.current ] ;
$(p).mark-target-as-explicit explain ;
rule pre-build ( )
{
local tl = [ modules.peek : top-level-targets ] ;
if stage in $(tl) || install in $(tl)
{
# FIXME: Remove 'if' when Boost regression tests start using trunk bjam.
if PAD in [ RULENAMES ]
{
configure.print-component-configuration ;
}
}
}
IMPORT $(__name__) : pre-build : : $(__name__).pre-build ;
build-system.set-pre-build-hook $(__name__).pre-build ;
rule post-build ( ok ? )
{
if forward in [ modules.peek : top-level-targets ]
{
if $(ok)
{
local include-path = [ path.native $(BOOST_ROOT) ] ;
local stage-abs = [ path.native $(stage-locate)/lib ] ;
ECHO "
The Boost C++ Libraries were successfully built!
The following directory should be added to compiler include paths:
$(include-path)
The following directory should be added to linker library paths:
$(stage-abs)
" ;
}
}
}
IMPORT $(__name__) : post-build : : $(__name__).post-build ;
build-system.set-post-build-hook $(__name__).post-build ;
################################################################################
#
# 5. Top-level setup.
#
################################################################################
# Decides which libraries are to be installed by looking at --with-<library>
# --without-<library> arguments. Returns the list of directories under "libs"
# which must be built and installed.
#
rule libraries-to-install ( existing-libs * )
{
local argv = [ modules.peek : ARGV ] ;
local with-parameter = [ MATCH ^--with-(.*) : $(argv) ] ;
local without-parameter = [ MATCH ^--without-(.*) : $(argv) ] ;
if ! $(with-parameter) && ! $(without-parameter)
{
# Nothing is specified on command line. See if maybe project-config.jam
# has some choices.
local libs = [ modules.peek project-config : libraries ] ;
with-parameter = [ MATCH ^--with-(.*) : $(libs) ] ;
without-parameter = [ MATCH ^--without-(.*) : $(libs) ] ;
}
# Do some checks.
if $(with-parameter) && $(without-parameter)
{
EXIT error\: both --with-<library> and --without-<library> specified ;
}
local wrong = [ set.difference $(with-parameter) : $(existing-libs) ] ;
if $(wrong)
{
EXIT error\: wrong library name '$(wrong[1])' in the --with-<library>
option. ;
}
local wrong = [ set.difference $(without-parameter) : $(existing-libs) ] ;
if $(wrong)
{
EXIT error\: wrong library name '$(wrong[1])' in the --without-<library>
option. ;
}
if $(with-parameter)
{
return [ set.intersection $(existing-libs) : $(with-parameter) ] ;
}
else
{
return [ set.difference $(existing-libs) : $(without-parameter) ] ;
}
}
rule declare-targets ( all-libraries * )
{
configure.register-components $(all-libraries) ;
# Select the libraries to install.
libraries = [ libraries-to-install $(all-libraries) ] ;
configure.components-building $(libraries) ;
if [ option.get "show-libraries" : : true ]
{
ECHO The following libraries require building\: ;
for local l in $(libraries)
{
ECHO " - $(l)" ;
}
EXIT ;
}
declare_top_level_targets $(libraries) ;
}
# Returns the properties identifying the toolset. We'll use them
# below to configure checks. These are essentially same as in
# configure.builds, except we don't use address-model and
# architecture - as we're trying to detect them here.
#
rule toolset-properties ( properties * )
{
local toolset = [ property.select <toolset> : $(properties) ] ;
local toolset-version-property = "<toolset-$(toolset:G=):version>" ;
return [ property.select <target-os> <toolset> $(toolset-version-property) : $(properties) ] ;
}
feature.feature deduced-address-model : 32 64 : propagated optional composite hidden ;
feature.compose <deduced-address-model>32 : <address-model>32 ;
feature.compose <deduced-address-model>64 : <address-model>64 ;
rule deduce-address-model ( properties * )
{
local result ;
local filtered = [ toolset-properties $(properties) ] ;
local names = 32 64 ;
local idx = [ configure.find-builds "default address-model" : $(filtered)
: /boost/architecture//32 "32-bit"
: /boost/architecture//64 "64-bit" ] ;
result = $(names[$(idx)]) ;
if $(result)
{
# Normally, returning composite feature here is equivalent to forcing
# consituent properties as well. But we only want to indicate toolset
# deduced default, so also pick whatever address-model is explicitly
# specified, if any.
result = <deduced-address-model>$(result) [ property.select <address-model> : $(properties) ] ;
}
return $(result) ;
}
rule address-model ( )
{
return <conditional>@boostcpp.deduce-address-model ;
}
local deducable-architectures = arm mips1 power riscv s390x sparc x86 combined ;
feature.feature deduced-architecture : $(deducable-architectures) : propagated optional composite hidden ;
for a in $(deducable-architectures)
{
feature.compose <deduced-architecture>$(a) : <architecture>$(a) ;
}
rule deduce-architecture ( properties * )
{
local result ;
local filtered = [ toolset-properties $(properties) ] ;
local names = arm mips1 power riscv s390x sparc x86 combined ;
local idx = [ configure.find-builds "default architecture" : $(filtered)
: /boost/architecture//arm
: /boost/architecture//mips1
: /boost/architecture//power
: /boost/architecture//riscv
: /boost/architecture//s390x
: /boost/architecture//sparc
: /boost/architecture//x86
: /boost/architecture//combined ] ;
result = $(names[$(idx)]) ;
if $(result)
{
# See comment in deduce-address-model.
result = <deduced-architecture>$(result) [ property.select <architecture> : $(properties) ] ;
}
return $(result) ;
}
rule architecture ( )
{
return <conditional>@boostcpp.deduce-architecture ;
}

View File

@@ -0,0 +1,39 @@
@ECHO OFF
REM Copyright (C) 2009 Vladimir Prus
REM Copyright 2019-2020 Rene Rivera
REM
REM Distributed under the Boost Software License, Version 1.0.
REM (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
:b2_build
ECHO Building the B2 engine..
pushd src\engine
call .\build.bat %*
@ECHO OFF
popd
if exist ".\src\engine\b2.exe" (
copy .\src\engine\b2.exe . > nul
goto :b2_built)
goto :b2_failure
:b2_built
ECHO.
ECHO Building is done. To install, run:
ECHO.
ECHO .\b2 --prefix=DIR install
ECHO.
goto :end
:b2_failure
ECHO.
ECHO Failed to build the B2 engine.
ECHO.
goto :end
:end
exit /b %ERRORLEVEL%

View File

@@ -0,0 +1,28 @@
#!/bin/sh
# Copyright (C) 2005, 2006 Douglas Gregor.
# Copyright (C) 2006 The Trustees of Indiana University
# Copyright (C) 2010 Bryce Lelbach
# Copyright 2018-2020 Rene Rivera
#
# 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)
# Build b2
echo "Building the B2 engine.."
pwd=`pwd`
"${pwd}/src/engine/build.sh" "$@"
if [ $? -ne 0 ]; then
echo
echo "Failed to build the B2 engine." 1>&2
exit 1
fi
cd "$pwd"
cp "./src/engine/b2" .
cat << EOF
Building is done. To install, run:
./b2 install --prefix=<DIR>
EOF

View File

@@ -0,0 +1,48 @@
$! Copyright 2015 Artur Shepilko.
$!
$! 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)
$!
$ THIS_FACILITY = "BOOSTBUILD"
$
$ verify = f$trnlnm("VERIFY_''THIS_FACILITY'")
$ save_verify = f$verify(verify)
$ save_default = f$env("DEFAULT")
$
$ SAY := WRITE SYS$OUTPUT
$
$ ON WARNING THEN CONTINUE
$ ON ERROR THEN GOTO ERROR
$
$ SAY "I|Bootstrapping the build engine..."
$
$ set def [.src.engine]
$ @build_vms /out=[--]bootstrap.log
$
$ set def 'save_default'
$
$ if f$search("[.src.engine.bin_vms]b2.exe") .eqs. "" then goto ERROR
$ copy [.src.engine.bin_vms]b2.exe []
$ copy [.src.engine.bin_vms]bjam.exe []
$
$ SAY "I|Bootstrapping is done, B2.EXE created."
$ type sys$input
$DECK
To build and install under ROOT: directory, run:
MC []B2 --prefix="/root" install
Set B2 command:
B2 :== $ROOT:[BIN]B2.EXE
$EOD
$ sts = 1
$
$EXIT:
$ set def 'save_default'
$ exit 'sts' + (0 * f$verify(save_verify))
$ERROR:
$ SAY "E|Failed to bootstrap build engine, see BOOTSTRAP.LOG for details."
$ sts = 4
$ goto EXIT

View File

@@ -0,0 +1,138 @@
#|
Copyright 2004,2006 Vladimir Prus
Copyright 2018 Rene Rivera
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
|#
#|
Doc generation works in two modes: standalone embedded and website.
For the standalone we just generate the local html for inclusion in a release
archive. This is the default when no arguments are given.
For the website we clone the website branch locally, generatate the docs in
the website tree, commit, and push. The default for those arguments is to
build as if we are doing "develop" branch docs.
b2 --website-dir=website --website-doc-dir=manual/develop website
Building documentation has only been tested on Posix systems and requires:
* Ruby
* Python 2
* gem install asciidoctor
* gem install pygments.rb
* pip install --user Pygments
* pip install --user https://github.com/bfgroup/jam_pygments/archive/master.zip
|#
import asciidoctor ;
import modules ;
import path ;
project b2doc
;
path-constant PYGMENTS_DIR : src/pygments ;
path-constant STYLES_DIR : src/styles ;
doc-dir = [ MATCH "--doc-dir=(.*)" : [ modules.peek : ARGV ] ] ;
doc-dir ?= html ;
website = [ MATCH "(website)" : [ modules.peek : ARGV ] ] ;
website-dir = [ MATCH "--website-dir=(.*)" : [ modules.peek : ARGV ] ] ;
website-dir ?= website ;
website-doc-dir = [ MATCH "--website-doc-dir=(.*)" : [ modules.peek : ARGV ] ] ;
website-doc-dir ?= manual/develop ;
if $(website)
{
doc-dir = $(website-dir)/$(website-doc-dir) ;
}
# ECHO $(website) .. $(website-dir) .. $(website-doc-dir) .. $(doc-dir) ;
html index : src/standalone.adoc :
:
# <flags>--require=$(PYGMENTS_DIR)/pygments_init.rb
<flags>--trace
<flags>--verbose
# <dependency>$(PYGMENTS_DIR)/pygments_init.rb
# <flags>"-a stylesheet=amber.css"
# <flags>"-a stylesdir=$(STYLES_DIR)"
# <asciidoctor-attribute>linkcss
;
explicit index ;
install html : index : <location>$(doc-dir) <dependency>website-html ;
explicit html ;
make index.html : : @make_redir_html : <location>.. ;
REDIR_HTML = "
<html><head><meta http-equiv=\"refresh\" content=\"0; URL=doc/html/index.html\"></head><body>
Automatic redirection failed, please go to <a href=\"doc/html/index.html\">doc/html/index.html</a>.
<!-- Distributed under the Boost Software License, Version 1.0. \(See accompanying file LICENSE.txt or copy at https://www.bfgroup.xyz/b2/LICENSE.txt\) -->
</body></html>
" ;
actions make_redir_html
{
echo @($(<):O=F:E=$(REDIR_HTML))
}
explicit index.html ;
alias standalone-html : html ;
if $(website)
{
make website-checkout : : @website-checkout ;
make website-publish : html : @website-publish ;
alias website-html : website-checkout ;
always website-checkout ;
always website-publish ;
}
else
{
alias website-checkout ;
alias website-publish ;
alias website-html ;
}
alias website : website-publish ;
explicit website-checkout ;
explicit website-publish ;
explicit website-html ;
explicit website ;
###############################################################################
actions website-checkout
{
rm -rf "$(website-dir)"
git clone --verbose --branch gh-pages --depth 1 "https://${GH_TOKEN}github.com/bfgroup/b2.git" "$(website-dir)" || exit 1
CD=${PWD}
cd "$(website-dir)"
git rm --ignore-unmatch -r "$(website-doc-dir)" || exit 1
mkdir -p "$(website-doc-dir)" || exit 1
cd ${CD}
echo "done" > "$(<)"
}
actions website-publish
{
CD=${PWD}
cd "$(website-dir)/$(website-doc-dir)"
git config user.email "b2-bot"
git config user.name "b2-bot"
git add --verbose . || exit 1
git commit -m "Update user manual."
git push || exit 1
cd ${CD}
rm -rf "$(website-dir)"
echo "done" > "$(<)"
}
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : standalone-html index.html ;
explicit boostrelease ;

View File

@@ -0,0 +1,65 @@
[[bbv2.reference.class.abstract-target]]
= Class abstract-target
Base class for all abstract targets.
[source]
----
class abstract-target {
rule __init__ ( name : project )
rule name ( )
rule project ( )
rule location ( )
rule full-name ( )
rule generate ( property-set )
}
----
Classes derived from
link:#bbv2.reference.class.abstract-target[abstract-target]:
* project-target
* main-target
* basic-target
--
1. `rule __init__ ( name : project )`
+
`name`::
The name of the target in the Jamfile.
`project`::
The link:#bbv2.reference.class.project-target[project] to which this
target belongs.
2. `rule name ( )`
+
Returns the name of this target.
3. `rule project ( )`
+
Returns the link:#bbv2.reference.class.project-target[project] for this
target.
4. `rule location ( )`
+
Returns the location where the target was declared.
5. `rule full-name ( )`
+
Returns a user-readable name for this target.
6. [[bbv2.reference.class.abstract-target.generate]] `rule generate ( property-set )`
+
Generates virtual targets for this abstract target using the specified
properties, unless a different value of some feature is required by the
target. This is an abstract method which must be overridden by derived
classes.
+
On success, returns:
+
* a property-set with the usage requirements to be applied to dependents
* a list of produced virtual targets, which may be empty.
+
If `property-set` is empty, performs the default build of this target,
in a way specific to the derived class.
--

View File

@@ -0,0 +1,829 @@
@import url(https://fonts.googleapis.com/css2?family=Comfortaa&display=swap);
/*! normalize.css v2.1.2 | MIT License | git.io/normalize */
/* ========================================================================== HTML5 display definitions ========================================================================== */
/** Correct `block` display not defined in IE 8/9. */
@import url(https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap);
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
/** Correct `inline-block` display not defined in IE 8/9. */
audio, canvas, video { display: inline-block; }
/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
audio:not([controls]) { display: none; height: 0; }
/** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */
[hidden], template { display: none; }
script { display: none !important; }
/* ========================================================================== Base ========================================================================== */
/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ }
/** Remove default margin. */
body { margin: 0; }
/* ========================================================================== Links ========================================================================== */
/** Remove the gray background color from active links in IE 10. */
a { background: transparent; }
/** Address `outline` inconsistency between Chrome and other browsers. */
a:focus { outline: thin dotted; }
/** Improve readability when focused and also mouse hovered in all browsers. */
a:active, a:hover { outline: 0; }
/* ========================================================================== Typography ========================================================================== */
/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */
h1 { font-size: 2em; margin: 0.67em 0; }
/** Address styling not present in IE 8/9, Safari 5, and Chrome. */
abbr[title] { border-bottom: 1px dotted; }
/** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */
b, strong { font-weight: bold; }
/** Address styling not present in Safari 5 and Chrome. */
dfn { font-style: italic; }
/** Address differences between Firefox and other browsers. */
hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
/** Address styling not present in IE 8/9. */
mark { background: #ff0; color: #000; }
/** Correct font family set oddly in Safari 5 and Chrome. */
code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; }
/** Improve readability of pre-formatted text in all browsers. */
pre { white-space: pre-wrap; }
/** Set consistent quote types. */
q { quotes: "\201C" "\201D" "\2018" "\2019"; }
/** Address inconsistent and variable font size in all browsers. */
small { font-size: 80%; }
/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
/* ========================================================================== Embedded content ========================================================================== */
/** Remove border when inside `a` element in IE 8/9. */
img { border: 0; }
/** Correct overflow displayed oddly in IE 9. */
svg:not(:root) { overflow: hidden; }
/* ========================================================================== Figures ========================================================================== */
/** Address margin not present in IE 8/9 and Safari 5. */
figure { margin: 0; }
/* ========================================================================== Forms ========================================================================== */
/** Define consistent border, margin, and padding. */
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
/** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */
legend { border: 0; /* 1 */ padding: 0; /* 2 */ }
/** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */
button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ }
/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
button, input { line-height: normal; }
/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */
button, select { text-transform: none; }
/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */
button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }
/** Re-set default cursor for disabled elements. */
button[disabled], html input[disabled] { cursor: default; }
/** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }
/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; }
/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
/** Remove inner padding and border in Firefox 4+. */
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
/** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */
textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ }
/* ========================================================================== Tables ========================================================================== */
/** Remove most spacing between table cells. */
table { border-collapse: collapse; border-spacing: 0; }
meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; }
meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; }
meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; }
*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
html, body { font-size: 100%; }
body { background: #111; color: #aaa; padding: 0; margin: 0; font-family: "Comfortaa", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; }
a:hover { cursor: pointer; }
img, object, embed { max-width: 100%; height: auto; }
object, embed { height: 100%; }
img { -ms-interpolation-mode: bicubic; }
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
.left { float: left !important; }
.right { float: right !important; }
.text-left { text-align: left !important; }
.text-right { text-align: right !important; }
.text-center { text-align: center !important; }
.text-justify { text-align: justify !important; }
.hide { display: none; }
.antialiased { -webkit-font-smoothing: antialiased; }
img { display: inline-block; vertical-align: middle; }
textarea { height: auto; min-height: 50px; }
select { width: 100%; }
p.lead { font-size: 1.21875em; line-height: 1.6; }
.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.45; color: #e18400; font-weight: normal; margin-top: 0; margin-bottom: 0.25em; }
/* Typography resets */
div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; }
/* Default Link Styles */
a { color: #FA9300; text-decoration: underline; line-height: inherit; }
a:hover, a:focus { color: #e18400; }
a img { border: none; }
/* Default paragraph styles */
p { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; text-rendering: optimizeLegibility; }
p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; }
/* Default header styles */
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: "Comfortaa", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-weight: 300; font-style: normal; color: #ffa92e; text-rendering: optimizeLegibility; margin-top: 1em; margin-bottom: 0.5em; line-height: 1.0125em; }
h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #ffe8c7; line-height: 0; }
h1 { font-size: 2.125em; }
h2 { font-size: 1.6875em; }
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; }
h4 { font-size: 1.125em; }
h5 { font-size: 1.125em; }
h6 { font-size: 1em; }
hr { border: solid #2b2b2b; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; }
/* Helpful Typography Defaults */
em, i { font-style: italic; line-height: inherit; }
strong, b { font-weight: bold; line-height: inherit; }
small { font-size: 60%; line-height: inherit; }
code { font-family: "IBM Plex Mono", "Droid Sans Mono", "DejaVu Sans Mono", "Monospace", monospace; font-weight: normal; color: #ffe8c7; }
/* Lists */
ul, ol, dl { font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; }
ul, ol { margin-left: 1.5em; }
ul.no-bullet, ol.no-bullet { margin-left: 1.5em; }
/* Unordered Lists */
ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ }
ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; }
ul.square { list-style-type: square; }
ul.circle { list-style-type: circle; }
ul.disc { list-style-type: disc; }
ul.no-bullet { list-style: none; }
/* Ordered Lists */
ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; }
/* Definition Lists */
dl dt { margin-bottom: 0.3125em; font-weight: bold; }
dl dd { margin-bottom: 1.25em; }
/* Abbreviations */
abbr, acronym { text-transform: uppercase; font-size: 90%; color: #aaa; border-bottom: 1px dotted #ddd; cursor: help; }
abbr { text-transform: none; }
/* Blockquotes */
blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #ddd; }
blockquote cite { display: block; font-size: 0.9375em; color: #aaa; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited { color: #aaa; }
blockquote, blockquote p { line-height: 1.6; color: #ffa92e; }
/* Microformats */
.vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #ddd; padding: 0.625em 0.75em; }
.vcard li { margin: 0; display: block; }
.vcard .fn { font-weight: bold; font-size: 0.9375em; }
.vevent .summary { font-weight: bold; }
.vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; }
@media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.2; }
h1 { font-size: 2.75em; }
h2 { font-size: 2.3125em; }
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
h4 { font-size: 1.4375em; } }
/* Tables */
table { background: #111; margin-bottom: 1.25em; border: solid 1px #613900; }
table thead, table tfoot { background: #2e1b00; font-weight: bold; }
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #aaa; text-align: left; }
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #aaa; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #040404; }
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.6; }
body { tab-size: 4; word-wrap: anywhere; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; }
table { word-wrap: normal; }
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.2; word-spacing: -0.05em; }
h1 strong, h2 strong, h3 strong, #toctitle strong, .sidebarblock > .content > .title strong, h4 strong, h5 strong, h6 strong { font-weight: 400; }
object, svg { display: inline-block; vertical-align: middle; }
.center { margin-left: auto; margin-right: auto; }
.stretch { width: 100%; }
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
.clearfix:after, .float-group:after { clear: both; }
:not(pre).nobreak { word-wrap: normal; }
:not(pre).nowrap { white-space: nowrap; }
:not(pre).pre-wrap { white-space: pre-wrap; }
:not(pre):not([class^=L]) > code { font-size: 0.875em; font-style: normal !important; letter-spacing: 0; padding: 0.1em 0.5ex; word-spacing: -0.15em; background-color: black; border: 1px solid #111; -webkit-border-radius: 8px; border-radius: 8px; line-height: 1.45; text-rendering: optimizeSpeed; }
pre { color: #FA9300; font-family: "IBM Plex Mono", "Droid Sans Mono", "DejaVu Sans Mono", "Monospace", monospace; line-height: 1.45; text-rendering: optimizeSpeed; }
pre code, pre pre { color: inherit; font-size: inherit; line-height: inherit; }
pre > code { display: block; }
pre.nowrap, pre.nowrap pre { white-space: pre; word-wrap: normal; }
em em { font-style: normal; }
strong strong { font-weight: normal; }
.keyseq { color: #dddddd; }
kbd { font-family: "IBM Plex Mono", "Droid Sans Mono", "DejaVu Sans Mono", "Monospace", monospace; display: inline-block; color: #aaa; font-size: 0.65em; line-height: 1.45; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: 0 0.15em; padding: 0.2em 0.5em; vertical-align: middle; position: relative; top: -0.1em; white-space: nowrap; }
.keyseq kbd:first-child { margin-left: 0; }
.keyseq kbd:last-child { margin-right: 0; }
.menuseq, .menuref { color: #000; }
.menuseq b:not(.caret), .menuref { font-weight: inherit; }
.menuseq { word-spacing: -0.02em; }
.menuseq b.caret { font-size: 1.25em; line-height: 0.8; }
.menuseq i.caret { font-weight: bold; text-align: center; width: 0.45em; }
b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
b.button:before { content: "["; padding: 0 3px 0 2px; }
b.button:after { content: "]"; padding: 0 2px 0 3px; }
p a > code:hover { color: #ffddae; }
#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; }
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
#content { margin-top: 1.25em; }
#content:before { content: none; }
#header > h1:first-child { color: #ffa92e; margin-top: 2.25rem; margin-bottom: 0; }
#header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid #2b2b2b; }
#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid #2b2b2b; padding-bottom: 8px; }
#header .details { border-bottom: 1px solid #2b2b2b; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #aaa; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; }
#header .details span:first-child { margin-left: -0.125em; }
#header .details span.email a { color: #ffa92e; }
#header .details br { display: none; }
#header .details br + span:before { content: "\00a0\2013\00a0"; }
#header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #ffa92e; }
#header .details br + span#revremark:before { content: "\00a0|\00a0"; }
#header #revnumber { text-transform: capitalize; }
#header #revnumber:after { content: "\00a0"; }
#content > h1:first-child:not([class]) { color: #ffa92e; border-bottom: 1px solid #2b2b2b; padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; }
#toc { border-bottom: 1px solid #1e1e1e; padding-bottom: 0.5em; }
#toc > ul { margin-left: 0.125em; }
#toc ul.sectlevel0 > li > a { font-style: italic; }
#toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; }
#toc ul { font-family: "Comfortaa", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; list-style-type: none; }
#toc li { line-height: 1.3334; margin-top: 0.3334em; }
#toc a { text-decoration: none; }
#toc a:active { text-decoration: underline; }
#toctitle { color: #e18400; font-size: 1.2em; }
@media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; }
body.toc2 { padding-left: 15em; padding-right: 0; }
#toc.toc2 { margin-top: 0 !important; background: black; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #1e1e1e; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }
#toc.toc2 #toctitle { margin-top: 0; margin-bottom: 0.8rem; font-size: 1.2em; }
#toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; }
#toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
body.toc2.toc-right { padding-left: 0; padding-right: 15em; }
body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #1e1e1e; left: auto; right: 0; } }
@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
#toc.toc2 { width: 20em; }
#toc.toc2 #toctitle { font-size: 1.375em; }
#toc.toc2 > ul { font-size: 0.95em; }
#toc.toc2 ul ul { padding-left: 1.25em; }
body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
#content #toc { border-style: solid; border-width: 1px; border-color: black; margin-bottom: 1.25em; padding: 1.25em; background: black; -webkit-border-radius: 8px; border-radius: 8px; }
#content #toc > :first-child { margin-top: 0; }
#content #toc > :last-child { margin-bottom: 0; }
#footer { max-width: none; background: #aaa; padding: 1.25em; }
#footer-text { color: #555555; line-height: 1.44; }
#content { margin-bottom: 0.625em; }
.sect1 { padding-bottom: 0.625em; }
@media only screen and (min-width: 768px) { #content { margin-bottom: 1.25em; }
.sect1 { padding-bottom: 1.25em; } }
.sect1:last-child { padding-bottom: 0; }
.sect1 + .sect1 { border-top: 1px solid #1e1e1e; }
#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > 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; }
#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\00A7"; font-size: 0.85em; display: block; padding-top: 0.1em; }
#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; }
#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #ffa92e; text-decoration: none; }
#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #ff9e15; }
details, .audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; }
details > summary:first-of-type { cursor: pointer; display: list-item; outline: none; margin-bottom: 0.75em; }
.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; font-family: "Comfortaa", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 1rem; font-style: italic; }
table.tableblock.fit-content > caption.title { white-space: nowrap; width: 0; }
.paragraph.lead > p, #preamble > .sectionbody > [class="paragraph"]:first-of-type p { font-size: 1.21875em; line-height: 1.6; color: #ffa92e; }
table.tableblock #preamble > .sectionbody > [class="paragraph"]:first-of-type p { font-size: inherit; }
.admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; }
.admonitionblock > table td.icon { text-align: center; width: 80px; }
.admonitionblock > table td.icon img { max-width: none; }
.admonitionblock > table td.icon .title { font-weight: bold; font-family: "Comfortaa", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; text-transform: uppercase; }
.admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #2b2b2b; color: #aaa; word-wrap: anywhere; }
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: black; margin-bottom: 1.25em; padding: 1.25em; background: #111; -webkit-border-radius: 8px; border-radius: 8px; }
.exampleblock > .content > :first-child { margin-top: 0; }
.exampleblock > .content > :last-child { margin-bottom: 0; }
.sidebarblock { border-style: solid; border-width: 1px; border-color: black; margin-bottom: 1.25em; padding: 1.25em; background: black; -webkit-border-radius: 8px; border-radius: 8px; }
.sidebarblock > :first-child { margin-top: 0; }
.sidebarblock > :last-child { margin-bottom: 0; }
.sidebarblock > .content > .title { color: #e18400; margin-top: 0; text-align: center; }
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
.literalblock pre, .listingblock > .content > pre { border: 1px solid #2e1b00; -webkit-border-radius: 8px; border-radius: 8px; overflow-x: auto; padding: 1em; font-size: 0.8125em; }
@media only screen and (min-width: 768px) { .literalblock pre, .listingblock > .content > pre { font-size: 0.90625em; } }
@media only screen and (min-width: 1280px) { .literalblock pre, .listingblock > .content > pre { font-size: 1em; } }
.literalblock pre, .listingblock > .content > pre:not(.highlight), .listingblock > .content > pre[class="highlight"], .listingblock > .content > pre[class^="highlight "] { background: black; }
.literalblock.output pre { color: black; background-color: #FA9300; }
.listingblock > .content { position: relative; }
.listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: inherit; opacity: 0.5; }
.listingblock:hover code[data-lang]:before { display: block; }
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: inherit; opacity: 0.5; }
.listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; }
.listingblock pre.highlightjs { padding: 0; }
.listingblock pre.highlightjs > code { padding: 1em; -webkit-border-radius: 8px; border-radius: 8px; }
.prettyprint { background: black; }
pre.prettyprint .linenums { line-height: 1.45; margin-left: 2em; }
pre.prettyprint li { background: none; list-style-type: inherit; padding-left: 0; }
pre.prettyprint li code[data-lang]:before { opacity: 1; }
pre.prettyprint li:not(:first-child) code[data-lang]:before { display: none; }
table.linenotable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; }
table.linenotable td[class] { color: inherit; vertical-align: top; padding: 0; line-height: inherit; white-space: normal; }
table.linenotable td.code { padding-left: 0.75em; }
table.linenotable td.linenos { border-right: 1px solid currentColor; opacity: 0.35; padding-right: 0.5em; }
pre.pygments .lineno { border-right: 1px solid currentColor; opacity: 0.35; display: inline-block; margin-right: 0.75em; }
pre.pygments .lineno:before { content: ""; margin-right: -0.125em; }
.quoteblock { margin: 0 1em 1.25em 1.5em; display: table; }
.quoteblock:not(.excerpt) > .title { margin-left: -1.5em; margin-bottom: 0.75em; }
.quoteblock blockquote, .quoteblock p { color: #ffa92e; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; }
.quoteblock blockquote { margin: 0; padding: 0; border: 0; }
.quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #e18400; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); }
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
.quoteblock .attribution { margin-top: 0.75em; margin-right: 0.5ex; text-align: right; }
.verseblock { margin: 0 1em 1.25em 1em; }
.verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #ffa92e; font-weight: 300; text-rendering: optimizeLegibility; }
.verseblock pre strong { font-weight: 400; }
.verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; }
.quoteblock .attribution, .verseblock .attribution { font-size: 0.9375em; line-height: 1.45; font-style: italic; }
.quoteblock .attribution br, .verseblock .attribution br { display: none; }
.quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.025em; color: #aaa; }
.quoteblock.abstract blockquote:before, .quoteblock.excerpt blockquote:before, .quoteblock .quoteblock blockquote:before { display: none; }
.quoteblock.abstract blockquote, .quoteblock.abstract p, .quoteblock.excerpt blockquote, .quoteblock.excerpt p, .quoteblock .quoteblock blockquote, .quoteblock .quoteblock p { line-height: 1.6; word-spacing: 0; }
.quoteblock.abstract { margin: 0 1em 1.25em 1em; display: block; }
.quoteblock.abstract > .title { margin: 0 0 0.375em 0; font-size: 1.15em; text-align: center; }
.quoteblock.excerpt > blockquote, .quoteblock .quoteblock { padding: 0 0 0.25em 1em; border-left: 0.25em solid #2b2b2b; }
.quoteblock.excerpt, .quoteblock .quoteblock { margin-left: 0; }
.quoteblock.excerpt blockquote, .quoteblock.excerpt p, .quoteblock .quoteblock blockquote, .quoteblock .quoteblock p { color: inherit; font-size: 1.0625rem; }
.quoteblock.excerpt .attribution, .quoteblock .quoteblock .attribution { color: inherit; text-align: left; margin-right: 0; }
p.tableblock:last-child { margin-bottom: 0; }
td.tableblock > .content { margin-bottom: 1.25em; word-wrap: anywhere; }
td.tableblock > .content > :last-child { margin-bottom: -1.25em; }
table.tableblock, th.tableblock, td.tableblock { border: 0 solid #613900; }
table.grid-all > * > tr > * { border-width: 1px; }
table.grid-cols > * > tr > * { border-width: 0 1px; }
table.grid-rows > * > tr > * { border-width: 1px 0; }
table.frame-all { border-width: 1px; }
table.frame-ends { border-width: 1px 0; }
table.frame-sides { border-width: 0 1px; }
table.frame-none > colgroup + * > :first-child > *, table.frame-sides > colgroup + * > :first-child > * { border-top-width: 0; }
table.frame-none > :last-child > :last-child > *, table.frame-sides > :last-child > :last-child > * { border-bottom-width: 0; }
table.frame-none > * > tr > :first-child, table.frame-ends > * > tr > :first-child { border-left-width: 0; }
table.frame-none > * > tr > :last-child, table.frame-ends > * > tr > :last-child { border-right-width: 0; }
table.stripes-all tr, table.stripes-odd tr:nth-of-type(odd), table.stripes-even tr:nth-of-type(even), table.stripes-hover tr:hover { background: #040404; }
th.halign-left, td.halign-left { text-align: left; }
th.halign-right, td.halign-right { text-align: right; }
th.halign-center, td.halign-center { text-align: center; }
th.valign-top, td.valign-top { vertical-align: top; }
th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
th.valign-middle, td.valign-middle { vertical-align: middle; }
table thead th, table tfoot th { font-weight: bold; }
tbody tr th { display: table-cell; line-height: 1.6; background: #2e1b00; }
tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #aaa; font-weight: bold; }
p.tableblock > code:only-child { background: none; padding: 0; }
p.tableblock { font-size: 1em; }
ol { margin-left: 1.75em; }
ul li ol { margin-left: 1.5em; }
dl dd { margin-left: 1.125em; }
dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; }
ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.625em; }
ul.checklist, ul.none, ol.none, ul.no-bullet, ol.no-bullet, ol.unnumbered, ul.unstyled, ol.unstyled { list-style-type: none; }
ul.no-bullet, ol.no-bullet, ol.unnumbered { margin-left: 0.625em; }
ul.unstyled, ol.unstyled { margin-left: 0; }
ul.checklist { margin-left: 0.625em; }
ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1.25em; font-size: 0.8em; position: relative; bottom: 0.125em; }
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { margin-right: 0.25em; }
ul.inline { display: -ms-flexbox; display: -webkit-box; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; list-style: none; margin: 0 0 0.625em -1.25em; }
ul.inline > li { margin-left: 1.25em; }
.unstyled dl dt { font-weight: normal; font-style: normal; }
ol.arabic { list-style-type: decimal; }
ol.decimal { list-style-type: decimal-leading-zero; }
ol.loweralpha { list-style-type: lower-alpha; }
ol.upperalpha { list-style-type: upper-alpha; }
ol.lowerroman { list-style-type: lower-roman; }
ol.upperroman { list-style-type: upper-roman; }
ol.lowergreek { list-style-type: lower-greek; }
.hdlist > table, .colist > table { border: 0; background: none; }
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
td.hdlist1, td.hdlist2 { vertical-align: top; padding: 0 0.625em; }
td.hdlist1 { font-weight: bold; padding-bottom: 1.25em; }
td.hdlist2 { word-wrap: anywhere; }
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
.colist td:not([class]):first-child { padding: 0.4em 0.75em 0 0.75em; line-height: 1; vertical-align: top; }
.colist td:not([class]):first-child img { max-width: none; }
.colist td:not([class]):last-child { padding: 0.25em 0; }
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px #fff; -webkit-box-shadow: 0 0 0 1px #ddd; box-shadow: 0 0 0 1px #ddd; }
.imageblock.left { margin: 0.25em 0.625em 1.25em 0; }
.imageblock.right { margin: 0.25em 0 1.25em 0.625em; }
.imageblock > .title { margin-bottom: 0; }
.imageblock.thumb, .imageblock.th { border-width: 6px; }
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
.image.left { margin-right: 0.625em; }
.image.right { margin-left: 0.625em; }
a.image { text-decoration: none; display: inline-block; }
a.image object { pointer-events: none; }
sup.footnote, sup.footnoteref { font-size: 0.875em; position: static; vertical-align: super; }
sup.footnote a, sup.footnoteref a { text-decoration: none; }
sup.footnote a:active, sup.footnoteref a:active { text-decoration: underline; }
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
#footnotes hr { width: 20%; min-width: 6.25em; margin: -0.25em 0 0.75em 0; border-width: 1px 0 0 0; }
#footnotes .footnote { padding: 0 0.375em 0 0.225em; line-height: 1.3334; font-size: 0.875em; margin-left: 1.2em; margin-bottom: 0.2em; }
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; margin-left: -1.05em; }
#footnotes .footnote:last-of-type { margin-bottom: 0; }
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
.gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; }
.gist .file-data > table td.line-data { width: 99%; }
div.unbreakable { page-break-inside: avoid; }
.big { font-size: larger; }
.small { font-size: smaller; }
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.aqua { color: #00bfbf; }
.aqua-background { background-color: #00fafa; }
.black { color: black; }
.black-background { background-color: black; }
.blue { color: #0000bf; }
.blue-background { background-color: #0000fa; }
.fuchsia { color: #bf00bf; }
.fuchsia-background { background-color: #fa00fa; }
.gray { color: #606060; }
.gray-background { background-color: #7d7d7d; }
.green { color: #006000; }
.green-background { background-color: #007d00; }
.lime { color: #00bf00; }
.lime-background { background-color: #00fa00; }
.maroon { color: #600000; }
.maroon-background { background-color: #7d0000; }
.navy { color: #000060; }
.navy-background { background-color: #00007d; }
.olive { color: #606000; }
.olive-background { background-color: #7d7d00; }
.purple { color: #600060; }
.purple-background { background-color: #7d007d; }
.red { color: #bf0000; }
.red-background { background-color: #fa0000; }
.silver { color: #909090; }
.silver-background { background-color: #bcbcbc; }
.teal { color: #006060; }
.teal-background { background-color: #007d7d; }
.white { color: #bfbfbf; }
.white-background { background-color: #fafafa; }
.yellow { color: #bfbf00; }
.yellow-background { background-color: #fafa00; }
span.icon > .fa { cursor: default; }
a span.icon > .fa { cursor: inherit; }
.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 0px 0px 5px #c77500; cursor: default; }
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #bc6e00; }
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; }
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; }
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; }
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; }
.conum[data-value] { display: inline-block; color: #fff !important; background-color: #aaa; -webkit-border-radius: 50%; border-radius: 50%; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; }
.conum[data-value] * { color: #fff !important; }
.conum[data-value] + b { display: none; }
.conum[data-value]:after { content: attr(data-value); }
pre .conum[data-value] { position: relative; top: -0.125em; }
b.conum * { color: inherit !important; }
.conum:not([data-value]):empty { display: none; }
dt, th.tableblock, td.content, div.footnote { text-rendering: optimizeLegibility; }
h1, h2, p, td.content, span.alt { letter-spacing: -0.01em; }
p strong, td.content strong, div.footnote strong { letter-spacing: -0.005em; }
strong { text-shadow: 0px 0px 2px; }
p, blockquote, dt, td.content, span.alt { font-size: 1.0625rem; }
p { margin-bottom: 1.25rem; }
.sidebarblock p, .sidebarblock dt, .sidebarblock td.content, p.tableblock { font-size: 1em; }
.exampleblock > .content { border-color: #2e1b00; -moz-box-shadow: 0 1px 4px #2e1b00; -webkit-box-shadow: 0 1px 4px #2e1b00; box-shadow: 0 1px 4px #2e1b00; }
.admonitionblock .icon .title { font-size: 2.5em; text-shadow: 0px 0px 5px #c77500; }
.caution .icon .title { color: #6610f2; }
.important .icon .title { color: #e74c3c; }
.note .icon .title { color: #3498db; }
.tip .icon .title { color: #00bc8c; }
.warning .icon .title { color: #f39c12; }
pre.pygments { background: #000 !important; }
.literalblock pre, .listingblock > .content > pre { font-size: 0.875em; }
@media only screen and (min-width: 768px) { .literalblock pre, .listingblock > .content > pre { font-size: 0.875em; } }
@media only screen and (min-width: 1280px) { .literalblock pre, .listingblock > .content > pre { font-size: 0.875em; } }
.literalblock pre, .listingblock > .content > pre { background: black !important; }
.sidebarblock { border-color: #2e1b00; }
a { color: inherit; }
#header .details { color: #c77500; }
#toc { scrollbar-width: none; scrollbar-color: #613900 transparent; }
#toc:hover { scrollbar-width: thin; scrollbar-color: #c77500 #2e1b00; }
#toc::-webkit-scrollbar { width: 0px; }
#toc::-webkit-scrollbar-thumb { background: #613900; }
#toc::-webkit-scrollbar-track { background: transparent; }
#toc:hover::-webkit-scrollbar { width: 6px; }
#toc:hover::-webkit-scrollbar-thumb { background: #c77500; }
#toc:hover::-webkit-scrollbar-track { background: #2e1b00; }
.print-only { display: none !important; }
@page { margin: 1.25cm 0.75cm; }
@media print { * { -moz-box-shadow: none !important; -webkit-box-shadow: none !important; box-shadow: none !important; text-shadow: none !important; }
html { font-size: 80%; }
a { color: inherit !important; text-decoration: underline !important; }
a.bare, a[href^="#"], a[href^="mailto:"] { text-decoration: none !important; }
a[href^="http:"]:not(.bare):after, a[href^="https:"]:not(.bare):after { content: "(" attr(href) ")"; display: inline-block; font-size: 0.875em; padding-left: 0.25em; }
abbr[title]:after { content: " (" attr(title) ")"; }
pre, blockquote, tr, img, object, svg { page-break-inside: avoid; }
thead { display: table-header-group; }
svg { max-width: 100%; }
p, blockquote, dt, td.content { font-size: 1em; orphans: 3; widows: 3; }
h2, h3, #toctitle, .sidebarblock > .content > .title, #toctitle, .sidebarblock > .content > .title { page-break-after: avoid; }
#header, #content, #footnotes, #footer { max-width: none; }
#toc, .sidebarblock, .exampleblock > .content { background: none !important; }
#toc { border-bottom: 1px solid #2b2b2b !important; padding-bottom: 0 !important; }
body.book #header { text-align: center; }
body.book #header > h1:first-child { border: 0 !important; margin: 2.5em 0 1em 0; }
body.book #header .details { border: 0 !important; display: block; padding: 0 !important; }
body.book #header .details span:first-child { margin-left: 0 !important; }
body.book #header .details br { display: block; }
body.book #header .details br + span:before { content: none !important; }
body.book #toc { border: 0 !important; text-align: left !important; padding: 0 !important; margin: 0 !important; }
body.book #toc, body.book #preamble, body.book h1.sect0, body.book .sect1 > h2 { page-break-before: always; }
.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 0 !important; }
.listingblock code[data-lang]:before { display: block; }
#footer { padding: 0 0.9375em; }
.hide-on-print { display: none !important; }
.print-only { display: block !important; }
.hide-for-print { display: none !important; }
.show-for-print { display: inherit !important; } }
@media print, amzn-kf8 { #header > h1:first-child { margin-top: 1.25rem; }
.sect1 { padding: 0 !important; }
.sect1 + .sect1 { border: 0; }
#footer { background: none; }
#footer-text { color: #aaa; font-size: 0.9em; } }
@media amzn-kf8 { #header, #content, #footnotes, #footer { padding: 0; } }
.menubar { position: fixed; display: block; top: 0px; left: 0px; right: 0px; background-color: black; border-bottom: 1px solid #2e1b00; padding: 10px; text-align: center; }
.menubar p { margin: 0px; }
.menubar image { padding-right: 1em; }
.menubar-item { padding-left: 1em; }
@media print { .menubar { display: none; } }

View File

@@ -0,0 +1,473 @@
[[bbv2.arch]]
B2 v2 architecture
---------------------------
This document is work-in progress. Do not expect much from it yet.
[[bbv2.arch.overview]]
Overview
--------
B2 implementation is structured in four different components:
"kernel", "util", "build" and "tools". The first two are relatively
uninteresting, so we will focus on the remaining pair. The "build"
component provides classes necessary to declare targets, determining
which properties should be used for their building, and creating the
dependency graph. The "tools" component provides user-visible
functionality. It mostly allows declaring specific kinds of main
targets, as well as registering available tools, which are then used
when creating the dependency graph.
[[bbv2.arch.build]]
The build layer
---------------
The build layer has just four main parts -- metatargets (abstract
targets), virtual targets, generators and properties.
* Metatargets (see the "targets.jam" module) represent all the
user-defined entities that can be built. The "meta" prefix signifies
that they do not need to correspond to exact files or even files at all
-- they can produce a different set of files depending on the build
request. Metatargets are created when Jamfiles are loaded. Each has a
`generate` method which is given a property set and produces virtual
targets for the passed properties.
* Virtual targets (see the "virtual-targets.jam" module) correspond to
actual atomic updatable entities -- most typically files.
* Properties are just (name, value) pairs, specified by the user and
describing how targets should be built. Properties are stored using the
`property-set` class.
* Generators are objects that encapsulate specific tools -- they can
take a list of source virtual targets and produce new virtual targets
from them.
The build process includes the following steps:
1. Top-level code calls the `generate` method of a metatarget with some
properties.
2. The metatarget combines the requested properties with its
requirements and passes the result, together with the list of sources,
to the `generators.construct` function.
3. A generator appropriate for the build properties is selected and its
`run` method is called. The method returns a list of virtual targets.
4. The virtual targets are returned to the top level code, and for each
instance, the `actualize` method is called to setup nodes and updating
actions in the dependency graph kept inside B2 engine. This
dependency graph is then updated, which runs necessary commands.
[[bbv2.arch.build.metatargets]]
Metatargets
~~~~~~~~~~~
There are several classes derived from "abstract-target". The
"main-target" class represents a top-level main target, the
"project-target" class acts like a container holding multiple main
targets, and "basic-target" class is a base class for all further target
types.
Since each main target can have several alternatives, all top-level
target objects are actually containers, referring to "real" main target
classes. The type of that container is "main-target". For example,
given:
....
alias a ;
lib a : a.cpp : <toolset>gcc ;
....
we would have one-top level "main-target" instance, containing one
"alias-target" and one "lib-target" instance. "main-target"'s "generate"
method decides which of the alternative should be used, and calls
"generate" on the corresponding instance.
Each alternative is an instance of a class derived from "basic-target".
"basic-target.generate" does several things that should always be done:
* Determines what properties should be used for building the target.
This includes looking at requested properties, requirements, and usage
requirements of all sources.
* Builds all sources.
* Computes usage requirements that should be passed back to targets
depending on this one.
For the real work of constructing a virtual target, a new method
"construct" is called.
The "construct" method can be implemented in any way by classes derived
from "basic-target", but one specific derived class plays the central
role -- "typed-target". That class holds the desired type of file to be
produced, and its "construct" method uses the generators module to do
the actual work.
This means that a specific metatarget subclass may avoid using
generators all together. However, this is deprecated and we are trying
to eliminate all such subclasses at the moment.
Note that the `build/targets.jam` file contains an UML diagram which
might help.
[[bbv2.arch.build.virtual]]
Virtual targets
~~~~~~~~~~~~~~~
Virtual targets are atomic updatable entities. Each virtual target can
be assigned an updating action -- instance of the `action` class. The
action class, in turn, contains a list of source targets, properties,
and a name of an action which should be executed.
We try hard to never create equal instances of the `virtual-target`
class. Code creating virtual targets passes them though the
`virtual-target.register` function, which detects if a target with the
same name, sources, and properties has already been created. In that
case, the preexisting target is returned.
When all virtual targets are produced, they are "actualized". This means
that the real file names are computed, and the commands that should be
run are generated. This is done by the `virtual-target.actualize` and
`action.actualize` methods. The first is conceptually simple, while the
second needs additional explanation. Commands in B2 are
generated in a two-stage process. First, a rule with an appropriate name
(for example "gcc.compile") is called and is given a list of target
names. The rule sets some variables, like "OPTIONS". After that, the
command string is taken, and variable are substitutes, so use of OPTIONS
inside the command string gets transformed into actual compile options.
B2 added a third stage to simplify things. It is now possible
to automatically convert properties to appropriate variable assignments.
For example, <debug-symbols>on would add "-g" to the OPTIONS variable,
without requiring to manually add this logic to gcc.compile. This
functionality is part of the "toolset" module.
Note that the `build/virtual-targets.jam` file contains an UML diagram
which might help.
[[bbv2.arch.build.properties]]
Properties
~~~~~~~~~~
Above, we noted that metatargets are built with a set of properties.
That set is represented by the `property-set` class. An important point
is that handling of property sets can get very expensive. For that
reason, we make sure that for each set of (name, value) pairs only one
`property-set` instance is created. The `property-set` uses extensive
caching for all operations, so most work is avoided. The
`property-set.create` is the factory function used to create instances
of the `property-set` class.
[[bbv2.arch.tools]]
The tools layer
---------------
Write me!
[[bbv2.arch.targets]]
Targets
-------
NOTE: THIS SECTION IS NOT EXPECTED TO BE READ! There are two
user-visible kinds of targets in B2. First are "abstract" —
they correspond to things declared by the user, e.g. projects and
executable files. The primary thing about abstract targets is that it is
possible to request them to be built with a particular set of
properties. Each property combination may possibly yield different built
files, so abstract target do not have a direct correspondence to built
files.
File targets, on the other hand, are associated with concrete files.
Dependency graphs for abstract targets with specific properties are
constructed from file targets. User has no way to create file targets
but can specify rules for detecting source file types, as well as rules
for transforming between file targets of different types. That
information is used in constructing the final dependency graph, as
described in the link:#bbv2.arch.depends[next section]. **Note:**File
targets are not the same entities as Jam targets; the latter are created
from file targets at the latest possible moment. *Note:*"File target" is
an originally proposed name for what we now call virtual targets. It is
more understandable by users, but has one problem: virtual targets can
potentially be "phony", and not correspond to any file.
[[bbv2.arch.depends]]
Dependency scanning
-------------------
Dependency scanning is the process of finding implicit dependencies,
like "#include" statements in {CPP}. The requirements for correct
dependency scanning mechanism are:
* link:#bbv2.arch.depends.different-scanning-algorithms[Support for
different scanning algorithms]. {CPP} and XML have quite different syntax
for includes and rules for looking up the included files.
* link:#bbv2.arch.depends.same-file-different-scanners[Ability to scan
the same file several times]. For example, a single {CPP} file may be
compiled using different include paths.
* link:#bbv2.arch.depends.dependencies-on-generated-files[Proper
detection of dependencies on generated files.]
* link:#bbv2.arch.depends.dependencies-from-generated-files[Proper
detection of dependencies from a generated file.]
[[bbv2.arch.depends.different-scanning-algorithms]]
Support for different scanning algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Different scanning algorithm are encapsulated by objects called
"scanners". Please see the "scanner" module documentation for more
details.
[[bbv2.arch.depends.same-file-different-scanners]]
Ability to scan the same file several times
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As stated above, it is possible to compile a {CPP} file multiple times,
using different include paths. Therefore, include dependencies for those
compilations can be different. The problem is that B2 engine
does not allow multiple scans of the same target. To solve that, we pass
the scanner object when calling `virtual-target.actualize` and it
creates different engine targets for different scanners.
For each engine target created with a specified scanner, a corresponding
one is created without it. The updating action is associated with the
scanner-less target, and the target with the scanner is made to depend
on it. That way if sources for that action are touched, all targets —
with and without the scanner are considered outdated.
Consider the following example: "a.cpp" prepared from "a.verbatim",
compiled by two compilers using different include paths and copied into
some install location. The dependency graph would look like:
....
a.o (<toolset>gcc) <--(compile)-- a.cpp (scanner1) ----+
a.o (<toolset>msvc) <--(compile)-- a.cpp (scanner2) ----|
a.cpp (installed copy) <--(copy) ----------------------- a.cpp (no scanner)
^
|
a.verbose --------------------------------+
....
[[bbv2.arch.depends.dependencies-on-generated-files]]
Proper detection of dependencies on generated files.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This requirement breaks down to the following ones.
1. If when compiling "a.cpp" there is an include of "a.h", the "dir"
directory is on the include path, and a target called "a.h" will be
generated in "dir", then B2 should discover the include, and
create "a.h" before compiling "a.cpp".
2. Since B2 almost always generates targets under the "bin"
directory, this should be supported as well. I.e. in the scenario above,
Jamfile in "dir" might create a main target, which generates "a.h". The
file will be generated to "dir/bin" directory, but we still have to
recognize the dependency.
The first requirement means that when determining what "a.h" means when
found in "a.cpp", we have to iterate over all directories in include
paths, checking for each one:
1. If there is a file named "a.h" in that directory, or
2. If there is a target called "a.h", which will be generated in that
that directory.
Classic Jam has built-in facilities for point (1) above, but that is not
enough. It is hard to implement the right semantics without builtin
support. For example, we could try to check if there exists a target
called "a.h" somewhere in the dependency graph, and add a dependency to
it. The problem is that without a file search in the include path, the
semantics may be incorrect. For example, one can have an action that
generated some "dummy" header, for systems which do not have a native
one. Naturally, we do not want to depend on that generated header on
platforms where a native one is included.
There are two design choices for builtin support. Suppose we have files
a.cpp and b.cpp, and each one includes header.h, generated by some
action. Dependency graph created by classic Jam would look like:
....
a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
<d2>header.h --------> header.y
[generated in d2]
b.cpp -----> <scanner2>header.h [search path: d1, d2, d4]
....
In this case, Jam thinks all header.h target are not related. The
correct dependency graph might be:
....
a.cpp ----
\
>----> <d2>header.h --------> header.y
/ [generated in d2]
b.cpp ----
....
or
....
a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
|
(includes)
V
<d2>header.h --------> header.y
[generated in d2]
^
(includes)
|
b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4]
....
The first alternative was used for some time. The problem however is:
what include paths should be used when scanning header.h? The second
alternative was suggested by Matt Armstrong. It has a similar effect:
Any target depending on <scanner1>header.h will also depend on
<d2>header.h. This way though we now have two different targets with two
different scanners, so those targets can be scanned independently. The
first alternative's problem is avoided, so the second alternative is
implemented now.
The second sub-requirements is that targets generated under the "bin"
directory are handled as well. B2 implements a semi-automatic
approach. When compiling {CPP} files the process is:
1. The main target to which the compiled file belongs to is found.
2. All other main targets that the found one depends on are found.
These include: main targets used as sources as well as those specified
as "dependency" properties.
3. All directories where files belonging to those main targets will be
generated are added to the include path.
After this is done, dependencies are found by the approach explained
previously.
Note that if a target uses generated headers from another main target,
that main target should be explicitly specified using the dependency
property. It would be better to lift this requirement, but it does not
seem to be causing any problems in practice.
For target types other than {CPP}, adding of include paths must be
implemented anew.
[[bbv2.arch.depends.dependencies-from-generated-files]]
Proper detection of dependencies from generated files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose file "a.cpp" includes "a.h" and both are generated by some
action. Note that classic Jam has two stages. In the first stage the
dependency graph is built and actions to be run are determined. In the
second stage the actions are executed. Initially, neither file exists,
so the include is not found. As the result, Jam might attempt to compile
a.cpp before creating a.h, causing the compilation to fail.
The solution in Boost.Jam is to perform additional dependency scans
after targets are updated. This breaks separation between build stages
in Jam — which some people consider a good thing — but I am not aware of
any better solution.
In order to understand the rest of this section, you better read some
details about Jam's dependency scanning, available at
http://public.perforce.com:8080/@md=d&cd=//public/jam/src/&ra=s&c=kVu@//2614?ac=10[this
link].
Whenever a target is updated, Boost.Jam rescans it for includes.
Consider this graph, created before any actions are run.
....
A -------> C ----> C.pro
/
B --/ C-includes ---> D
....
Both A and B have dependency on C and C-includes (the latter dependency
is not shown). Say during building we have tried to create A, then tried
to create C and successfully created C.
In that case, the set of includes in C might well have changed. We do
not bother to detect precisely which includes were added or removed.
Instead we create another internal node C-includes-2. Then we determine
what actions should be run to update the target. In fact this means that
we perform the first stage logic when already in the execution stage.
After actions for C-includes-2 are determined, we add C-includes-2 to
the list of A's dependents, and stage 2 proceeds as usual.
Unfortunately, we can not do the same with target B, since when it is
not visited, C target does not know B depends on it. So, we add a flag
to C marking it as rescanned. When visiting the B target, the flag is
noticed and C-includes-2 is added to the list of B's dependencies as
well.
Note also that internal nodes are sometimes updated too. Consider this
dependency graph:
....
a.o ---> a.cpp
a.cpp-includes --> a.h (scanned)
a.h-includes ------> a.h (generated)
|
|
a.pro <-------------------------------------------+
....
Here, our handling of generated headers come into play. Say that a.h
exists but is out of date with respect to "a.pro", then "a.h
(generated)" and "a.h-includes" will be marked for updating, but "a.h
(scanned)" will not. We have to rescan "a.h" after it has been created,
but since "a.h (generated)" has no associated scanner, it is only
possible to rescan "a.h" after "a.h-includes" target has been updated.
The above consideration lead to the decision to rescan a target whenever
it is updated, no matter if it is internal or not.
________________________________________________________________________________________________________
*Warning*
The remainder of this document is not intended to be read at all. This
will be rearranged in the future.
________________________________________________________________________________________________________
File targets
------------
As described above, file targets correspond to files that B2
manages. Users may be concerned about file targets in three ways: when
declaring file target types, when declaring transformations between
types and when determining where a file target is to be placed. File
targets can also be connected to actions that determine how the target
is to be created. Both file targets and actions are implemented in the
`virtual-target` module.
Types
~~~~~
A file target can be given a type, which determines what transformations
can be applied to the file. The `type.register` rule declares new types.
File type can also be assigned a scanner, which is then used to find
implicit dependencies. See "link:#bbv2.arch.depends[dependency
scanning]".
Target paths
~~~~~~~~~~~~
To distinguish targets build with different properties, they are put in
different directories. Rules for determining target paths are given
below:
1. All targets are placed under a directory corresponding to the
project where they are defined.
2. Each non free, non incidental property causes an additional element
to be added to the target path. That element has the the form
`<feature-name>-<feature-value>` for ordinary features and
`<feature-value>` for implicit ones. [TODO: Add note about composite
features].
3. If the set of free, non incidental properties is different from the
set of free, non incidental properties for the project in which the main
target that uses the target is defined, a part of the form
`main_target-<name>` is added to the target path. **Note:**It would be
nice to completely track free features also, but this appears to be
complex and not extremely needed.
For example, we might have these paths:
....
debug/optimization-off
debug/main-target-a
....

View File

@@ -0,0 +1,40 @@
.admonitionblock .icon .title {
font-size: 2.5em;
text-shadow: 1px 1px 2px rgba(0, 0, 0, .5);
}
.caution .icon .title {
color: rgba(192, 51, 0, 1);
}
.important .icon .title {
color: rgba(192, 0, 0, 1);
}
.note .icon .title {
color: rgba(26, 64, 128, 1);
}
.tip .icon .title {
color: rgba(255, 192, 0, 1);
}
.warning .icon .title {
color: rgba(192, 102, 0, 1);
}
p,blockquote,dt,td.content,span.alt {
font-size: 1.1rem
}
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
}
h1 {
font-size: 2.25em;
}
h2 {
font-size: 1.5em;
}
h3,#toctitle,.sidebarblock>.content>.title {
font-size: 1.3em;
}
h4, h5 {
font-size: 1.2em;
}
h6 {
font-size: 1.1em;
}

View File

@@ -0,0 +1,50 @@
[[bbv2.reference.class.basic-target]]
= Class basic-target
[source]
----
class basic-target : abstract-target {
rule __init__ ( name : project : sources * : requirements * : default-build * : usage-requirements * )
rule generate ( property-set )
rule construct ( name : source-targets * : property-set )
# Methods inherited from abstract-target
rule name ( )
rule project ( )
rule location ( )
rule full-name ( )
}
----
Implements the most standard way of constructing main target alternative
from sources. Allows sources to be either files or other main targets
and handles generation of those dependency targets.
--
1. `rule __init__ ( name : project : sources * : requirements * : default-build * : usage-requirements * )`
+
`name`::
The name of the target
`project`::
The link:#bbv2.reference.class.project-target[project] in which the
target is declared.
2. [[bbv2.reference.class.basic-target.generate]] `rule generate ( property-set )`
+
Overrides
link:#bbv2.reference.class.abstract-target.generate[abstract-target.generate].
Determines final build properties, generates sources, and calls
link:#bbv2.reference.class.basic-target.construct[construct]. This
method should not be overridden.
+
On success, returns:
+
* a property-set with the usage requirements to be applied to dependents
* a list of produced virtual targets, which may be empty.
3. [[bbv2.reference.class.basic-target.construct]] `rule construct ( name : source-targets * : property-set )`
+
Constructs virtual targets for this abstract target. Returns a
usage-requirements property-set and a list of virtual targets. Should be
overridden in derived classes.
--

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
[[bbv2.util]]
= Utilities
[[bbv2.util.debugger]]
== Debugger
[[bbv2.util.debugger.overview]]
=== Overview
B2 comes with a debugger for Jamfiles. To run the debugger,
start B2 with `b2 -dconsole`.
....
$ b2 -dconsole
(b2db) break gcc.init
Breakpoint 1 set at gcc.init
(b2db) run
Starting program: /usr/bin/b2
Breakpoint 1, gcc.init ( ) at /usr/share/boost-build/tools/gcc.jam:74
74 local tool-command = ;
(b2db) quit
....
[[bbv2.util.debugger.running]]
=== Running the Program
The `run` command is used to start a new `b2` subprocess for debugging.
The arguments to `run` are passed on the command line. If a child
process is already running, it will be terminated before the new child
is launched.
When the program is paused `continue` will resume execution. The `step`
command will advance the program by a single statement, stopping on
entry to another function or return from the current function. `next` is
like `step` except that it skips over function calls. `finish` executes
until the current function returns.
The `kill` command terminates the current child immediately.
[[bbv2.util.debugger.break]]
=== Breakpoints
Breakpoints are set using the `break` command. The location of the
breakpoint can be specified as either the name of a function (including
the module name) or or a file name and line number of the form
`file:line`. When a breakpoint is created it is given a unique id which
is used to identify it for other commands.
....
(b2db) break Jamfile:10
Breakpoint 1 set at Jamfile:10
(b2db) break msvc.init
Breakpoint 2 set at msvc.init
....
A breakpoint can be temporarily disabled using the `disable` command.
While a breakpoint is disabled, the child will not stop when it is hit.
A disabled breakpoint can be activated again with `enable`.
....
(b2db) disable 1
(b2db) enable 1
....
Breakpoints can be removed permanently with `delete` or `clear`. The
difference between them is that `delete` takes the breakpoint id while
`clear` takes the location of the breakpoint as originally specified to
break.
....
(b2db) clear Jamfile:10
Deleted breakpoint 1
(b2db) delete 2
....
[[bbv2.util.debugger.stack]]
=== Examining the Stack
The `backtrace` command will print a summary of every frame on the
stack.
The `print` command can be used to show the value of an expression.
....
(b2db) print [ modules.peek : ARGV ]
/usr/bin/b2 toolset=msvc install
(b2db) print $(__file__)
Jamfile.jam
....
[[bbv2.util.debugger.misc]]
=== Miscellaneous Commands
`quit` exits the debugger. `help` describes the available commands.

View File

@@ -0,0 +1,18 @@
= Examples
== Introduction
Here we include a collection of simple to complex fully working examples of
using Boost Build v2 for various tasks. They show the gamut from simple
to advanced features. If you find yourself looking at the examples and not
finding something you want to see working please post to our support list
and we'll try and come up with a solution and add it here for others to learn
from.
:leveloffset: +1
include::../../example/hello/readme.adoc[]
include::../../example/sanitizers/readme.adoc[]
:leveloffset: -1

View File

@@ -0,0 +1,863 @@
[[bbv2.extender]]
= Extender Manual
[[bbv2.extender.intro]]
== Introduction
This section explains how to extend B2 to accommodate your local
requirements -- primarily to add support for non-standard tools you
have. Before we start, be sure you have read and understood the concept
of metatarget, <<bbv2.overview.concepts>>, which is critical to
understanding the remaining material.
The current version of B2 has three levels of targets, listed
below.
metatarget::
Object that is created from declarations in Jamfiles. May be called
with a set of properties to produce concrete targets.
concrete target::
Object that corresponds to a file or an action.
jam target::
Low-level concrete target that is specific to Boost.Jam build engine.
Essentially a string -- most often a name of file.
In most cases, you will only have to deal with concrete targets and the
process that creates concrete targets from metatargets. Extending
metatarget level is rarely required. The jam targets are typically only
used inside the command line patterns.
WARNING: All of the Boost.Jam target-related builtin functions, like
`DEPENDS` or `ALWAYS` operate on jam targets. Applying them to metatargets or
concrete targets has no effect.
[[bbv2.extender.overview.metatargets]]
=== Metatargets
Metatarget is an object that records information specified in Jamfile,
such as metatarget kind, name, sources and properties, and can be called
with specific properties to generate concrete targets. At the code level
it is represented by an instance of class derived from
link:#bbv2.reference.class.abstract-target[abstract-target].
footnote:[This name is historic, and will be eventually changed to
`metatarget`]
The link:#bbv2.reference.class.abstract-target.generate[generate] method
takes the build properties (as an instance of the
link:#bbv2.reference.class.property-set[property-set] class) and returns
a list containing:
* As front element -- Usage-requirements from this invocation (an
instance of link:#bbv2.reference.class.property-set[property-set])
* As subsequent elements -- created concrete targets ( instances of the
`virtual-target` class.)
It's possible to lookup a metatarget by target-id using the
`targets.resolve-reference` function, and the
`targets.generate-from-reference` function can both lookup and generate
a metatarget.
The link:#bbv2.reference.class.abstract-target[abstract-target] class
has three immediate derived classes:
* link:#bbv2.reference.class.project-target[project-target] that
corresponds to a project and is not intended for further subclassing.
The link:#bbv2.reference.class.project-target.generate[generate] method
of this class builds all targets in the project that are not marked as
explicit.
* link:#bbv2.reference.class.main-target[main-target] corresponds to a
target in a project and contains one or more target alternatives. This
class also should not be subclassed. The
link:#bbv2.reference.class.main-target.generate[generate] method of this
class selects an alternative to build, and calls the
link:#bbv2.reference.class.basic-target.generate[generate] method of
that alternative.
* link:#bbv2.reference.class.basic-target[basic-target] corresponds to a
specific target alternative. This is base class, with a number of
derived classes. The
link:#bbv2.reference.class.basic-target.generate[generate] method
processes the target requirements and requested build properties to
determine final properties for the target, builds all sources, and
finally calls the abstract
link:#bbv2.reference.class.basic-target.construct[construct] method with
the list of source virtual targets, and the final properties.
The instances of the
link:#bbv2.reference.class.project-target[project-target] and
link:#bbv2.reference.class.main-target[main-target] classes are created
implicitly -- when loading a new Jamfiles, or when a new target
alternative with as-yet unknown name is created. The instances of the
classes derived from
link:#bbv2.reference.class.basic-target[basic-target] are typically
created when Jamfile calls a metatarget rule, such as such as `exe`.
It it permissible to create a custom class derived from
link:#bbv2.reference.class.basic-target[basic-target] and create new
metatarget rule that creates instance of such target. However, in the
majority of cases, a specific subclass of
link:#bbv2.reference.class.basic-target[basic-target] --
link:#bbv2.reference.class.typed-target[typed-target] is used. That
class is associated with a type and relays to generators to construct
concrete targets of that type. This process will be explained below.
When a new type is declared, a new metatarget rule is automatically
defined. That rule creates new instance of type-target, associated with
that type.
[[bbv2.extender.overview.targets]]
=== Concrete targets
Concrete targets are represented by instance of classes derived from
`virtual-target`. The most commonly used subclass is `file-target`. A
file target is associated with an action that creates it -- an
instance of the `action` class. The action, in turn, hold a list of
source targets. It also holds the
link:#bbv2.reference.class.property-set[property-set] instance with the
build properties that should be used for the action.
Here's an example of creating a target from another target, `source`
[source,jam]
----
local a = [ new action $(source) : common.copy : $(property-set) ] ;
local t = [ new file-target $(name) : CPP : $(project) : $(a) ] ;
----
The first line creates an instance of the `action` class. The first
parameter is the list of sources. The second parameter is the name a
jam-level link:#bbv2.overview.jam_language.actions[action]. The third
parameter is the property-set applying to this action. The second line
creates a target. We specify a name, a type and a project. We also pass
the action object created earlier. If the action creates several
targets, we can repeat the second line several times.
In some cases, code that creates concrete targets may be invoked more
than once with the same properties. Returning two different instances of
`file-target` that correspond to the same file clearly will result in
problems. Therefore, whenever returning targets you should pass them via
the `virtual-target.register` function, besides allowing B2 to
track which virtual targets got created for each metatarget, this will
also replace targets with previously created identical ones, as
necessary.footnote:[This create-then-register pattern is caused by
limitations of the Boost.Jam language. Python port is likely to never
create duplicate targets.] Here are a couple of examples:
[source,jam]
----
return [ virtual-target.register $(t) ] ;
return [ sequence.transform virtual-target.register : $(targets) ] ;
----
[[bbv2.extender.overview.generators]]
=== Generators
In theory, every kind of metatarget in B2 (like `exe`, `lib` or
`obj`) could be implemented by writing a new metatarget class that,
independently of the other code, figures what files to produce and what
commands to use. However, that would be rather inflexible. For example,
adding support for a new compiler would require editing several
metatargets.
In practice, most files have specific types, and most tools consume and
produce files of specific type. To take advantage of this fact,
B2 defines concept of target type and generators generators,
and has special metatarget class
link:#bbv2.reference.class.typed-target[typed-target]. Target type is
merely an identifier. It is associated with a set of file extensions
that correspond to that type. Generator is an abstraction of a tool. It
advertises the types it produces and, if called with a set of input
target, tries to construct output targets of the advertised types.
Finally, link:#bbv2.reference.class.typed-target[typed-target] is
associated with specific target type, and relays the generator (or
generators) for that type.
A generator is an instance of a class derived from `generator`. The
`generator` class itself is suitable for common cases. You can define
derived classes for custom scenarios.
[[bbv2.extender.example]]
== Example: 1-to-1 generator
Say you're writing an application that generates {CPP} code. If you ever
did this, you know that it's not nice. Embedding large portions of {CPP}
code in string literals is very awkward. A much better solution is:
1. Write the template of the code to be generated, leaving placeholders
at the points that will change
2. Access the template in your application and replace placeholders
with appropriate text.
3. Write the result.
It's quite easy to achieve. You write special verbatim files that are
just {CPP}, except that the very first line of the file contains the name
of a variable that should be generated. A simple tool is created that
takes a verbatim file and creates a cpp file with a single `char*`
variable whose name is taken from the first line of the verbatim file
and whose value is the file's properly quoted content.
Let's see what B2 can do.
First off, B2 has no idea about "verbatim files". So, you must
register a new target type. The following code does it:
[source,jam]
----
import type ;
type.register VERBATIM : verbatim ;
----
The first parameter to
link:#bbv2.reference.modules.type.register[type.register] gives the name
of the declared type. By convention, it's uppercase. The second
parameter is the suffix for files of this type. So, if B2 sees
`code.verbatim` in a list of sources, it knows that it's of type
`VERBATIM`.
Next, you tell B2 that the verbatim files can be transformed
into {CPP} files in one build step. A generator is a template for a build
step that transforms targets of one type (or set of types) into another.
Our generator will be called `verbatim.inline-file`; it transforms
`VERBATIM` files into `CPP` files:
[source,jam]
----
import generators ;
generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
----
Lastly, you have to inform B2 about the shell commands used to
make that transformation. That's done with an `actions` declaration.
[source,jam]
----
actions inline-file
{
"./inline-file.py" $(<) $(>)
}
----
Now, we're ready to tie it all together. Put all the code above in file
`verbatim.jam`, add `import verbatim ;` to `Jamroot.jam`, and it's
possible to write the following in your Jamfile:
[source,jam]
----
exe codegen : codegen.cpp class_template.verbatim usage.verbatim ;
----
The listed verbatim files will be automatically converted into {CPP}
source files, compiled and then linked to the `codegen` executable.
In subsequent sections, we will extend this example, and review all the
mechanisms in detail. The complete code is available in the
`example/customization` directory.
[[bbv2.extending.targets]]
== Target types
The first thing we did in the link:#bbv2.extender.intro[introduction]
was declaring a new target type:
[source,jam]
----
import type ;
type.register VERBATIM : verbatim ;
----
The type is the most important property of a target. B2 can
automatically generate necessary build actions only because you specify
the desired type (using the different main target rules), and because
B2 can guess the type of sources from their extensions.
The first two parameters for the `type.register` rule are the name of
new type and the list of extensions associated with it. A file with an
extension from the list will have the given target type. In the case
where a target of the declared type is generated from other sources, the
first specified extension will be used.
Sometimes you want to change the suffix used for generated targets
depending on build properties, such as toolset. For example, some
compiler uses extension `elf` for executable files. You can use the
`type.set-generated-target-suffix` rule:
[source,jam]
----
type.set-generated-target-suffix EXE : <toolset>elf : elf ;
----
A new target type can be inherited from an existing one.
[source,jam]
----
type.register PLUGIN : : SHARED_LIB ;
----
The above code defines a new type derived from `SHARED_LIB`. Initially,
the new type inherits all the properties of the base type - in
particular generators and suffix. Typically, you'll change the new type
in some way. For example, using `type.set-generated-target-suffix` you
can set the suffix for the new type. Or you can write a special
generator for the new type. For example, it can generate additional
meta-information for the plugin. In either way, the `PLUGIN` type can be
used whenever `SHARED_LIB` can. For example, you can directly link
plugins to an application.
A type can be defined as "main", in which case B2 will
automatically declare a main target rule for building targets of that
type. More details can be found
link:#bbv2.extending.rules.main-type[later].
[[bbv2.extending.scanners]]
== Scanners
Sometimes, a file can refer to other files via some include system. To
make B2 track dependencies between included files, you need to
provide a scanner. The primary limitation is that only one scanner can
be assigned to a target type.
First, we need to declare a new class for the scanner:
[source,jam]
----
class verbatim-scanner : common-scanner
{
rule pattern ( )
{
return "//###include[ ]*\"([^\"]*)\"" ;
}
}
----
All the complex logic is in the `common-scanner` class, and you only
need to override the method that returns the regular expression to be
used for scanning. The parentheses in the regular expression indicate
which part of the string is the name of the included file. Only the
first parenthesized group in the regular expression will be recognized;
if you can't express everything you want that way, you can return
multiple regular expressions, each of which contains a parenthesized
group to be matched.
After that, we need to register our scanner class:
[source,jam]
----
scanner.register verbatim-scanner : include ;
----
The value of the second parameter, in this case `include`, specifies the
properties that contain the list of paths that should be searched for
the included files.
Finally, we assign the new scanner to the `VERBATIM` target type:
[source,jam]
----
type.set-scanner VERBATIM : verbatim-scanner ;
----
That's enough for scanning include dependencies.
[[bbv2.extending.tools]]
== Tools and generators
This section will describe how B2 can be extended to support
new tools.
For each additional tool, a B2 object called generator must be
created. That object has specific types of targets that it accepts and
produces. Using that information, B2 is able to automatically
invoke the generator. For example, if you declare a generator that takes
a target of the type `D` and produces a target of the type `OBJ`, when
placing a file with extension `.d` in a list of sources will cause
B2 to invoke your generator, and then to link the resulting
object file into an application. (Of course, this requires that you
specify that the `.d` extension corresponds to the `D` type.)
Each generator should be an instance of a class derived from the
`generator` class. In the simplest case, you don't need to create a
derived class, but simply create an instance of the `generator` class.
Let's review the example we've seen in the
link:#bbv2.extender.intro[introduction].
[source,jam]
----
import generators ;
generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
actions inline-file
{
"./inline-file.py" $(<) $(>)
}
----
We declare a standard generator, specifying its id, the source type and
the target type. When invoked, the generator will create a target of
type `CPP` with a source target of type `VERBATIM` as the only source.
But what command will be used to actually generate the file? In
B2, actions are specified using named "actions" blocks and the
name of the action block should be specified when creating targets. By
convention, generators use the same name of the action block as their
own id. So, in above example, the "inline-file" actions block will be
used to convert the source into the target.
There are two primary kinds of generators: standard and composing, which
are registered with the `generators.register-standard` and the
`generators.register-composing` rules, respectively. For example:
[source,jam]
----
generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
generators.register-composing mex.mex : CPP LIB : MEX ;
----
The first (standard) generator takes a _single_ source of type
`VERBATIM` and produces a result. The second (composing) generator takes
any number of sources, which can have either the `CPP` or the `LIB`
type. Composing generators are typically used for generating top-level
target type. For example, the first generator invoked when building an
`exe` target is a composing generator corresponding to the proper
linker.
You should also know about two specific functions for registering
generators: `generators.register-c-compiler` and
`generators.register-linker`. The first sets up header dependency
scanning for C files, and the seconds handles various complexities like
searched libraries. For that reason, you should always use those
functions when adding support for compilers and linkers.
(Need a note about UNIX)
*Custom generator classes*
The standard generators allows you to specify source and target types,
an action, and a set of flags. If you need anything more complex, you
need to create a new generator class with your own logic. Then, you have
to create an instance of that class and register it. Here's an example
how you can create your own generator class:
[source,jam]
----
class custom-generator : generator
{
rule __init__ ( * : * )
{
generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
}
}
generators.register
[ new custom-generator verbatim.inline-file : VERBATIM : CPP ] ;
----
This generator will work exactly like the `verbatim.inline-file`
generator we've defined above, but it's possible to customize the
behavior by overriding methods of the `generator` class.
There are two methods of interest. The `run` method is responsible for
the overall process - it takes a number of source targets, converts them
to the right types, and creates the result. The `generated-targets`
method is called when all sources are converted to the right types to
actually create the result.
The `generated-targets` method can be overridden when you want to add
additional properties to the generated targets or use additional
sources. For a real-life example, suppose you have a program analysis
tool that should be given a name of executable and the list of all
sources. Naturally, you don't want to list all source files manually.
Here's how the `generated-targets` method can find the list of sources
automatically:
[source,jam]
----
class itrace-generator : generator {
...
rule generated-targets ( sources + : property-set : project name ? )
{
local leaves ;
local temp = [ virtual-target.traverse $(sources[1]) : : include-sources ] ;
for local t in $(temp)
{
if ! [ $(t).action ]
{
leaves += $(t) ;
}
}
return [ generator.generated-targets $(sources) $(leafs)
: $(property-set) : $(project) $(name) ] ;
}
}
generators.register [ new itrace-generator nm.itrace : EXE : ITRACE ] ;
----
The `generated-targets` method will be called with a single source
target of type `EXE`. The call to `virtual-target.traverse` will return
all targets the executable depends on, and we further find files that
are not produced from anything. The found targets are added to the
sources.
The `run` method can be overridden to completely customize the way the
generator works. In particular, the conversion of sources to the desired
types can be completely customized. Here's another real example. Tests
for the Boost Python library usually consist of two parts: a Python
program and a {CPP} file. The {CPP} file is compiled to Python extension
that is loaded by the Python program. But in the likely case that both
files have the same name, the created Python extension must be renamed.
Otherwise, the Python program will import itself, not the extension.
Here's how it can be done:
[source,jam]
----
rule run ( project name ? : property-set : sources * )
{
local python ;
for local s in $(sources)
{
if [ $(s).type ] = PY
{
python = $(s) ;
}
}
local libs ;
for local s in $(sources)
{
if [ type.is-derived [ $(s).type ] LIB ]
{
libs += $(s) ;
}
}
local new-sources ;
for local s in $(sources)
{
if [ type.is-derived [ $(s).type ] CPP ]
{
local name = [ $(s).name ] ; # get the target's basename
if $(name) = [ $(python).name ]
{
name = $(name)_ext ; # rename the target
}
new-sources += [ generators.construct $(project) $(name) :
PYTHON_EXTENSION : $(property-set) : $(s) $(libs) ] ;
}
}
result = [ construct-result $(python) $(new-sources) : $(project) $(name)
: $(property-set) ] ;
}
----
First, we separate all source into python files, libraries and {CPP}
sources. For each {CPP} source we create a separate Python extension by
calling `generators.construct` and passing the {CPP} source and the
libraries. At this point, we also change the extension's name, if
necessary.
[[bbv2.extending.features]]
== Features
Often, we need to control the options passed the invoked tools. This is
done with features. Consider an example:
[source,jam]
----
# Declare a new free feature
import feature : feature ;
feature verbatim-options : : free ;
# Cause the value of the 'verbatim-options' feature to be
# available as 'OPTIONS' variable inside verbatim.inline-file
import toolset : flags ;
flags verbatim.inline-file OPTIONS <verbatim-options> ;
# Use the "OPTIONS" variable
actions inline-file
{
"./inline-file.py" $(OPTIONS) $(<) $(>)
}
----
We first define a new feature. Then, the `flags` invocation says that
whenever verbatim.inline-file action is run, the value of the
`verbatim-options` feature will be added to the `OPTIONS` variable, and
can be used inside the action body. You'd need to consult online help
(--help) to find all the features of the `toolset.flags` rule.
Although you can define any set of features and interpret their values
in any way, B2 suggests the following coding standard for
designing features.
Most features should have a fixed set of values that is portable (tool
neutral) across the class of tools they are designed to work with. The
user does not have to adjust the values for a exact tool. For example,
`<optimization>speed` has the same meaning for all {CPP} compilers and the
user does not have to worry about the exact options passed to the
compiler's command line.
Besides such portable features there are special 'raw' features that
allow the user to pass any value to the command line parameters for a
particular tool, if so desired. For example, the `<cxxflags>` feature
allows you to pass any command line options to a {CPP} compiler. The
`<include>` feature allows you to pass any string preceded by `-I` and
the interpretation is tool-specific. (See <<bbv2.faq.external>>
for an example of very smart usage of that feature). Of course one
should always strive to use portable features, but these are still be
provided as a backdoor just to make sure B2 does not take away
any control from the user.
Using portable features is a good idea because:
* When a portable feature is given a fixed set of values, you can build
your project with two different settings of the feature and B2
will automatically use two different directories for generated files.
B2 does not try to separate targets built with different raw
options.
* Unlike with “raw” features, you don't need to use specific
command-line flags in your Jamfile, and it will be more likely to work
with other tools.
*Steps for adding a feature*
Adding a feature requires three steps:
1. Declaring a feature. For that, the "feature.feature" rule is used.
You have to decide on the set of
link:#bbv2.reference.features.attributes[feature attributes]:
* if you want a feature value set for one target to automatically
propagate to its dependent targets then make it “propagated”.
* if a feature does not have a fixed list of values, it must be “free.”
For example, the `include` feature is a free feature.
* if a feature is used to refer to a path relative to the Jamfile, it
must be a “path” feature. Such features will also get their values
automatically converted to B2's internal path representation.
For example, `include` is a path feature.
* if feature is used to refer to some target, it must be a “dependency”
feature.
2. Representing the feature value in a target-specific variable. Build
actions are command templates modified by Boost.Jam variable expansions.
The `toolset.flags` rule sets a target-specific variable to the value of
a feature.
3. Using the variable. The variable set in step 2 can be used in a
build action to form command parameters or files.
*Another example*
Here's another example. Let's see how we can make a feature that refers
to a target. For example, when linking dynamic libraries on Windows, one
sometimes needs to specify a "DEF file", telling what functions should
be exported. It would be nice to use this file like this:
[source,jam]
----
lib a : a.cpp : <def-file>a.def ;
----
Actually, this feature is already supported, but anyway...
1. Since the feature refers to a target, it must be "dependency".
+
----
feature def-file : : free dependency ;
----
2. One of the toolsets that cares about DEF files is msvc. The
following line should be added to it.
+
----
flags msvc.link DEF_FILE <def-file> ;
----
3. Since the DEF_FILE variable is not used by the msvc.link action, we
need to modify it to be:
+
----
actions link bind DEF_FILE
{
$(.LD) .... /DEF:$(DEF_FILE) ....
}
----
+
Note the `bind DEF_FILE` part. It tells B2 to translate the
internal target name in `DEF_FILE` to a corresponding filename in the
`link` action. Without it the expansion of `$(DEF_FILE)` would be a
strange symbol that is not likely to make sense for the linker.
+
We are almost done, except for adding the following code to `msvc.jam`:
+
----
rule link
{
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}
----
+
This is a workaround for a bug in B2 engine, which will
hopefully be fixed one day.
*Variants and composite features.*
Sometimes you want to create a shortcut for some set of features. For
example, `release` is a value of `<variant>` and is a shortcut for a set
of features.
It is possible to define your own build variants. For example:
[source,jam]
----
variant crazy : <optimization>speed <inlining>off
<debug-symbols>on <profiling>on ;
----
will define a new variant with the specified set of properties. You can
also extend an existing variant:
[source,jam]
----
variant super_release : release : <define>USE_ASM ;
----
In this case, `super_release` will expand to all properties specified by
`release`, and the additional one you've specified.
You are not restricted to using the `variant` feature only. Here's
example that defines a brand new feature:
[source,jam]
----
feature parallelism : mpi fake none : composite link-incompatible ;
feature.compose <parallelism>mpi : <library>/mpi//mpi/<parallelism>none ;
feature.compose <parallelism>fake : <library>/mpi//fake/<parallelism>none ;
----
This will allow you to specify the value of feature `parallelism`, which
will expand to link to the necessary library.
[[bbv2.extending.rules]]
== Main target rules
A main target rule (e.g “link:#bbv2.tasks.programs[exe]” Or
“link:#bbv2.tasks.libraries[lib]”) creates a top-level target. It's
quite likely that you'll want to declare your own and there are two ways
to do that.
[[bbv2.extending.rules.main-type]]The first way applies when your target rule
should just produce a target
of specific type. In that case, a rule is already defined for you! When
you define a new type, B2 automatically defines a corresponding
rule. The name of the rule is obtained from the name of the type, by
down-casing all letters and replacing underscores with dashes. For
example, if you create a module `obfuscate.jam` containing:
[source,jam]
----
import type ;
type.register OBFUSCATED_CPP : ocpp ;
import generators ;
generators.register-standard obfuscate.file : CPP : OBFUSCATED_CPP ;
----
and import that module, you'll be able to use the rule "obfuscated-cpp"
in Jamfiles, which will convert source to the OBFUSCATED_CPP type.
The second way is to write a wrapper rule that calls any of the existing
rules. For example, suppose you have only one library per directory and
want all cpp files in the directory to be compiled into that library.
You can achieve this effect using:
[source,jam]
----
lib codegen : [ glob *.cpp ] ;
----
If you want to make it even simpler, you could add the following
definition to the `Jamroot.jam` file:
[source,jam]
----
rule glib ( name : extra-sources * : requirements * )
{
lib $(name) : [ glob *.cpp ] $(extra-sources) : $(requirements) ;
}
----
allowing you to reduce the Jamfile to just
[source,jam]
----
glib codegen ;
----
Note that because you can associate a custom generator with a target
type, the logic of building can be rather complicated. For example, the
`boostbook` module declares a target type `BOOSTBOOK_MAIN` and a custom
generator for that type. You can use that as example if your main target
rule is non-trivial.
[[bbv2.extending.toolset_modules]]
== Toolset modules
If your extensions will be used only on one project, they can be placed
in a separate `.jam` file and imported by your `Jamroot.jam`. If the
extensions will be used on many projects, users will thank you for a
finishing touch.
The `using` rule provides a standard mechanism for loading and
configuring extensions. To make it work, your module should provide an
`init` rule. The rule will be called with the same parameters that were
passed to the `using` rule. The set of allowed parameters is determined
by you. For example, you can allow the user to specify paths, tool
versions, and other options.
Here are some guidelines that help to make B2 more consistent:
* The `init` rule should never fail. Even if the user provided an
incorrect path, you should emit a warning and go on. Configuration may
be shared between different machines, and wrong values on one machine
can be OK on another.
* Prefer specifying the command to be executed to specifying the tool's
installation path. First of all, this gives more control: it's possible
to specify
+
----
/usr/bin/g++-snapshot
time g++
----
+
as the command. Second, while some tools have a logical "installation
root", it's better if the user doesn't have to remember whether a
specific tool requires a full command or a path.
* Check for multiple initialization. A user can try to initialize the
module several times. You need to check for this and decide what to do.
Typically, unless you support several versions of a tool, duplicate
initialization is a user error. If the tool's version can be specified
during initialization, make sure the version is either always specified,
or never specified (in which case the tool is initialized only once). For
example, if you allow:
+
----
using yfc ;
using yfc : 3.3 ;
using yfc : 3.4 ;
----
+
Then it's not clear if the first initialization corresponds to version
3.3 of the tool, version 3.4 of the tool, or some other version. This
can lead to building twice with the same version.
* If possible, `init` must be callable with no parameters. In which
case, it should try to autodetect all the necessary information, for
example, by looking for a tool in PATH or in common installation
locations. Often this is possible and allows the user to simply write:
+
----
using yfc ;
----
* Consider using facilities in the `tools/common` module. You can take a
look at how `tools/gcc.jam` uses that module in the `init` rule.

View File

@@ -0,0 +1,404 @@
[[bbv2.faq]]
= Frequently Asked Questions
[[bbv2.faq.featurevalue]]
== How do I get the current value of feature in Jamfile?
This is not possible, since Jamfile does not have "current" value of any
feature, be it toolset, build variant or anything else. For a single run
of B2, any given main target can be built with several property
sets. For example, user can request two build variants on the command
line. Or one library is built as shared when used from one application,
and as static when used from another. Each Jamfile is read only once so
generally there is no single value of a feature you can access in
Jamfile.
A feature has a specific value only when building a target, and there
are two ways you can use that value:
* Use conditional requirements or indirect conditional requirements. See
link:#bbv2.overview.targets.requirements.conditional[the section called “Requirements”].
* Define a custom generator and a custom main target type. The custom
generator can do arbitrary processing or properties. See the
link:#bbv2.extender[extender manual]
[[bbv2.faq.duplicate]]
== I am getting a "Duplicate name of actual target" error. What does that mean?
The most likely case is that you are trying to compile the same file
twice, with almost the same, but differing properties. For example:
[source,jam]
----
exe a : a.cpp : <include>/usr/local/include ;
exe b : a.cpp ;
----
The above snippet requires two different compilations of `a.cpp`, which
differ only in their `include` property. Since the `include` feature is
declared as `free` B2 does not create a separate build
directory for each of its values and those two builds would both produce
object files generated in the same build directory. Ignoring this and
compiling the file only once would be dangerous as different includes
could potentially cause completely different code to be compiled.
To solve this issue, you need to decide if the file should be compiled
once or twice.
1. To compile the file only once, make sure that properties are the
same for both target requests:
+
[source,jam]
----
exe a : a.cpp : <include>/usr/local/include ;
exe b : a.cpp : <include>/usr/local/include ;
----
+
or:
+
[source,jam]
----
alias a-with-include : a.cpp : <include>/usr/local/include ;
exe a : a-with-include ;
exe b : a-with-include ;
----
+
or if you want the `includes` property not to affect how any other
sources added for the built `a` and `b` executables would be compiled:
+
[source,jam]
----
obj a-obj : a.cpp : <include>/usr/local/include ;
exe a : a-obj ;
exe b : a-obj ;
----
+
Note that in both of these cases the `include` property will be applied
only for building these object files and not any other sources that
might be added for targets `a` and `b`.
2. To compile the file twice, you can tell B2 to compile it to
two separate object files like so:
+
[source,jam]
----
obj a_obj : a.cpp : <include>/usr/local/include ;
obj b_obj : a.cpp ;
exe a : a_obj ;
exe b : b_obj ;
----
+
or you can make the object file targets local to the main target:
+
[source,jam]
----
exe a : [ obj a_obj : a.cpp : <include>/usr/local/include ] ;
exe b : [ obj a_obj : a.cpp ] ;
----
+
which will cause B2 to actually change the generated object
file names a bit for you and thus avoid any conflicts.
+
Note that in both of these cases the `include` property will be applied
only for building these object files and not any other sources that
might be added for targets `a` and `b`.
A good question is why B2 can not use some of the above
approaches automatically. The problem is that such magic would only help
in half of the cases, while in the other half it would be silently doing
the wrong thing. It is simpler and safer to ask the user to clarify his
intention in such cases.
[[bbv2.faq.envar]]
== Accessing environment variables
Many users would like to use environment variables in Jamfiles, for
example, to control the location of external libraries. In many cases it
is better to declare those external libraries in the site-config.jam
file, as documented in the link:#bbv2.recipes.site-config[recipes
section]. However, if the users already have the environment variables
set up, it may not be convenient for them to set up their
site-config.jam files as well and using the environment variables might
be reasonable.
Boost.Jam automatically imports all environment variables into its
built-in .ENVIRON module so user can read them from there directly or by
using the helper os.environ rule. For example:
[source,jam]
----
import os ;
local unga-unga = [ os.environ UNGA_UNGA ] ;
ECHO $(unga-unga) ;
----
or a bit more realistic:
[source,jam]
----
import os ;
local SOME_LIBRARY_PATH = [ os.environ SOME_LIBRARY_PATH ] ;
exe a : a.cpp : <include>$(SOME_LIBRARY_PATH) ;
----
[[bbv2.faq.proporder]]
== How to control properties order?
For internal reasons, B2 sorts all the properties
alphabetically. This means that if you write:
[source,jam]
----
exe a : a.cpp : <include>b <include>a ;
----
then the command line with first mention the `a` include directory, and
then `b`, even though they are specified in the opposite order. In most
cases, the user does not care. But sometimes the order of includes, or
other properties, is important. For such cases, a special syntax is
provided:
[source,jam]
----
exe a : a.cpp : <include>a&&b ;
----
The `&&` symbols separate property values and specify that their order
should be preserved. You are advised to use this feature only when the
order of properties really matters and not as a convenient shortcut.
Using it everywhere might negatively affect performance.
[[bbv2.faq.liborder]]
== How to control the library linking order on Unix?
On Unix-like operating systems, the order in which static libraries are
specified when invoking the linker is important, because by default, the
linker uses one pass though the libraries list. Passing the libraries in
the incorrect order will lead to a link error. Further, this behavior
is often used to make one library override symbols from another. So,
sometimes it is necessary to force specific library linking order.
B2 tries to automatically compute the right order. The primary
rule is that if library `a` "uses" library `b`, then library `a` will
appear on the command line before library `b`. Library `a` is considered
to use `b` if `b` is present either in the `a` library's sources or its
usage is listed in its requirements. To explicitly specify the `use`
relationship one can use the `<use>` feature. For example, both of the
following lines will cause `a` to appear before `b` on the command line:
[source,jam]
----
lib a : a.cpp b ;
lib a : a.cpp : <use>b ;
----
The same approach works for searched libraries as well:
[source,jam]
----
lib z ;
lib png : : <use>z ;
exe viewer : viewer png z ;
----
[[bbv2.faq.external]]
== Can I get capture external program output using a Boost.Jam variable?
The `SHELL` builtin rule may be used for this purpose:
[source,jam]
----
local gtk_includes = [ SHELL "gtk-config --cflags" ] ;
----
[[bbv2.faq.projectroot]]
== How to get the project root (a.k.a. Jamroot) location?
You might want to use your project's root location in your Jamfiles. To
access it just declare a path constant in your `Jamroot.jam` file using:
[source,jam]
----
path-constant TOP : . ;
----
After that, the `TOP` variable can be used in every Jamfile.
[[bbv2.faq.flags]]
== How to change compilation flags for one file?
If one file must be compiled with special options, you need to
explicitly declare an `obj` target for that file and then use that
target in your `exe` or `lib` target:
[source,jam]
----
exe a : a.cpp b ;
obj b : b.cpp : <optimization>off ;
----
Of course you can use other properties, for example to specify specific
C/{CPP} compiler options:
[source,jam]
----
exe a : a.cpp b ;
obj b : b.cpp : <cflags>-g ;
----
You can also use link:#bbv2.tutorial.conditions[conditional properties]
for finer control:
[source,jam]
----
exe a : a.cpp b ;
obj b : b.cpp : <variant>release:<optimization>off ;
----
[[bbv2.faq.dll-path]]
== Why are the `dll-path` and `hardcode-dll-paths` properties useful?
NOTE: This entry is specific to Unix systems.
Before answering the questions, let us recall a few points about shared
libraries. Shared libraries can be used by several applications, or
other libraries, without physically including the library in the
application which can greatly decrease the total application size. It is
also possible to upgrade a shared library when the application is
already installed.
However, in order for application depending on shared libraries to be
started the OS may need to find the shared library when the application
is started. The dynamic linker will search in a system-defined list of
paths, load the library and resolve the symbols. Which means that you
should either change the system-defined list, given by the
`LD_LIBRARY_PATH` environment variable, or install the libraries to a
system location. This can be inconvenient when developing, since the
libraries are not yet ready to be installed, and cluttering system paths
may be undesirable. Luckily, on Unix there is another way.
An executable can include a list of additional library paths, which will
be searched before system paths. This is excellent for development
because the build system knows the paths to all libraries and can
include them in the executables. That is done when the
`hardcode-dll-paths` feature has the `true` value, which is the default.
When the executables should be installed, the story is different.
Obviously, installed executable should not contain hardcoded paths to
your development tree. (The `install` rule explicitly disables the
`hardcode-dll-paths` feature for that reason.) However, you can use the
`dll-path` feature to add explicit paths manually. For example:
[source,jam]
----
install installed : application : <dll-path>/usr/lib/snake
<location>/usr/bin ;
----
will allow the application to find libraries placed in the
`/usr/lib/snake` directory.
If you install libraries to a nonstandard location and add an explicit
path, you get more control over libraries which will be used. A library
of the same name in a system location will not be inadvertently used. If
you install libraries to a system location and do not add any paths, the
system administrator will have more control. Each library can be
individually upgraded, and all applications will use the new library.
Which approach is best depends on your situation. If the libraries are
relatively standalone and can be used by third party applications, they
should be installed in the system location. If you have lots of
libraries which can be used only by your application, it makes sense to
install them to a nonstandard directory and add an explicit path, like
the example above shows. Please also note that guidelines for different
systems differ in this respect. For example, the Debian GNU guidelines
prohibit any additional search paths while Solaris guidelines suggest
that they should always be used.
[[bbv2.recipes.site-config]]
== Targets in site-config.jam
It is desirable to declare standard libraries available on a given
system. Putting target declaration in a specific project's Jamfile is
not really good, since locations of the libraries can vary between
different development machines and then such declarations would need to
be duplicated in different projects. The solution is to declare the
targets in B2's `site-config.jam` configuration file:
[source,jam]
----
project site-config ;
lib zlib : : <name>z ;
----
Recall that both `site-config.jam` and `user-config.jam` are projects,
and everything you can do in a Jamfile you can do in those files as
well. So, you declare a project id and a target. Now, one can write:
[source,jam]
----
exe hello : hello.cpp /site-config//zlib ;
----
in any Jamfile.
[[bbv2.faq.header-only-libraries]]
== Header-only libraries
In modern {CPP}, libraries often consist of just header files, without any
source files to compile. To use such libraries, you need to add proper
includes and possibly defines to your project. But with a large number
of external libraries it becomes problematic to remember which libraries
are header only, and which ones you have to link to. However, with
B2 a header-only library can be declared as B2 target
and all dependents can use such library without having to remember
whether it is a header-only library or not.
Header-only libraries may be declared using the `alias` rule, specifying
their include path as a part of its usage requirements, for example:
[source,jam]
----
alias my-lib
: # no sources
: # no build requirements
: # no default build
: <include>whatever ;
----
The includes specified in usage requirements of `my-lib` are
automatically added to all of its dependents build properties. The
dependents need not care if `my-lib` is a header-only or not, and it is
possible to later make `my-lib` into a regular compiled library without
having to add the includes to its dependents declarations.
If you already have proper usage requirements declared for a project
where a header-only library is defined, you do not need to duplicate
them for the `alias` target:
[source,jam]
----
project my : usage-requirements <include>whatever ;
alias mylib ;
----
[[bbv2.faq.names]]
== What is the difference between B2, `b2`, `bjam` and Perforce Jam?
B2 is the name of the complete build system. The executable
that runs it is `b2`. That executable is written in C and implements
performance-critical algorithms, like traversal of dependency graph and
executing commands. It also implements an interpreted language used to
implement the rest of B2. This executable is formally called
"B2 engine".
The B2 engine is derived from an earlier build tool called
Perforce Jam. Originally, there were just minor changes, and the
filename was `bjam`. Later on, with more and more changes, the
similarity of names became a disservice to users, and as of Boost
1.47.0, the official name of the executable was changed to `b2`. A copy
named `bjam` is still created for compatibility, but you are encouraged
to use the new name in all cases.
Perforce Jam was an important foundation, and we gratefully acknowledge
its influence, but for users today, these tools share only some basics
of the interpreted language.

View File

@@ -0,0 +1,30 @@
[[root_option]]
root
Specifies root directory of the compiler installation. This option is
necessary only if it is not possible to detect this information from the
compiler command—for example if the specified compiler command is a user
script.
[[common_options]]
cflags
Specifies additional compiler flags that will be used when compiling C
sources.
cxxflags
Specifies additional compiler flags that will be used when compiling {CPP}
sources.
compileflags
Specifies additional compiler flags that will be used when compiling
both C and {CPP} sources.
linkflags
Specifies additional command line options that will be passed to the
linker.

View File

@@ -0,0 +1,382 @@
[[b2.history]]
= History
== Version 4.7.2
* Fix errors configuring intel-linux toolset if icpx is not in the PATH but
icpc is in the PATH.
-- _Mark E. Hamilton_
* Add `cxxstd=20` to msvc toolset now that VS 2019 onward supports it.
-- _Peter Dimov_
== Version 4.7.1
* Fix regression for linking with `clang-win` toolset.
-- _Peter Dimov_
== Version 4.7.0
Many, many fixes and internal cleanups in this release. But also adding
auto-detection and bootstrap for VS 2022 preview toolset.
* *New:* Add vc143, aka VS2022, aka cl.exe 17.x toolset support. Includes
building engine and automatic detection of the prerelease toolset.
-- _Sergei Krivonos_
* Allow alias targets to continue even if `<build>no` is in the usage
requirement. Which allows composition of alias targets that may contain
optional targets, like tests.
-- _Dmitry Arkhipov_
* Fix use of `JAMSHELL` in gcc toolset.
-- _René Ferdinand Rivera Morell_
* Fix compiling b2 enging such that it works when run in cross-architecture
emulation context. I.e. when running arm binaries in QEMU 64 bit host.
-- _René Ferdinand Rivera Morell_
* Default to 64bit MSVC on 64 bit hosts.
-- _Matt Chambers_
* Remove `/NOENTRY` option for resource only DLLs to allow correct linking.
-- _gnaggnoyil_
* Fix redefinition error of `unix` when compiling engine on OpenBSD.
-- _Brad Smith_
* Fix building with clang on iOS and AppleTV having extra unrecognized
compiler options.
-- _Konstantin Ivlev_
* Add missing Boost.JSON to `boost` support module.
-- _Dmitry Arkhipov_
* Add arm/arm64 target support in clang-win toolset.
-- _Volo Zyko_
* Avoid warnings about threading model for qt5.
-- _psandana_
* Unify Clang and GCC PCH creation.
-- _Nikita Kniazev_
* Move Objective-C support to GCC toolset.
-- _Nikita Kniazev_
* Support values for instruction-set feature for Xilinx ZYNQ.
-- _Thomas Brown_
* MIPS: add generic mips architecture.
-- _YunQiang Su_
* Fix preprocessing on MSVC compiler.
-- _Nikita Kniazev_
== Version 4.6.1
* Fix building b2 engine with cygwin64.
-- _René Ferdinand Rivera Morell_
* Fix version detection of clang toolset from compiler exec.
-- _Nikita Kniazev_
== Version 4.6.0
This release wraps up a few new features that make using some toolsets easier
(thanks to Nikita). It's now also possible to specify empty flags features on
the command line, like `cxxfalgs=`, and have those be ignored. This helps to
make CI scripts shorter as they don't need to handle those cases specially.
And as usual there are many bug fixes and adjustments. Thanks to everyone who
contributed to this release.
* *New:* Allow clang toolset to be auto-configured to a specific version by using
`toolset=clang-xx` on the command line.
-- _Nikita Kniazev_
* *New:* Include pch header automatically and on-demand on gcc and msvc toolset to
mirror clang functionality.
-- _Nikita Kniazev_
* *New:* Features that are narked as 'free' and 'optional' will now be ignored when
the value specified on the command line is empty. Hence once can specify
`cxxflags=` on the command line without errors.
-- _René Ferdinand Rivera Morell_
* Preserve `bootstrap.sh` invoke arguments to forward to the `build.sh` script.
-- _tkoecker_
* Remove use of `local` in `buils.sh` to be compatible with some, not fully
capable, shells.
-- _Tanzinul Islam_
* Workaround shell array ref error in `build.sh` on busybox shells.
-- _tkoecker_
* Check for needing `-pthread` to build engine with gcc on some platforms.
-- _tkoecker_
* Default to using clang on MacOS.
-- _Stéphan Kochen_
* Add `/python//numpy` target to use as a dependency to communicate version
specific properties.
-- _Peter Dimov_
* Add default value for cxx and cxxflags from env vars `CXX` and `CXXFLAGS`
when using the custom `cxx` toolset to build the engine.
-- _Samuel Debionne_ and _René Ferdinand Rivera Morell_
* Fix detection of `intel-linux` toolset installation when only the compiler
executable is in the `PATH`.
-- _René Ferdinand Rivera Morell_
* Fix `b2` executable path determination for platforms that don't have a
native method of getting the path to executables, like OpenBSD.
-- _René Ferdinand Rivera Morell_
* Fix `property.find` error message.
-- _Thomas Brown_
== Version 4.5.0
Some minor fixes to improve some old issues.
* Reenable ability of generators to return `property-set` as first item.
-- _Andrew McCann_
* Fix examples to return 0 on success.
-- _Mateusz Łoskot_
* Handle spaces in CXX path in `config_toolset.bat`.
* Fix Conan b2 generator link, and pkg-config doc build error.
-- _René Ferdinand Rivera Morell_
== Version 4.4.2
This release is the first of the new home for B2 at Build Frameworks Group.
* Change references in documentation and sources of boost.org to point
at equivalent bfgroup resources.
-- _René Ferdinand Rivera Morell_
* New theme for B2 site and documentation.
-- _René Ferdinand Rivera Morell_
== Version 4.4.1
Minor patch to correct missing fix for macOS default engine compiler.
* Fix engine build defaulting to gcc instead of clang on macOS/Xcode.
-- _René Ferdinand Rivera Morell_
== Version 4.4.0
Along with a variety of fixes this version introduces "dynamic" response file
support for some toolsets. This means that under most circumstances, if
supported by the toolset, response files are not generated. Instead the
command is expanded to include the options directly.
* *New:* Add `response-file` feature to control the kind of response file usage in
toolset action.
-- _René Ferdinand Rivera Morell_
* *New:* Add `:O=value` variable modifier for `@()` expansion.
-- _René Ferdinand Rivera Morell_
* *New:* Add `:<=value` and `:>=value` variable modifiers for prefix and postfix
values *after* the complete expansion of variable references.
-- _René Ferdinand Rivera Morell_
* *New:* Implement PCH on clang-win and clang-darwin.
-- _Nikita Kniazev_
* *New:* Add support for Intel oneAPI release to intel-linux toolset.
-- _René Ferdinand Rivera Morell_
* *New:* Add support for Intel oneAPI release to intel-windows toolset.
-- _Edward Diener_
* Remove one at time linking limit. Once upon a time this was a performance
tweak as hardware and software was not up to doing multiple links at once.
Common setups are better equipped.
-- _René Ferdinand Rivera Morell_
* Fix building engine with GCC on AIX.
-- _René Ferdinand Rivera Morell_
* Support building engine as either 32 or 64 bit addressing model.
-- _René Ferdinand Rivera Morell_
* Basic support for building b2 engine on GNU/Hurd.
-- _Pino Toscano_
* Update "borland" toolset to bcc32c for building B2.
-- _Tanzinul Islam_
* Ensure Embarcadero toolset name is only "embtc".
-- _Tanzinul Islam_
* Adapt for Emscripten 2.0 change of default behavior for archives.
-- _Basil Fierz_
* Fix path to bootstrap for back compat.
-- _René Ferdinand Rivera Morell_
* Add missing BOOST_ROOT to boot strap search.
-- _René Ferdinand Rivera Morell_
* Fix for engine compile on FreeBSD.
-- _René Ferdinand Rivera Morell_
* Default MSVC to a native platform, and remove ambiguous implicit
address-model ARM/ARM64 values.
-- _Nikita Kniazev_
* Fix detection of MIPS32 for b2 engine build.
-- _Ivan Melnikov_
* Enable building b2 engine with clang on Windows.
-- _Gei0r_
* Fix building b2 engine with Intel Linux icpc.
-- _Alain Miniussi_
* Rework `build.sh` to fix many bugs and to avoid use of common env vars.
-- _René Ferdinand Rivera Morell_
* Remove limitation of relevant features for configure checks.
-- _René Ferdinand Rivera Morell_
* Reformat configure check output to inform the variants of the checks in a
reasonably brief form.
-- _René Ferdinand Rivera Morell_
* Support building engine on Windows Bash with Mingw.
-- _René Ferdinand Rivera Morell_
== Version 4.3.0
There are many invidual fixes in this release. Many thanks for the
contributions. Special thanks to Nikita for the many improvements to msvc
and general plugging of support holes in all the compilers.
There are some notable new features from Dmitry, Edward, and Nkita:
* *New:* Add `force-include` feature to include headers before all sources.
-- _Nikita Kniazev_
* *New:* Partial support for Embarcadero C++ compilers based on clang-5.
-- _Edward Diener_
* *New:* Implement configurable installation prefixes that use features.
-- _Dmitry Arkhipov_
* *New:* Add `translate-path` feature. The translate-path feature allows for
custom path handling, with a provided rule, on a per target basis. This can
be used to support custom path syntax.
-- _René Ferdinand Rivera Morell_
* *New:* Add portable B2 system install option. This allows the b2 executable
and the build system files to live side by side. And hence to be (re)located
anywhere on disk. Soon to be used to supports Windows and other installers.
This removes the need for the `boost-build.jam` file for bootstrap. Making
it easier for users to get started.
-- _René Ferdinand Rivera Morell_
* Unbreak building from VS Preview command prompt.
-- _Marcel Raad_
* Fix compiler version check on macOS darwin toolset.
-- _Bo Anderson_
* Remove pch target naming restriction on GCC.
-- _Nikita Kniazev_
* Select appropriate QNX target platform.
-- _Alexander Karzhenkov_
* Various space & performance improvements to the b2 engine build on Windows.
-- _Nikita Kniazev_
* Fill extra and pedantic warning options for every compiler.
-- _Nikita Kniazev_
* Include OS error reason for engine IO failures.
-- _Nikita Kniazev_
* Use /Zc:inline and /Zc:throwingNew flags for better language conformance.
-- _Nikita Kniazev_
* Add cxxstd value 20 for C++20.
-- _Andrey Semashev_
* Parallel B2 engine compilation on MSVC.
-- _Nikita Kniazev_
* Updated instruction-set feature with new x86 targets.
-- _Andrey Semashev_
* Pass /nologo to rc on Windows compilers.
-- _Nikita Kniazev_
* Fixed negation in conditional properties.
-- _Nikita Kniazev_
* Remove leftover manifest generation early exiting.
-- _Nikita Kniazev_
* Fix timestamp delta calculation.
-- _Nikita Kniazev_
* Add missing assembler options to clang-win.jam, to enable Context to build.
-- _Peter Dimov_
* Updated scarce `:chars` documentation with `:BS` example.
-- _Nikita Kniazev_
* Fix link statically against boost-python on linux.
-- _Joris Carrier_
* Ongoing cleanup of engine build warnings.
-- _René Ferdinand Rivera Morell_
* Allow self-testing of toolsets that use response files.
-- _René Ferdinand Rivera Morell_
* Port `Jambase` to native C++. Hence removing one of the oldest parts of the
original Jam bootstrap process.
-- _René Ferdinand Rivera Morell_
== Version 4.2.0
This release is predominantly minor fixes and cleanup of the engine. In
particular the bootstrap/build process now clearly communicates C++11
requirement.
* Add `saxonhe_dir` action.
-- _Richard Hodges_
* Add CI testing for historical Boost versions on Windows MSVC.
-- _René Ferdinand Rivera Morell_
* Check for C++11 support when building engine. Including an informative
error message as to that fact.
-- _René Ferdinand Rivera Morell_
* Update Jam grammar parser with latest `bison` version.
-- _René Ferdinand Rivera Morell_
* Allow root `b2 b2` engine build to work even if `bison` grammar generator
is not available.
-- _René Ferdinand Rivera Morell_
* Warning free engine build on at least Windows, macOS, and Linux.
-- _René Ferdinand Rivera Morell_
* Sanitize Windows engine build to consistently use ANSI Win32 API.
-- _Mateusz Loskot_
* Fix b2 engine not exiting, with error, early when it detects a Jam language
error.
-- _Mateusz Loskot_
* Print help for local modules, i.e. current dir.
-- _Thomas Brown_
== Version 4.1.0
Many small bug fixes in this release. But there are some new features also.
There's now an `lto` feature to specify the use of LTO, and what kind. The
existing `stdlib` feature now has real values and corresponding options
for some toolsets. But most importantly there's new documentation for all
the features.
Thank to all the users that contributed to this release with these changes:
* Support for VS2019 for intel-vin 19.0. -- _Edward Diener_
* Fix compiler warnings about `-std=gnu11` when building `b2` on Cygwin. --
_Andrey Semashev_
* Add example of creating multiple PCHs for individual headers.
-- _René Ferdinand Rivera Morell_
* Add QNX threading flags for GCC toolset. -- _Aurelien Chartier_
* Fix version option for IBM and Sun compilers when building b2 engine
-- _Juan Alday_
* Rename `strings.h` to `jam_strings.h` in `b2` engine to avoid clash with
POSIX `strings.h` header. -- _Andrey Semashev_
* Add options for `cxxstd` feature for IBM compiler. -- _Edward Diener_
* Many fixes to intel-win toolset. -- _Edwad Diener_
* Add z15 instruction set for gcc based toolsets. -- _Neale Ferguson_
* Improve using MSVC from a Cygwin shell. -- _Michael Haubenwallner_
* Add LTO feature and corresponding support for gcc and clang toolsets.
-- _Dmitry Arkhipov_
* Fix errors when a source doesn't have a type. -- _Peter Dimov_
* Add documentation for features. -- _Dmitry Arkhipov_
* Enhance `stdlib` feature, and corresponding documentation, for clang, gcc,
and sun toolsets. -- _Dmitry Arkhipov_
* Install rule now makes explicit only the immediate targets it creates.
-- _Dmitry Arkhipov_
* Add armasm (32 and 64) support for msvc toolset. -- _Michał Janiszewski_
* Fix errors with custom un-versioned gcc toolset specifications.
-- _Peter Dimov_
* Allow arflags override in gcc toolset specifications. -- _hyc_
* Fix founds libs not making it to the clang-win link command line.
-- _Peter Dimov_
* Updated intel-win toolset to support for Intel C++ 19.1.
-- _Edward Diener_
* Detect difference between MIPS32 and MIPS64 for OS in b2 engine.
-- _YunQiang Su_
== Version 4.0.1
This patch release fixes a minor issue when trying to configure toolsets that
override the toolset version with a non-version tag. Currently this is only
known to be a problem if you: (a) configure a toolset version to something
like "`tot`" (b) in Boost 1.72.0 when it creates cmake install artifacts.
Fix for this was provided Peter Dimov.
== Version 4.0.0
After even more years of development the landscape of build systems has changed
considerably, and so has the landscape of compilers. This version marks the
start of B2 transitioning to a {CPP} implementation. Initially this means that
the engine will be compiled as C++ source but that source is still the base
C implementation. Over time it will transform to a {CPP} code base in both the
engine and build system. Some changes in this start:
* Requires {CPP} 11 to build engine.
* Simplified build scripts to make it easier to maintain.
* Building with {CPP} optimizations gives an immediate performance improvement.
Other changes in this release:
* Add support for using prebuilt OpenSSL. -- _Damian Jarek_
* Define the riscv architecture feature. -- _Andreas Schwab_
* Add ARM64 as a valid architecture for MSVC. -- _Marc Sweetgall_
* Set coverage flags, from coverage feature, for gcc and clang. -- _Damian Jarek_
* Add s390x CPU and support in gcc/clang. -- _Neale Ferguson_
* Support importing pkg-config packages. -- _Dmitry Arkhipov_
* Support for leak sanitizer. -- _Damian Jarek_
* Fix missing `/manifest` option in clang-win to fix admin elevation for exes
with "update" in the name. -- _Peter Dimov_
* Add `freertos` to `os` feature. -- _Thomas Brown_
* Default parallel jobs (`-jX`) to the available CPU threads. -- _René Ferdinand Rivera Morell_
* Simpler coverage feature. -- _Hans Dembinski_
* Better stacks for sanitizers. -- _James E. King III_
WARNING: The default number of parallel jobs has changed in this release from
"1" to the number of cores. There are circumstances when that default can be
larger than the allocated cpu resources, for instance in some virtualized
container installs.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,99 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View File

@@ -0,0 +1,15 @@
Want to learn about B2 features? Start with the
link:#bbv2.tutorial[tutorial] and continue with the link:#bbv2.overview[overview].
When you're ready to try B2 in practice, go to the
link:#bbv2.installation[installation].
Building a project with B2? See the link:#bbv2.installation[installation]
and then read the link:#bbv2.overview.invocation[overview].
Setting up B2 on your project? Take a look at the
link:#bbv2.overview[overview] and link:#bbv2.extender[extender manual].
If there's anything you find unclear in this documentation, report the
problem directly in the https://github.com/bfgroup/b2/issues[issue
tracker]. For more general questions, please post them to our discussion
forums (https://github.com/bfgroup/b2/discussions[]).

View File

@@ -0,0 +1,30 @@
[[bbv2.installation]]
= Installation
To install B2 from an official release, as available on
https://github.com/bfgroup/b2/releases[GitHub],
follow these steps:
1. Unpack the release. On the command line, go to the root of the
unpacked tree.
2. Run either `.\bootstrap.bat` (on Windows), or `./bootstrap.sh` (on
other operating systems).
3. Run
+
[source,shell]
----
$ ./b2 install --prefix=PREFIX
----
+
where PREFIX is a directory where you want B2 to be installed.
4. Optionally, add `PREFIX/bin` to your PATH environment variable.
[source,shell]
----
$ PREFIX/bin/b2
----
A simple executable should be built.
NOTE: A C+\+11 capable compiler is needed to build the `b2` engine. But using
the `b2` engine and build system does not require C++11.

View File

@@ -0,0 +1,35 @@
[[bbv2.reference.class.main-target]]
= Class main-target
[source,jam]
----
class main-target : abstract-target {
rule generate ( property-set )
# Methods inherited from abstract-target
rule name ( )
rule project ( )
rule location ( )
rule full-name ( )
}
----
A link:#bbv2.reference.class.main-target[main-target] represents a named
top-level target in a Jamfile.
--
1. [[bbv2.reference.class.main-target.generate]] `rule generate ( property-set )`
+
Overrides
link:#bbv2.reference.class.abstract-target.generate[abstract-target.generate].
Select an alternative for this main target, by finding all alternatives
whose requirements are satisfied by `property-set` and picking the one
with the longest requirements set. Returns the result of calling
link:#bbv2.reference.class.basic-target.generate[generate] on that
alternative.
+
On success, returns:
+
* a property-set with the usage requirements to be applied to dependents
* a list of produced virtual targets, which may be empty.
--

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
[[bbv2.reference.modules.path]]
= path
Performs various path manipulations. Paths are always in a 'normalized'
representation. In it, a path may be either:
* `'.'`, or
* `['/'] [ ( '..' '/' )* (token '/')* token ]`
In plain english, a path can be rooted, `'..'` elements are allowed only
at the beginning, and it never ends in slash, except for the path
consisting of slash only.
1. [[bbv2.reference.modules.path.make]] `rule make ( native )`
+
Converts the native path into normalized form.
2. [[bbv2.reference.modules.path.native]] `rule native ( path )`
+
Builds the native representation of the path.
3. [[bbv2.reference.modules.path.is-rooted]] `rule is-rooted ( path )`
+
Tests if a path is rooted.
4. [[bbv2.reference.modules.path.has-parent]] `rule has-parent ( path )`
+
Tests if a path has a parent.
5. [[bbv2.reference.modules.path.basename]] `rule basename ( path )`
+
Returns the path without any directory components.
6. [[bbv2.reference.modules.path.parent]] `rule parent ( path )`
+
Returns the parent directory of the path. If no parent exists, an error
is issued.
7. [[bbv2.reference.modules.path.reverse]] `rule reverse ( path )`
+
Returns `path2` such that `[ join path path2 ] = "."`. The path may not
contain `".."` element or be rooted.
8. [[bbv2.reference.modules.path.join]] `rule join ( elements + )`
+
Concatenates the passed path elements. Generates an error if any element
other than the first one is rooted. Skips any empty or undefined path
elements.
9. [[bbv2.reference.modules.path.root]] `rule root ( path root )`
+
If `path` is relative, it is rooted at `root`. Otherwise, it is
unchanged.
10. [[bbv2.reference.modules.path.pwd]] `rule pwd ( )`
+
Returns the current working directory.
11. [[bbv2.reference.modules.path.glob]] `rule glob ( dirs * : patterns + : exclude-patterns * )`
+
Returns the list of files matching the given pattern in the specified
directory. Both directories and patterns are supplied as portable paths.
Each pattern should be a non-absolute path, and can't contain "." or
".." elements. Each slash separated element of a pattern can contain the
following special characters:
+
* '?' matches any character
* '*' matches an arbitrary number of characters
+
A file `$(d)/e1/e2/e3` (where 'd' is in `$(dirs)`) matches the pattern
p1/p2/p3 if and only if e1 matches p1, e2 matches p2 and so on. For
example:
+
[source,jam]
----
[ glob . : *.cpp ]
[ glob . : */build/Jamfile ]
----
12. [[bbv2.reference.modules.path.glob-tree]] `rule glob-tree ( roots * : patterns + : exclude-patterns * )`
+
Recursive version of link:#bbv2.reference.modules.path.glob[glob].
Builds the glob of files while also searching in the subdirectories of
the given roots. An optional set of exclusion patterns will filter out
the matching entries from the result. The exclusions also apply to the
subdirectory scanning, such that directories that match the exclusion
patterns will not be searched.
13. [[bbv2.reference.modules.path.exists]] `rule exists ( file )`
+
Returns true if the specified file exists.
14. [[bbv2.reference.modules.path.all-parents]] `rule all-parents ( path : upper_limit ? : cwd ? )`
+
Find out the absolute name of path and return the list of all the
parents, starting with the immediate one. Parents are returned as
relative names. If `upper_limit` is specified, directories above it will
be pruned.
15. [[bbv2.reference.modules.path.glob-in-parents]] `rule glob-in-parents ( dir : patterns + : upper-limit ? )`
+
Search for `patterns` in parent directories of `dir`, up to and
including `upper_limit`, if it is specified, or till the filesystem root
otherwise.
16. [[bbv2.reference.modules.path.relative]] `rule relative ( child parent : no-error ? )`
+
Assuming `child` is a subdirectory of `parent`, return the relative path
from `parent` to `child`.
17. [[bbv2.reference.modules.path.relative-to]] `rule relative-to ( path1 path2 )`
+
Returns the minimal path to path2 that is relative path1.
18. [[bbv2.reference.modules.path.programs-path]] `rule programs-path ( )`
+
Returns the list of paths which are used by the operating system for
looking up programs.
19. [[bbv2.reference.modules.path.makedirs]] `rule makedirs ( path )`
+
Creates a directory and all parent directories that do not already
exist.

View File

@@ -0,0 +1,59 @@
[[bbv2.reference.class.project-target]]
= Class project-target
[source,jam]
----
class project-target : abstract-target {
rule generate ( property-set )
rule build-dir ( )
rule main-target ( name )
rule has-main-target ( name )
rule find ( id : no-error ? )
# Methods inherited from abstract-target
rule name ( )
rule project ( )
rule location ( )
rule full-name ( )
}
----
This class has the following responsibilities:
* Maintaining a list of main targets in this project and building them.
--
1. [[bbv2.reference.class.project-target.generate]] `rule generate ( property-set )`
+
Overrides
link:#bbv2.reference.class.abstract-target.generate[abstract-target.generate].
Generates virtual targets for all the targets contained in this project.
+
On success, returns:
+
* a property-set with the usage requirements to be applied to dependents
* a list of produced virtual targets, which may be empty.
2. `rule build-dir ( )`
+
Returns the root build directory of the project.
3. `rule main-target ( name )`
+
Returns a link:#bbv2.reference.class.main-target[main-target] class
instance corresponding to `name`. Can only be called after the project
has been fully loaded.
4. `rule has-main-target ( name )`
+
Returns whether a link:#bbv2.reference.class.main-target[main-target]
with the specified name exists. Can only be called after the project has
been fully loaded.
5. `rule find ( id : no-error ? )`
+
Find and return the target with the specified id, treated relative to
self. Id may specify either a target or a file name with the target
taking priority. May report an error or return nothing if the target is
not found depending on the `no-error` parameter.
--

View File

@@ -0,0 +1,66 @@
[[bbv2.reference.class.property-set]]
= Class property-set
Class for storing a set of properties.
[source,jam]
----
class property-set {
rule raw ( )
rule str ( )
rule propagated ( )
rule add ( ps )
rule add-raw ( properties * )
rule refine ( ps )
rule get ( feature )
}
----
There is 1<->1 correspondence between identity and value. No two
instances of the class are equal. To maintain this property, the
'property-set.create' rule should be used to create new instances.
Instances are immutable.
--
1. `rule raw ( )`
+
Returns a Jam list of the stored properties.
2. `rule str ( )`
+
Returns the string representation of the stored properties.
3. `rule propagated ( )`
+
Returns a link:#bbv2.reference.class.property-set[property-set]
containing all the
link:#bbv2.reference.features.attributes.propagated[propagated]
properties in this
link:#bbv2.reference.class.property-set[property-set].
4. [[bbv2.reference.class.property-set.add]] `rule add ( ps )`
+
Returns a new link:#bbv2.reference.class.property-set[property-set]
containing the union of the properties in this
link:#bbv2.reference.class.property-set[property-set] and in `ps`.
+
NOTE: If `ps` contains non-free properties that should override the values in
this object, use link:#bbv2.reference.class.property-set.refine[refine]
instead.
5. `rule add-raw ( properties * )`
+
Link link:#bbv2.reference.class.property-set.add[add], except that it
takes a list of properties instead of a
link:#bbv2.reference.class.property-set[property-set].
6. [[bbv2.reference.class.property-set.refine]] `rule refine ( ps )`
+
Refines properties by overriding any non-free and non-conditional
properties for which a different value is specified in `ps`. Returns the
resulting link:#bbv2.reference.class.property-set[property-set].
7. `rule get ( feature )`
+
Returns all the values of `feature`.
--

View File

@@ -0,0 +1,11 @@
=begin
Copyright 2018 Rene Rivera
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.txt or http://www.boost.org/LICENSE_1_0.txt)
=end
require 'pygments'
# Need to create/register non-builtin lexers even if they are global plugins.
Pygments::Lexer.create name: 'Jam', aliases: ['jam','bjam','b2'],
filenames: ['*.jam','Jamfile','Jamroot'], mimetypes: ['text/x-jam']

View File

@@ -0,0 +1,3 @@
[[bbv2.recipes]]
B2 System V2 recipes
-----------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
[[bbv2.reference.modules.regex]]
= regex
Contains rules for string processing using regular expressions.
* `"x*"` matches the pattern `"x"` zero or more times.
* `"x+"` matches `"x"` one or more times.
* `"x?"` matches `"x"` zero or one time.
* `"[abcd]"` matches any of the characters, `"a"`, `"b"`, `"c"`, and
`"d"`. A character range such as `"[a-z]"` matches any character between
`"a"` and `"z"`. `"[^abc]"` matches any character which is not `"a"`,
`"b"`, or `"c"`.
* `"x|y"` matches either pattern `"x"` or pattern `"y"`
* `(x)` matches `"x"` and captures it.
* `"^"` matches the beginning of the string.
* `"$"` matches the end of the string.
* "\<" matches the beginning of a word.
* "\>" matches the end of a word.
1. [[bbv2.reference.modules.regex.split]] `rule split ( string separator )`
+
Returns a list of the following substrings:
+
.. from beginning till the first occurrence of `separator` or till the
end,
.. between each occurrence of `separator` and the next occurrence,
.. from the last occurrence of `separator` till the end.
+
If no separator is present, the result will contain only one element.
2. [[bbv2.reference.modules.regex.split-list]] `rule split-list ( list * : separator )`
+
Returns the concatenated results of applying
link:#bbv2.reference.modules.regex.split[regex.split] to every element
of the list using the separator pattern.
3. [[bbv2.reference.modules.regex.match]] `rule match ( pattern : string : indices * )`
+
Match `string` against `pattern`, and return the elements indicated by
`indices`.
4. [[bbv2.reference.modules.regex.transform]] `rule transform ( list * : pattern : indices * )`
+
Matches all elements of `list` against the `pattern` and returns a list
of elements indicated by `indices` of all successful matches. If
`indices` is omitted returns a list of first parenthesized groups of all
successful matches.
5. [[bbv2.reference.modules.regex.escape]] `rule escape ( string : symbols : escape-symbol )`
+
Escapes all of the characters in `symbols` using the escape symbol
`escape-symbol` for the given string, and returns the escaped string.
6. [[bbv2.reference.modules.regex.replace]] `rule replace ( string match replacement )`
+
Replaces occurrences of a match string in a given string and returns the
new string. The match string can be a regex expression.
7. [[bbv2.reference.modules.regex.replace-list]] `rule replace-list ( list * : match : replacement )`
+
Replaces occurrences of a match string in a given list of strings and
returns a list of new strings. The match string can be a regex
expression.
See also: link:#jam.language.rules.builtins.utility.\_match__[MATCH]

View File

@@ -0,0 +1,55 @@
[[bbv2.reference.modules.sequence]]
= sequence
Various useful list functions. Note that algorithms in this module
execute largely in the caller's module namespace, so that local rules
can be used as function objects. Also note that most predicates can be
multi-element lists. In that case, all but the first element are
prepended to the first argument which is passed to the rule named by the
first element.
1. `rule filter ( predicate + : sequence * )`
+
Return the elements `e` of `$(sequence)` for which `[ $(predicate) e ]`
has a non-null value.
2. `rule transform ( function + : sequence * )`
+
Return a new sequence consisting of `[ $(function) $(e) ]` for each
element `e` of `$(sequence)`.
3. `rule reverse ( s * )`
+
Returns the elements of `s` in reverse order.
4. `rule insertion-sort ( s * : ordered * )`
+
Insertion-sort `s` using the BinaryPredicate `ordered`.
5. `rule merge ( s1 * : s2 * : ordered * )`
+
Merge two ordered sequences using the BinaryPredicate `ordered`.
6. `rule join ( s * : joint ? )`
+
Join the elements of `s` into one long string. If `joint` is supplied,
it is used as a separator.
7. `rule length ( s * )`
+
Find the length of any sequence.
8. `rule unique ( list * : stable ? )`
+
Removes duplicates from `list`. If `stable` is passed, then the order of
the elements will be unchanged.
9. `rule max-element ( elements + : ordered ? )`
+
Returns the maximum number in `elements`. Uses `ordered` for comparisons
or `numbers.less` if none is provided.
10. `rule select-highest-ranked ( elements * : ranks * )`
+
Returns all of `elements` for which the corresponding element in the
parallel list `rank` is equal to the maximum value in `rank`.

View File

@@ -0,0 +1,70 @@
= B2 User Manual
:copyright: Copyright 2018-2021 René Ferdinand Rivera Morell; Copyright 2006, 2014 Vladimir Prus
:author: René Ferdinand Rivera Morell, Vladimir Prus, Steven Watanabe
:toc: left
:toclevels: 2
:sectanchors:
:sectnums:
:nofooter:
:stylesheet: amber.css
// :source-highlighter: rouge
// :source-highlighter: pygments
:source-language: jam
:highlightjsdir: hljs
// :pygments-style: native
// :rouge-style: native
// :pygments-style: friendly
:caution-caption: ⚑
:important-caption: ‼
:note-caption:
:tip-caption: ☀
:warning-caption: ⚠
:CPP: C++
== Introduction
ifdef::backend-html5[]
++++
<style>
</style>
++++
endif::[]
include::howto.adoc[]
****
Copyright 2018-2021 René Ferdinand Rivera Morell;
Copyright 2006, 2014 Vladimir Prus.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file `LICENSE.txt` or copy at https://www.bfgroup.xyz/b2/LICENSE.txt)
****
toc::[]
:leveloffset: +1
include::install.adoc[]
include::tutorial.adoc[]
include::overview.adoc[]
include::tasks.adoc[]
include::reference.adoc[]
include::debug.adoc[]
include::extending.adoc[]
include::faq.adoc[]
include::tools.adoc[]
include::examples.adoc[]
include::bjam.adoc[]
include::history.adoc[]
:leveloffset: -1

View File

@@ -0,0 +1,728 @@
[[bbv2.tasks]]
= Common tasks
This section describes main targets types that B2 supports
out-of-the-box. Unless otherwise noted, all mentioned main target rules
have the common signature, described in
link:#bbv2.overview.targets[the section called “Declaring Targets”].
[[bbv2.tasks.programs]]
== Programs
Programs are created using the `exe` rule, which follows the
link:#bbv2.main-target-rule-syntax[common syntax]. For example:
[source]
----
exe hello
: hello.cpp some_library.lib /some_project//library
: <threading>multi
;
----
This will create an executable file from the sources--in this case,
one {CPP} file, one library file present in the same directory, and
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
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
add the paths manually, or have the build place the application and the
libraries into the same directory. See
link:#bbv2.tasks.installing[the section called “Installing”].
[[bbv2.tasks.libraries]]
== Libraries
Library targets are created using the `lib` rule, which follows the
link:#bbv2.main-target-rule-syntax[common syntax]. For example:
[source]
----
lib helpers : helpers.cpp ;
----
This will define a library target named `helpers` built from the
`helpers.cpp` source file. It can be either a static library or a shared
library, depending on the value of the
link:#bbv2.builtin.features.link[`<link>`] feature.
Library targets can represent:
* Libraries that should be built from source, as in the example above.
* Prebuilt libraries which already exist on the system. Such libraries
can be searched for by the tools using them (typically with the linker's
`-l` option) or their paths can be known in advance by the build system.
The syntax for prebuilt libraries is given below:
[source]
----
lib z : : <name>z <search>/home/ghost ;
lib compress : : <file>/opt/libs/compress.a ;
----
The `name` property specifies the name of the library without the
standard prefixes and suffixes. For example, depending on the system,
`z` could refer to a file called `z.so`, `libz.a`, or `z.lib`, etc. The
`search` feature specifies paths in which to search for the library in
addition to the default compiler paths. `search` can be specified
several times or it can be omitted, in which case only the default
compiler paths will be searched. The `file` property specifies the file
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]
====
The value of the `search` feature is just added to the linker search
path. When linking to multiple libraries, the paths specified by
`search` are combined without regard to which `lib` target each path
came from. Thus, given
[source]
----
lib a : : <name>a <search>/pool/release ;
lib b : : <name>b <search>/pool/debug ;
----
If /pool/release/a.so, /pool/release/b.so, /pool/debug/a.so, and
/pool/release/b.so all exist, the linker will probably take both `a` and
`b` from the same directory, instead of finding `a` in /pool/release and
`b` in /pool/debug. If you need to distinguish between multiple
libraries with the same name, it's safer to use `file`.
====
For convenience, the following syntax is allowed:
[source]
----
lib z ;
lib gui db aux ;
----
which has exactly the same effect as:
[source]
----
lib z : : <name>z ;
lib gui : : <name>gui ;
lib db : : <name>db ;
lib aux : : <name>aux ;
----
When a library references another library you should put that other
library in its list of sources. This will do the right thing in all
cases. For portability, you should specify library dependencies even for
searched and prebuilt libraries, otherwise, static linking on Unix will
not work. For example:
[source]
----
lib z ;
lib png : z : <name>png ;
----
[NOTE]
====
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
library with automatically link to its source library as well.
On the other hand, when a shared library has a static library as a
source then the first library will be built so that it completely
includes the second one.
If you do not want a shared library to include all the libraries
specified in its sources (especially statically linked ones), you would
need to use the following:
[source]
----
lib b : a.cpp ;
lib a : a.cpp : <use>b : : <library>b ;
----
This specifies that library `a` uses library `b`, and causes all
executables that link to `a` to link to `b` also. In this case, even for
shared linking, the `a` library will not refer to `b`.
====
link:#bbv2.overview.targets[Usage requirements] are often very useful
for defining library targets. For example, imagine that you want you
build a `helpers` library and its interface is described in its
`helpers.hpp` header file located in the same directory as the
`helpers.cpp` source file. Then you could add the following to the
Jamfile located in that same directory:
[source]
----
lib helpers : helpers.cpp : : : <include>. ;
----
which would automatically add the directory where the target has been
defined (and where the library's header file is located) to the
compiler's include path for all targets using the `helpers` library.
This feature greatly simplifies Jamfiles.
[[bbv2.tasks.alias]]
== Alias
The `alias` rule gives an alternative name to a group of targets. For
example, to give the name `core` to a group of three other targets with
the following code:
[source]
----
alias core : im reader writer ;
----
Using `core` on the command line, or in the source list of any other
target is the same as explicitly using `im`, `reader`, and `writer`.
Another use of the `alias` rule is to change build properties. For
example, if you want to link statically to the Boost Threads
library, you can write the following:
[source]
----
alias threads : /boost/thread//boost_thread : <link>static ;
----
and use only the `threads` alias in your Jamfiles.
You can also specify usage requirements for the `alias` target. If you
write the following:
[source]
----
alias header_only_library : : : : <include>/usr/include/header_only_library ;
----
then using `header_only_library` in sources will only add an include
path. Also note that when an alias has sources, their usage requirements
are propagated as well. For example:
[source]
----
lib library1 : library1.cpp : : : <include>/library/include1 ;
lib library2 : library2.cpp : : : <include>/library/include2 ;
alias static_libraries : library1 library2 : <link>static ;
exe main : main.cpp static_libraries ;
----
will compile `main.cpp` with additional includes required for using the
specified static libraries.
[[bbv2.tasks.installing]]
== Installing
This section describes various ways to install built targets and
arbitrary files.
=== Basic install
For installing a built target you should use the `install` rule, which
follows the link:#bbv2.main-target-rule-syntax[common syntax]. For
example:
[source]
----
install dist : hello helpers ;
----
will cause the targets `hello` and `helpers` to be moved to the `dist`
directory, relative to the Jamfile's directory. The directory can be
changed using the `location` property:
[source]
----
install dist : hello helpers : <location>/usr/bin ;
----
While you can achieve the same effect by changing the target name to
`/usr/bin`, using the `location` property is better as it allows you to
use a mnemonic target name.
The `location` property is especially handy when the location is not
fixed, but depends on the build variant or environment variables:
[source]
----
install dist : hello helpers :
<variant>release:<location>dist/release
<variant>debug:<location>dist/debug ;
install dist2 : hello helpers : <location>$(DIST) ;
----
See also link:#bbv2.reference.variants.propcond[conditional properties]
and link:#bbv2.faq.envar[environment variables]
=== Installing with all dependencies
Specifying the names of all libraries to install can be boring. The
`install` allows you to specify only the top-level executable targets to
install, and automatically install all dependencies:
[source]
----
install dist : hello :
<install-dependencies>on <install-type>EXE
<install-type>LIB
;
----
will find all targets that `hello` depends on, and install all of those
which are either executables or libraries. More specifically, for each
target, other targets that were specified as sources or as dependency
properties, will be recursively found. One exception is that targets
referred with the link:#bbv2.builtin.features.use[`use`] feature are not
considered, as that feature is typically used to refer to header-only
libraries. If the set of target types is specified, only targets of that
type will be installed, otherwise, all found target will be installed.
=== Preserving Directory Hierarchy
By default, the `install` rule will strip paths from its sources. So, if
sources include `a/b/c.hpp`, the `a/b` part will be ignored. To make the
`install` rule preserve the directory hierarchy you need to use the
`<install-source-root>` feature to specify the root of the hierarchy you
are installing. Relative paths from that root will be preserved. For
example, if you write:
[source]
----
install headers
: a/b/c.h
: <location>/tmp <install-source-root>a
;
----
the a file named `/tmp/b/c.h` will be created.
The link:#bbv2.reference.glob-tree[`glob-tree`] rule can be used to find
all files below a given directory, making it easy to install an entire
directory tree.
=== Installing into Several Directories
The link:#bbv2.tasks.alias[`alias`] rule can be used when targets need
to be installed into several directories:
[source]
----
alias install : install-bin install-lib ;
install install-bin : applications : /usr/bin ;
install install-lib : helper : /usr/lib ;
----
Because the `install` rule just copies targets, most free features
footnote:[see the definition of "free" in
link:#bbv2.reference.features.attributes[the section called “Feature Attributes”].]
have no effect when used in requirements of the `install` rule. The only two
that matter are
link:#bbv2.builtin.features.dependency[`dependency`] and, on Unix,
link:#bbv2.builtin.features.dll-path[`dll-path`].
NOTE: (Unix specific) On Unix, executables built using B2 typically
contain the list of paths to all used shared libraries. For installing,
this is not desired, so B2 relinks the executable with an empty
list of paths. You can also specify additional paths for installed
executables using the `dll-path` feature.
[[bbv2.builtins.testing]]
== Testing
B2 has convenient support for running unit tests. The simplest
way is the `unit-test` rule, which follows the
link:#bbv2.main-target-rule-syntax[common syntax]. For example:
[source]
----
unit-test helpers_test : helpers_test.cpp helpers ;
----
The `unit-test` rule behaves like the link:#bbv2.tasks.programs[exe]
rule, but after the executable is created it is also run. If the
executable returns an error code, the build system will also return an
error and will try running the executable on the next invocation until
it runs successfully. This behavior ensures that you can not miss a
unit test failure.
There are few specialized testing rules, listed below:
[source]
----
rule compile ( sources : requirements * : target-name ? )
rule compile-fail ( sources : requirements * : target-name ? )
rule link ( sources + : requirements * : target-name ? )
rule link-fail ( sources + : requirements * : target-name ? )
----
They are given a list of sources and requirements. If the target name is
not provided, the name of the first source file is used instead. The
`compile*` tests try to compile the passed source. The `link*` rules try
to compile and link an application from all the passed sources. The
`compile` and `link` rules expect that compilation/linking succeeds. The
`compile-fail` and `link-fail` rules expect that the
compilation/linking fails.
There are two specialized rules for running executables, which are more
powerful than the `unit-test` rule. The `run` rule has the following
signature:
[source]
----
rule run ( sources + : args * : input-files * : requirements * : target-name ?
: default-build * )
----
The rule builds application from the provided sources and runs it,
passing `args` and `input-files` as command-line arguments. The `args`
parameter is passed verbatim and the values of the `input-files`
parameter are treated as paths relative to containing Jamfile, and are
adjusted if `b2` is invoked from a different directory. The `run-fail`
rule is identical to the `run` rule, except that it expects that the run
fails.
All rules described in this section, if executed successfully, create a
special manifest file to indicate that the test passed. For the
`unit-test` rule the files is named `target-name.passed` and for the other
rules it is called `target-name.test`. The `run*` rules also capture all
output from the program, and store it in a file named `target-name.output`.
If the `preserve-test-targets` feature has the
value `off`, then `run` and the `run-fail` rules will remove the
executable after running it. This somewhat decreases disk space
requirements for continuous testing environments. The default value of
`preserve-test-targets` feature is `on`.
It is possible to print the list of all test targets (except for
`unit-test`) declared in your project, by passing the `--dump-tests`
command-line option. The output will consist of lines of the form:
[source]
----
boost-test(test-type) path : sources
----
It is possible to process the list of tests, B2 output and the
presence/absence of the `*.test` files created when test passes into
human-readable status table of tests. Such processing utilities are not
included in B2.
The following features adjust behavior of the testing metatargets.
`testing.arg`::
Defines an argument to be passed to the target when it is executed
before the list of input files.
+
[source]
----
unit-test helpers_test
: helpers_test.cpp helpers
: <testing.arg>"--foo bar"
;
----
`testing.input-file`::
Specifies a file to be passed to the executable on the command line
after the arguments. All files must be specified in alphabetical order
due to constraints in the current implementation.
`testing.launcher`::
By default, the executable is run directly. Sometimes, it is desirable
to run the executable using some helper command. You should use this
property to specify the name of the helper command. For example, if
you write:
+
[source]
----
unit-test helpers_test
: helpers_test.cpp helpers
: <testing.launcher>valgrind
;
----
+
The command used to run the executable will be:
+
[source,shell]
----
valgrind bin/$toolset/debug/helpers_test
----
`test-info`::
A description of the test. This is displayed as part of the
`--dump-tests` command-line option.
[[bbv2.builtins.raw]]
== Custom commands
For most main target rules, B2 automatically figures out the
commands to run. When you want to use new file types or support new
tools, one approach is to extend B2 to support them smoothly,
as documented in link:#bbv2.extender[Extender Manual]. However, if the new
tool is only used in a single place, it might be easier just to specify the
commands to run explicitly.
Three main target rules can be used for that. The `make` rule allows you to
construct a single file from any number of source file, by running a command
you specify. The `notfile` rule allows you to run an arbitrary command,
without creating any files. And finally, the `generate` rule allows you to
describe a transformation using B2's virtual targets. This is
higher-level than the file names that the `make` rule operates with and
allows you to create more than one target, create differently named targets
depending on properties, or use more than one tool.
The `make` rule is used when you want to create one file from a number
of sources using some specific command. The `notfile` is used to
unconditionally run a command.
Suppose you want to create the file `file.out` from the file `file.in`
by running the command `in2out`. Here is how you would do this in B2:
[source]
----
make file.out : file.in : @in2out ;
actions in2out
{
in2out $(<) $(>)
}
----
If you run `b2` and `file.out` does not exist, B2 will run the
`in2out` command to create that file. For more details on specifying
actions, see
link:#bbv2.overview.jam_language.actions[the section called “Boost.Jam Language”].
It could be that you just want to run some command unconditionally, and
that command does not create any specific files. For that you can use
the `notfile` rule. For example:
[source]
----
notfile echo_something : @echo ;
actions echo
{
echo "something"
}
----
The only difference from the `make` rule is that the name of the target
is not considered a name of a file, so B2 will unconditionally
run the action.
The `generate` rule is used when you want to express transformations
using B2's virtual targets, as opposed to just filenames. The
`generate` rule has the standard main target rule signature, but you are
required to specify the `generating-rule` property. The value of the
property should be in the form `@_rule-name_`, the named rule should have the
following signature:
[source]
----
rule generating-rule ( project name : property-set : sources * )
----
and will be called with an instance of the `project-target` class, the
name of the main target, an instance of the `property-set` class
containing build properties, and the list of instances of the
`virtual-target` class corresponding to sources. The rule must return a
list of `virtual-target` instances. The interface of the
`virtual-target` class can be learned by looking at the
`build/virtual-target.jam` file. The `generate` example contained in the
B2 distribution illustrates how the `generate` rule can be
used.
[[bbv2.reference.precompiled_headers]]
== Precompiled Headers
Precompiled headers is a mechanism to speed up compilation by creating a
partially processed version of some header files, and then using that
version during compilations rather then repeatedly parsing the original
headers. B2 supports precompiled headers with gcc and msvc
toolsets.
To use precompiled headers, follow the following steps:
1. Create a header that includes headers used by your project that you
want precompiled. It is better to include only headers that are
sufficiently stable -- like headers from the compiler and external
libraries. B2 will include the header automatically and on-demand.
2. Declare a new B2 target for the precompiled header and add
that precompiled header to the sources of the target whose compilation
you want to speed up:
+
[source]
----
cpp-pch pch : pch.hpp ;
exe main : main.cpp pch ;
----
+
You can use the `c-pch` rule if you want to use the precompiled header
in C programs.
The `pch` example in B2 distribution can be used as reference.
Please note the following:
* The build properties used to compile the source files and the
precompiled header must be the same. Consider using project requirements
to assure this.
* Precompiled headers must be used purely as a way to improve
compilation time, not to save the number of `#include` statements. If a
source file needs to include some header, explicitly include it in the
source file, even if the same header is included from the precompiled
header. This makes sure that your project will build even if precompiled
headers are not supported.
* Prior to version 4.2, the gcc compiler did not allow anonymous
namespaces in precompiled headers, which limits their utility. See the
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29085[bug report] for
details.
* Previosuly B2 had not been automatically inluding the header, a user
was required to include the header at the top of every source file
the precompiled header will be used with.
[[bbv2.reference.generated_headers]]
== Generated headers
Usually, B2 handles implicit dependencies completely
automatically. For example, for {CPP} files, all `#include` statements are
found and handled. The only aspect where user help might be needed is
implicit dependency on generated files.
By default, B2 handles such dependencies within one main
target. For example, assume that main target "app" has two sources,
"app.cpp" and "parser.y". The latter source is converted into "parser.c"
and "parser.h". Then, if "app.cpp" includes "parser.h", B2 will
detect this dependency. Moreover, since "parser.h" will be generated
into a build directory, the path to that directory will automatically be
added to the include path.
Making this mechanism work across main target boundaries is possible,
but imposes certain overhead. For that reason, if there is implicit
dependency on files from other main targets, the `<implicit-dependency>`
feature must be used, for example:
[source]
----
lib parser : parser.y ;
exe app : app.cpp : <implicit-dependency>parser ;
----
The above example tells the build system that when scanning all sources
of "app" for implicit-dependencies, it should consider targets from
"parser" as potential dependencies.
[[bbv2.tasks.crosscompile]]
== Cross-compilation
B2 supports cross compilation with the gcc and msvc toolsets.
When using gcc, you first need to specify your cross compiler in
`user-config.jam` (see
link:#bbv2.overview.configuration[the section called “Configuration”]), for
example:
[source]
----
using gcc : arm : arm-none-linux-gnueabi-g++ ;
----
After that, if the host and target os are the same, for example Linux,
you can just request that this compiler version be used:
[source,shell]
----
b2 toolset=gcc-arm
----
If you want to target a different operating system from the host, you
need to additionally specify the value for the `target-os` feature, for
example:
[source,bat]
----
# On windows box
b2 toolset=gcc-arm target-os=linux
# On Linux box
b2 toolset=gcc-mingw target-os=windows
----
For the complete list of allowed operating system names, please see the
documentation for link:#bbv2.builtin.features.target-os[target-os
feature].
When using the msvc compiler, it's only possible to cross-compile to a
64-bit system on a 32-bit host. Please see
link:#bbv2.reference.tools.compiler.msvc.64[the section called “64-bit support”]
for details.
[[bbv2.tasks.packagemanagers]]
== Package Managers
B2 support automatic, or manual, loading of generated build files
from package managers. For example using the Conan package manager which
generates `conanbuildinfo.jam` files B2 will load that files automatically
when it loads the project at the same location. The included file can
define targets and other project declarations in the context of the
project it's being loaded into. Control over what package manager file
is loaded can be controlled with (in order of priority):
* With the `use-packages` rule.
* Command line argument `--use-package-manager=X`.
* Environment variable `PACKAGE_MANAGER_BUILD_INFO`.
* Built-in detection of the file. Currently this includes: "conan".
**`use-packages` rule:**
[source]
----
rule use-packages ( name-or-glob-pattern ? )
----
The `use-packages` rule allows one to specify in the projects themselves kind
of package definitions to use either as the ones for a built-in package
manager support. For example:
[source]
----
use-packages conan ;
----
Or to specify a `glob` pattern to find the file with the definitions. For
instance:
[source]
----
use-packages "packages.jam" ;
----
**`--use-package-manager` command line option:**
The `--use-package-manager=NAME` command line option allows one to
non-intrusively specify per invocation which of the built-in package manager
types to use.
**`PACKAGE_MANAGER_BUILD_INFO` variable:**
The `PACKAGE_MANAGER_BUILD_INFO` variable, which is taken from the environment
or defined with the `-sX=Y` option, specifies a `glob` pattern to use to find
the package definitions.
**Built-in detection:**
There are a number of built-in `glob` patterns to support popular package
managers. Currently the supported ones are:
* Conan (`conan`): currently supports the
link:https://docs.conan.io/en/latest/reference/generators/b2.html[`b2 generator`].

View File

@@ -0,0 +1,19 @@
= Extra Tools
== Documentation Tools
:leveloffset: +2
include::../../src/tools/asciidoctor.jam[tag=doc]
:leveloffset: -2
== Miscellaneous Tools
:leveloffset: +2
include::../../src/tools/pkg-config.jam[tag=doc]
:leveloffset: -2
:leveloffset: +2
include::../../src/tools/sass.jam[tag=doc]
:leveloffset: -2

View File

@@ -0,0 +1,553 @@
[[bbv2.tutorial]]
= Tutorial
This section will guide you though the most basic features of
B2. We will start with the “Hello, world” example, learn how to
use libraries, and finish with testing and installing features.
[[bbv2.tutorial.hello]]
== Hello, world
The simplest project that B2 can construct is stored in
`example/hello/` directory. The project is described by a file called
`Jamfile` that contains:
[source]
----
exe hello : hello.cpp ;
----
Even with this simple setup, you can do some interesting things. First
of all, just invoking `b2` will build the `hello` executable by compiling
and linking `hello.cpp`. By default, the debug variant is built. Now, to
build the release variant of `hello`, invoke
[source,shell]
----
b2 release
----
Note that the debug and release variants are created in different
directories, so you can switch between variants or even build multiple
variants at once, without any unnecessary recompilation. Let us extend
the example by adding another line to our project's `Jamfile`:
[source]
----
exe hello2 : hello.cpp ;
----
Now let us build both the debug and release variants of our project
again:
[source,shell]
----
b2 debug release
----
Note that two variants of `hello2` are linked. Since we have already
built both variants of `hello`, hello.cpp will not be recompiled;
instead the existing object files will just be linked into the
corresponding variants of `hello2`. Now let us remove all the built
products:
[source,shell]
----
b2 --clean debug release
----
It is also possible to build or clean specific targets. The following
two commands, respectively, build or clean only the debug version of
`hello2`.
[source,shell]
----
b2 hello2
b2 --clean hello2
----
[[bbv2.tutorial.properties]]
== Properties
To represent aspects of target configuration such as debug and release
variants, or single- and multi-threaded builds portably, B2
uses _features_ with associated _values_. For example, the `debug-symbols`
feature can have a value of `on` or `off`. A _property_ is just a
(feature, value) pair. When a user initiates a build, B2
automatically translates the requested properties into appropriate
command-line flags for invoking toolset components like compilers and
linkers.
There are many built-in features that can be combined to produce
arbitrary build configurations. The following command builds the
project's `release` variant with inlining disabled and debug symbols
enabled:
[source,shell]
----
b2 release inlining=off debug-symbols=on
----
Properties on the command-line are specified with the syntax:
----
feature-name=feature-value
----
The `release` and `debug` that we have seen in `b2` invocations are just
a shorthand way to specify values of the `variant` feature. For example,
the command above could also have been written this way:
[source,shell]
----
b2 variant=release inlining=off debug-symbols=on
----
`variant` is so commonly-used that it has been given special status as
an _implicit_ feature—B2 will deduce its identity just from the
name of one of its values.
A complete description of features can be found in
link:#bbv2.reference.features[the section called “Features and properties”].
[[bbv2.tutorial.properties.requirements]]
=== Build Requests and Target Requirements
The set of properties specified on the command line constitutes a _build
request_—a description of the desired properties for building the
requested targets (or, if no targets were explicitly requested, the
project in the current directory). The _actual_ properties used for
building targets are typically a combination of the build request and
properties derived from the project's `Jamfile` (and its other Jamfiles,
as described in
link:#bbv2.tutorial.hierarchy[the section called “Project Hierarchies”]).
For example, the locations of `#include`d header files are normally not
specified on the command-line, but described in Jamfiles as _target
requirements_ and automatically combined with the build request for those
targets. Multi-threaded compilation is another example of a typical
target requirement. The Jamfile fragment below illustrates how these
requirements might be specified.
[source]
----
exe hello
: hello.cpp
: <include>boost <threading>multi
;
----
When `hello` is built, the two requirements specified above will always
be present. If the build request given on the `b2` command-line
explicitly contradicts a target's requirements, the target requirements
usually override (or, in the case of “free” features like
`<include>`, footnote:[See
link:#bbv2.reference.features.attributes[the section called “Feature Attributes”]]
augment) the build request.
TIP: The value of the `<include>` feature is relative to the location of
`Jamfile` where it is used.
[[bbv2.tutorial.properties.project_attributes]]
=== Project Attributes
If we want the same requirements for our other target, `hello2`, we
could simply duplicate them. However, as projects grow, that approach
leads to a great deal of repeated boilerplate in Jamfiles. Fortunately,
there's a better way. Each project can specify a set of _attributes_,
including requirements:
[source]
----
project
: requirements <include>/home/ghost/Work/boost <threading>multi
;
exe hello : hello.cpp ;
exe hello2 : hello.cpp ;
----
The effect would be as if we specified the same requirement for both
`hello` and `hello2`.
[[bbv2.tutorial.hierarchy]]
== Project Hierarchies
So far we have only considered examples with one project, with one
user-written `Jamfile` file. A typical large codebase would
be composed of many projects organized into a tree. The top of the tree
is called the _project root_. Every subproject is defined by a file called
`Jamfile` in a descendant directory of the project root. The parent
project of a subproject is defined by the nearest Jamfile
file in an ancestor directory. For example, in the following directory
layout:
....
top/
|
+-- Jamfile
|
+-- app/
| |
| +-- Jamfile
| `-- app.cpp
|
`-- util/
|
+-- foo/
. |
. +-- Jamfile
. `-- bar.cpp
....
the project root is `top/`. The projects in `top/app/` and
`top/util/foo/` are immediate children of the root project.
NOTE: When we refer to a “Jamfile,” set in normal type, we mean a file called
either `Jamfile` or `Jamroot`. When we need to be more specific, the
filename will be set as “`Jamfile`” or “`Jamroot`.”
Projects inherit all attributes (such as requirements) from their
parents. Inherited requirements are combined with any requirements
specified by the subproject. For example, if `top/Jamfile` has
[source]
----
<include>/home/ghost/local
----
in its requirements, then all of its sub-projects will have it in their
requirements, too. Of course, any project can add include paths to those
specified by its parents. footnote:[Many features will be overridden,
rather than added-to, in sub-projects See
link:#bbv2.reference.features.attributes[the section called “Feature Attributes”] for more information] More
details can be found in link:#bbv2.overview.projects[the section called “Projects”].
Invoking `b2` without explicitly specifying any targets on the command
line builds the project rooted in the current directory. Building a
project does not automatically cause its sub-projects to be built unless
the parent project's Jamfile explicitly requests it. In our example,
`top/Jamfile` might contain:
[source]
----
build-project app ;
----
which would cause the project in `top/app/` to be built whenever the
project in `top/` is built. However, targets in `top/util/foo/` will be
built only if they are needed by targets in `top/` or `top/app/`.
[[bbv2.tutorial.libs]]
== Dependent Targets
When building a target `X` that depends on first building another target
`Y` (such as a library that must be linked with X), `Y` is called a
_dependency_ of `X` and `X` is termed a _dependent_ of `Y`.
To get a feeling of target dependencies, let's continue the above
example and see how `top/app/Jamfile` can use libraries from
`top/util/foo`. If `top/util/foo/Jamfile` contains
[source]
----
lib bar : bar.cpp ;
----
then to use this library in `top/app/Jamfile`, we can write:
[source]
----
exe app : app.cpp ../util/foo//bar ;
----
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
libraries, for example `LIBS` variable. In B2, you just add the
library to the list of sources.
Suppose we build `app` with:
[source,shell]
----
b2 app optimization=full define=USE_ASM
----
Which properties will be used to build `foo`? The answer is that some
features are _propagated_ — B2 attempts to use dependencies with
the same value of propagated features. The `<optimization>` feature is
propagated, so both `app` and `foo` will be compiled with full
optimization. But `<define>` is not propagated: its value will be added
as-is to the compiler flags for `a.cpp`, but won't affect `foo`.
Let's improve this project further. The library probably has some
headers that must be used when compiling `app.cpp`. We could manually
add the necessary `#include` paths to the `app` requirements as values of
the `<include>` feature, but then this work will be repeated for all
programs that use `foo`. A better solution is to modify
`util/foo/Jamfile` in this way:
[source]
----
project
: usage-requirements <include>.
;
lib foo : foo.cpp ;
----
Usage requirements are applied not to the target being declared but to
its dependents. In this case, `<include>.` will be applied to all
targets that directly depend on `foo`.
Another improvement is using symbolic identifiers to refer to the
library, as opposed to `Jamfile` location. In a large project, a library
can be used by many targets, and if they all use `Jamfile` location, a change
in directory organization entails much work.
The solution is to use project ids—symbolic names not tied to directory
layout. First, we need to assign a project id by adding this code to
`Jamfile`:
[source]
----
use-project /library-example/foo : util/foo ;
----
Second, we modify `app/Jamfile` to use the project id:
[source]
----
exe app : app.cpp /library-example/foo//bar ;
----
The `/library-example/foo//bar` syntax is used to refer to the target
`bar` in the project with id `/library-example/foo`. We've achieved our
goal—if the library is moved to a different directory, only `top/Jamfile`
must be modified. Note that project ids are global—two Jamfiles
are not allowed to assign the same project id to different directories.
[TIP]
====
If you want all applications in some project to link to a certain
library, you can avoid having to specify directly the sources of every
target by using the `<library>` property. For example, if
`/boost/filesystem//fs` should be linked to all applications in your
project, you can add `<library>/boost/filesystem//fs` to the project's
requirements, like this:
[source]
----
project
: requirements <library>/boost/filesystem//fs
;
----
====
[[bbv2.tutorial.linkage]]
== Static and shared libraries
Libraries can be either _static_, which means they are included in
executable files that use them, or _shared_ (a.k.a. _dynamic_), which
are only referred to from executables, and must be available at run
time. B2 can create and use both kinds.
The kind of library produced from a `lib` target is determined by the
value of the `link` feature. Default value is `shared`, and to build a
static library, the value should be `static`. You can request a static
build either on the command line:
[source,shell]
----
b2 link=static
----
or in the library's requirements:
[source]
----
lib l : l.cpp : <link>static ;
----
We can also use the `<link>` property to express linking requirements on
a per-target basis. For example, if a particular executable can be
correctly built only with the static version of a library, we can
qualify the executable's link:#bbv2.reference.targets.references[target
reference] to the library as follows:
[source]
----
exe important : main.cpp helpers/<link>static ;
----
No matter what arguments are specified on the `b2` command line,
`important` will only be linked with the static version of `helpers`.
Specifying properties in target references is especially useful if you
use a library defined in some other project (one you can't change) but
you still want static (or dynamic) linking to that library in all cases.
If that library is used by many targets, you _could_ use target
references everywhere:
[source]
----
exe e1 : e1.cpp /other_project//bar/<link>static ;
exe e10 : e10.cpp /other_project//bar/<link>static ;
----
but that's far from being convenient. A better approach is to introduce
a level of indirection. Create a local `alias` target that refers to the
static (or dynamic) version of `foo`:
[source]
----
alias foo : /other_project//bar/<link>static ;
exe e1 : e1.cpp foo ;
exe e10 : e10.cpp foo ;
----
The link:#bbv2.tasks.alias[alias] rule is specifically used to rename a
reference to a target and possibly change the properties.
[TIP]
====
When one library uses another, you put the second library in the source
list of the first. For example:
[source]
----
lib utils : utils.cpp /boost/filesystem//fs ;
lib core : core.cpp utils ;
exe app : app.cpp core ;
----
This works no matter what kind of linking is used. When `core` is built as a
shared library, links `utils` directly into it. Static libraries can't link
to other libraries, so when `core` is built as a static library, its
dependency on `utils` is passed along to `core`'s dependents, causing `app`
to be linked with both `core` and `utils`.
====
NOTE: (Note for non-UNIX system). Typically, shared libraries must be
installed to a directory in the dynamic linker's search path. Otherwise,
applications that use shared libraries can't be started. On Windows, the
dynamic linker's search path is given by the `PATH` environment variable.
This restriction is lifted when you use B2 testing
facilities—the `PATH` variable will be automatically adjusted before
running the executable.
[[bbv2.tutorial.conditions]]
== Conditions and alternatives
Sometimes, particular relationships need to be maintained among a
target's build properties. For example, you might want to set specific
`#define` when a library is built as shared, or when a target's
`release` variant is built. This can be achieved using _conditional
requirements_.
[source]
----
lib network : network.cpp
: <link>shared:<define>NETWORK_LIB_SHARED
<variant>release:<define>EXTRA_FAST
;
----
In the example above, whenever `network` is built with `<link>shared`,
`<define>NETWORK_LIB_SHARED` will be in its properties, too. Also, whenever
its release variant is built, `<define>EXTRA_FAST` will appear in its
properties.
Sometimes the ways a target is built are so different that describing
them using conditional requirements would be hard. For example, imagine
that a library actually uses different source files depending on the
toolset used to build it. We can express this situation using target
_alternatives_:
[source]
----
lib demangler : dummy_demangler.cpp ; # <1>
lib demangler : demangler_gcc.cpp : <toolset>gcc ; # <2>
lib demangler : demangler_msvc.cpp : <toolset>msvc ; # <3>
----
When building `demangler`, B2 will compare requirements for
each alternative with build properties to find the best match. For
example, when building with `<toolset>gcc` alternative *(2)*, will be
selected, and when building with `<toolset>msvc` alternative *(3)* will be
selected. In all other cases, the most generic alternative *(1)* will be
built.
[[bbv2.tutorial.prebuilt]]
== Prebuilt targets
To link to libraries whose build instructions aren't given in a Jamfile,
you need to create `lib` targets with an appropriate `file` property.
Target alternatives can be used to associate multiple library files with
a single conceptual target. For example:
[source]
----
# util/lib2/Jamfile
lib lib2
:
: <file>lib2_release.a <variant>release
;
lib lib2
:
: <file>lib2_debug.a <variant>debug
;
----
This example defines two alternatives for `lib2`, and for each one names
a prebuilt file. Naturally, there are no sources. Instead, the `<file>`
feature is used to specify the file name.
Once a prebuilt target has been declared, it can be used just like any
other target:
[source]
----
exe app : app.cpp ../util/lib2//lib2 ;
----
As with any target, the alternative selected depends on the properties
propagated from `lib2`'s dependents. If we build the release and debug
versions of `app` it will be linked with `lib2_release.a` and
`lib2_debug.a`, respectively.
System libraries — those that are automatically found by the toolset by
searching through some set of predetermined paths — should be declared
almost like regular ones:
[source]
----
lib pythonlib : : <name>python22 ;
----
We again don't specify any sources, but give a `name` that should be
passed to the compiler. If the gcc toolset were used to link an
executable target to `pythonlib`, `-lpython22` would appear in the
command line (other compilers may use different options).
We can also specify where the toolset should look for the library:
[source]
----
lib pythonlib : : <name>python22 <search>/opt/lib ;
----
And, of course, target alternatives can be used in the usual way:
[source]
----
lib pythonlib : : <name>python22 <variant>release ;
lib pythonlib : : <name>python22_d <variant>debug ;
----
A more advanced use of prebuilt targets is described in
link:#bbv2.recipes.site-config[the section called “Targets in
site-config.jam”].

View File

@@ -0,0 +1,108 @@
[[bbv2.reference.modules.type]]
= type
Deals with target type declaration and defines target class which
supports typed targets.
1. [[bbv2.reference.modules.type.register]] `rule register ( type : suffixes * : base-type ? )`
+
Registers a target type, possible derived from a `base-type`. Providing
a list of suffixes here is a shortcut for separately calling the
link:#bbv2.reference.modules.type.register-suffixes[register-suffixes]
rule with the given suffixes and the
link:#bbv2.reference.modules.type.set-generated-target-suffix[set-generated-target-suffix]
rule with the first given suffix.
2. [[bbv2.reference.modules.type.register-suffixes]] `rule register-suffixes ( suffixes + : type )`
+
Specifies that files with suffix from `suffixes` be recognized as
targets of type `type`. Issues an error if a different type is already
specified for any of the suffixes.
3. [[bbv2.reference.modules.type.registered]] `rule registered ( type )`
+
Returns true iff type has been registered.
4. [[bbv2.reference.modules.type.validate]] `rule validate ( type )`
+
Issues an error if `type` is unknown.
5. [[bbv2.reference.modules.type.set-scanner]] `rule set-scanner ( type : scanner )`
+
Sets a scanner class that will be used for this type.
6. [[bbv2.reference.modules.type.get-scanner]] `rule get-scanner ( type : property-set )`
+
Returns a scanner instance appropriate to `type` and `property-set`.
7. [[bbv2.reference.modules.type.base]] `rule base ( type )`
+
Returns a base type for the given type or nothing in case the given type
is not derived.
8. [[bbv2.reference.modules.type.all-bases]] `rule all-bases ( type )`
+
Returns the given type and all of its base types in order of their
distance from type.
9. [[bbv2.reference.modules.type.all-derived]] `rule all-derived ( type )`
+
Returns the given type and all of its derived types in order of their
distance from type.
10. [[bbv2.reference.modules.type.is-derived]] `rule is-derived ( type base )`
+
Returns true if `type` is equal to `base` or has `base` as its direct or
indirect base.
11. [[bbv2.reference.modules.type.set-generated-target-suffix]] `rule set-generated-target-suffix ( type : properties * : suffix )`
+
Sets a file suffix to be used when generating a target of `type` with
the specified properties. Can be called with no properties if no suffix
has already been specified for the `type`. The `suffix` parameter can be
an empty string (`""`) to indicate that no suffix should be used.
+
Note that this does not cause files with `suffix` to be automatically
recognized as being of `type`. Two different types can use the same
suffix for their generated files but only one type can be auto-detected
for a file with that suffix. User should explicitly specify which one
using the
link:#bbv2.reference.modules.type.register-suffixes[register-suffixes]
rule.
12. [[bbv2.reference.modules.type.change-generated-target-suffix]] `rule change-generated-target-suffix ( type : properties * : suffix )`
+
Change the suffix previously registered for this type/properties
combination. If suffix is not yet specified, sets it.
13. [[bbv2.reference.modules.type.generated-target-suffix]] `rule generated-target-suffix ( type : property-set )`
+
Returns the suffix used when generating a file of `type` with the given
properties.
14. [[bbv2.reference.modules.type.set-generated-target-prefix]] `rule set-generated-target-prefix ( type : properties * : prefix )`
+
Sets a target prefix that should be used when generating targets of
`type` with the specified properties. Can be called with empty
properties if no prefix for `type` has been specified yet.
+
The `prefix` parameter can be empty string (`""`) to indicate that no
prefix should be used.
+
Usage example: library names use the `"lib"` prefix on unix.
15. [[bbv2.reference.modules.type.change-generated-target-prefix]] `rule change-generated-target-prefix ( type : properties * : prefix )`
+
Change the prefix previously registered for this type/properties
combination. If prefix is not yet specified, sets it.
16. [[bbv2.reference.modules.type.generated-target-prefix]] `rule generated-target-prefix ( type : property-set )`
+
Returns the prefix used when generating a file of `type` with the given
properties.
17. [[bbv2.reference.modules.type.type]] `rule type ( filename )`
+
Returns file type given its name. If there are several dots in filename,
tries each suffix. E.g. for name of "file.so.1.2" suffixes "2", "1", and
"so" will be tried.

View File

@@ -0,0 +1,54 @@
[[bbv2.reference.class.typed-target]]
= Class typed-target
[source,jam]
----
class typed-target : basic-target {
rule __init__ ( name : project : type : sources * : requirements * : default-build * : usage-requirements * )
rule type ( )
rule construct ( name : source-targets * : property-set )
# Methods inherited from abstract-target
rule name ( )
rule project ( )
rule location ( )
rule full-name ( )
# Methods inherited from basic-target
rule generate ( property-set )
}
----
link:#bbv2.reference.class.typed-target[typed-target] is the most common
kind of target alternative. Rules for creating typed targets are defined
automatically for each type.
--
1. `rule __init__ ( name : project : type : sources * : requirements * : default-build * : usage-requirements * )`
+
`name`::
The name of the target
`project`::
The link:#bbv2.reference.class.project-target[project] in which the
target is declared.
`type`::
The link:#bbv2.reference.modules.type[type] of the target.
2. `rule type ( )`
+
Returns the link:#bbv2.reference.modules.type[type] of the target.
3. `rule construct ( name : source-targets * : property-set )`
+
Implements
link:#bbv2.reference.class.basic-target.construct[basic-target.construct].
Attempts to create a target of the correct type using generators
appropriate for the given
link:#bbv2.reference.class.property-set[property-set]. Returns a
link:#bbv2.reference.class.property-set[property-set] containing the
usage requirements and a list of virtual targets.
+
NOTE: This function is invoked automatically by
link:#bbv2.reference.class.basic-target.generate[basic-target.generate]
and should not be called directly by users.
--

View File

@@ -0,0 +1,3 @@
= The Dangerous and Thrilling Documentation Chronicles
This journey begins on a bleary Monday morning.

View File

@@ -0,0 +1,38 @@
= b2(1)
Rene Rivera
v0.0.0
:doctype: manpage
:manmanual: B2
:mansource: B2
:man-linkstyle: pass:[blue R < >]
== NAME
b2 - Boost Build
== SYNOPSIS
*b2* ['OPTION']... 'TARGET'...
== OPTIONS
*-n*::
Print out what would get built.
== EXIT STATUS
*0*::
Success.
*1*::
Failure.
== RESOURCES
*Project web site:* http://boost.org
== COPYING
Copyright \(C) 2017 {author}. +
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.txt or copy at https://www.bfgroup.xyz/b2/LICENSE.txt)

View File

@@ -0,0 +1,11 @@
#|
Copyright 2017 Rene Rivera
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE.txt or copy at
https://www.bfgroup.xyz/b2/LICENSE.txt)
|#
html example_html : example.adoc ;
manpage example_1 : example_manpage.adoc ;
pdf example_pdf : example.adoc ;
docbook example_docbook : example.adoc ;

View File

@@ -0,0 +1,6 @@
# Copyright 2002, 2003 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
boost-build ../src/kernel ;

View File

@@ -0,0 +1,8 @@
import feature ;
feature.feature tblgen : : dependency free ;
project built_tool ;
build-project core ;

View File

@@ -0,0 +1,39 @@
import toolset ;
import os ;
project : requirements <tblgen>../tblgen//tblgen ;
# Create a.c using a custom action defined below.
make a.c : a.td : @tblgen ;
# Use a.c in executable.
exe core : core.cpp a.c ;
# The action has to invoke the tool built in other
# parts of the project. The <tblgen> feature is used
# to specify the location of the tool, and the flags
# statement below make the full path to the tool
# available inside the action.
toolset.flags tblgen COMMAND <tblgen> ;
# We generally want a.c to be rebuilt when the tool changes.
rule tblgen ( targets * : sources * : properties * )
{
DEPENDS $(targets) : [ on $(targets) return $(COMMAND) ] ;
}
# The action that invokes the tool
actions tblgen bind COMMAND
{
$(COMMAND:E=tblgen) > $(<)
}
if [ os.name ] = VMS
{
actions tblgen bind COMMAND
{
PIPE MCR $(COMMAND:WE=tblgen) > $(<:W)
}
}

View File

@@ -0,0 +1,5 @@
int main()
{
return 0;
}

View File

@@ -0,0 +1,5 @@
This example shows how to build an executable and then use it
for generating other targets. The 'tblgen' subdirectory builds
a tool, while the 'core' subdirectory uses that tool. Refer
to core/Jamfile.jam for detailed comments.

View File

@@ -0,0 +1,4 @@
project : requirements -<tblgen>tblgen//tblgen ;
exe tblgen : tblgen.cpp ;

View File

@@ -0,0 +1,9 @@
#include <iostream>
int main()
{
std::cout << "int foo;\n";
return 0;
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2014 Rene Rivera
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE.txt or copy at
// https://www.bfgroup.xyz/b2/LICENSE.txt)
#include <iostream>
#include <cstdlib>
int main()
{
std::cout << "Bye!\n";
return EXIT_FAILURE
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2014 Rene Rivera
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE.txt or copy at
// https://www.bfgroup.xyz/b2/LICENSE.txt)
#include <iostream>
#include <cstdlib>
int main()
{
std::cout << "Bye!\n";
return EXIT_FAILURE;
}

View File

@@ -0,0 +1,15 @@
# Copyright 2016 Rene Rivera
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
using testing ;
import property-set ;
import path ;
exe success : success.cpp ;
run success : arg1 arg2 : : : success-a ;
run success : arg3 arg4 : : : success-b ;
run post.cpp : : success-a : : post-a ;
run post.cpp : : success-b : : post-b ;

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2014 Rene Rivera
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE.txt or copy at
// https://www.bfgroup.xyz/b2/LICENSE.txt)
#include <iostream>
#include <cstdlib>
int main(int argc, char *argv[])
{
std::cout << argv[1] << "\n";
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2014 Rene Rivera
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE.txt or copy at
// https://www.bfgroup.xyz/b2/LICENSE.txt)
#include <iostream>
#include <cstdlib>
int main(int argc, char *argv[])
{
std::cout << "Hi!\n";
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,7 @@
class_template
class %class_name% {
public:
%class_name%() {}
~%class_name%() {}
};

View File

@@ -0,0 +1,36 @@
// (C) Copyright Vladimir Prus, 2003
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE.txt or copy at
// https://www.bfgroup.xyz/b2/LICENSE.txt)
// Please see 'usage.verbatim' file for usage notes.
#include <iostream>
#include <string>
#include <cstring>
using std::cout;
using std::string;
using std::strlen;
extern const char class_template[];
extern const char usage[];
int main(int ac, char* av[])
{
if (av[1]) {
string class_name = av[1];
string s = class_template;
string::size_type n;
while((n = s.find("%class_name%")) != string::npos) {
s.replace(n, strlen("%class_name%"), class_name);
}
std::cout << "Output is:\n";
std::cout << s << "\n";
return 0;
} else {
std::cout << usage << "\n";
return 1;
}
}

View File

@@ -0,0 +1,44 @@
#!/usr/bin/python
# Copyright 2003 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
import sys
from string import strip
def quote_line(line):
result = ""
for i in line:
if (i == '\\'):
result = result + '\\\\'
elif (i == '\"'):
result = result + '\\\"'
elif (i != '\r' and i != '\n'):
result = result + i;
return '\"' + result + '\\n\"'
def quote_file(file):
result = ""
for i in file.readlines():
result = result + quote_line(i) + "\n"
return result
if len(sys.argv) < 3:
print "Usage: inline_file.py output_c_file file_to_include"
else:
output_c_file = sys.argv[1]
out_file = open(output_c_file, "w");
file_to_include = sys.argv[2]
in_file = open(file_to_include, "r");
variable_name = strip(in_file.readline())
out_file.write("extern const char %s[] = {\n%s};\n\n" % (variable_name, quote_file(in_file)))
in_file.close()
out_file.close()

View File

@@ -0,0 +1,9 @@
# Copyright 2003 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
import verbatim ;
exe codegen : codegen.cpp class.verbatim usage.verbatim
t1.verbatim ;

View File

@@ -0,0 +1,11 @@
Copyright 2003 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)
This example show how to add a new target type and a new tool support to
B2. Please refer to extender manual for a complete description of this
example.
Note that this example requires Python. If cygwin Python on Windows is to be
used, please go to "verbatim.jam" and follow instructions there.

View File

@@ -0,0 +1,2 @@
t1
//###include "t2.verbatim"

View File

@@ -0,0 +1,5 @@
usage
Usage: codegen class_name
This program takes a template of C++ code and replaces of all occurrences of
%class_name% with the passed 'class_name' parameter.

View File

@@ -0,0 +1,61 @@
# Copyright 2003, 2004 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
# This file shows some of the primary customization mechanisms in B2 V2
# and should serve as a basic for your own customization.
# Each part has a comment describing its purpose, and you can pick the parts
# which are relevant to your case, remove everything else, and then change names
# and actions to taste.
import os ;
# Declare a new target type. This allows B2 to do something sensible
# when targets with the .verbatim extension are found in sources.
import type ;
type.register VERBATIM : verbatim ;
# Declare a dependency scanner for the new target type. The
# 'inline-file.py' script does not handle includes, so this is
# only for illustraction.
import scanner ;
# First, define a new class, derived from 'common-scanner',
# that class has all the interesting logic, and we only need
# to override the 'pattern' method which return regular
# expression to use when scanning.
class verbatim-scanner : common-scanner
{
rule pattern ( )
{
return "//###include[ ]*\"([^\"]*)\"" ;
}
}
# Register the scanner class. The 'include' is
# the property which specifies the search path
# for includes.
scanner.register verbatim-scanner : include ;
# Assign the scanner class to the target type.
# Now, all .verbatim sources will be scanned.
# To test this, build the project, touch the
# t2.verbatim file and build again.
type.set-scanner VERBATIM : verbatim-scanner ;
import generators ;
generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
# Note: To use Cygwin Python on Windows change the following line
# to "python inline_file.py $(<) $(>)"
# Also, make sure that "python" in in PATH.
actions inline-file
{
"./inline_file.py" $(<) $(>)
}
if [ os.name ] = VMS
{
actions inline-file
{
python inline_file.py $(<:W) $(>:W)
}
}

View File

@@ -0,0 +1,47 @@
# Copyright 2010 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
# This file is only used with Python port of Boost.Build
# This file shows some of the primary customization mechanisms in Boost.Build V2
# and should serve as a basic for your own customization.
# Each part has a comment describing its purpose, and you can pick the parts
# which are relevant to your case, remove everything else, and then change names
# and actions to taste.
# Declare a new target type. This allows Boost.Build to do something sensible
# when targets with the .verbatim extension are found in sources.
import b2.build.type as type
type.register("VERBATIM", ["verbatim"])
# Declare a dependency scanner for the new target type. The
# 'inline-file.py' script does not handle includes, so this is
# only for illustraction.
import b2.build.scanner as scanner;
# First, define a new class, derived from 'common-scanner',
# that class has all the interesting logic, and we only need
# to override the 'pattern' method which return regular
# expression to use when scanning.
class VerbatimScanner(scanner.CommonScanner):
def pattern(self):
return "//###include[ ]*\"([^\"]*)\""
scanner.register(VerbatimScanner, ["include"])
type.set_scanner("VERBATIM", VerbatimScanner)
import b2.build.generators as generators
generators.register_standard("verbatim.inline-file",
["VERBATIM"], ["CPP"])
from b2.manager import get_manager
get_manager().engine().register_action("verbatim.inline-file",
"""
./inline_file.py $(<) $(>)
""")

View File

@@ -0,0 +1,11 @@
# Copyright 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)
This example shows the 'generate' rule, that allows you to construct target
using any arbitrary set of transformation and commands.
The rule is similar to 'make' and 'notfile', but unlike those, you can operate
in terms of B2 'virtual targets', which is more flexible.
Please consult the docs for more explanations.

View File

@@ -0,0 +1,10 @@
int main()
{
}
/*
Copyright 2007 Vladimir Prus
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
*/

View File

@@ -0,0 +1,26 @@
import "class" : new ;
import common ;
rule generate-example ( project name : property-set : sources * )
{
local result ;
for local s in $(sources)
{
#local source-name = [ $(s).name ] ;
#local source-action = [ $(s).action ] ;
#local source-properties = [ $(source-action).properties ] ;
# Create a new action, that takes the source target and runs the
# 'common.copy' command on it.
local a = [ new non-scanning-action $(s) : common.copy : $(property-set)
] ;
# Create a target to represent the action result. Uses the target name
# passed here via the 'name' parameter and the same type and project as
# the source.
result += [ new file-target $(name) : [ $(s).type ] : $(project) : $(a)
] ;
}
return $(result) ;
}

View File

@@ -0,0 +1,16 @@
from b2.build.virtual_target import NonScanningAction, FileTarget
def generate_example(project, name, ps, sources):
result = []
for s in sources:
a = NonScanningAction([s], "common.copy", ps)
# Create a target to represent the action result. Uses the target name
# passed here via the 'name' parameter and the same type and project as
# the source.
result.append(FileTarget(name, s.type(), project, a))
return result

View File

@@ -0,0 +1,9 @@
# Copyright 2007 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
import generate ;
import gen ;
generate a2 : a.cpp : <generating-rule>@gen.generate-example ;

View File

@@ -0,0 +1,6 @@
# Copyright 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)
This example shows how to declare a new generator class. It is necessary when
generator's logic is more complex that just running a single tool.

View File

@@ -0,0 +1,10 @@
int main()
{
return 0;
}
/*
Copyright 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)
*/

View File

@@ -0,0 +1,6 @@
# Copyright 2006 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
import soap ;
exe foo : foo.gci : <server>on ;

View File

@@ -0,0 +1,86 @@
# Copyright 2006 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
# This is example of a fictional code generator tool.
# It accepts a single input of type '.gci' and produces
# either one or two outputs of type .cpp, depending
# on the value of the feature <server-mode>
#
# This example is loosely based on gSOAP code generator.
import type ;
import generators ;
import feature ;
import common ;
import "class" : new ;
import os ;
type.register GCI : gci ;
feature.feature server : off on : incidental ;
class soap-generator : generator
{
import "class" : new ;
rule __init__ ( * : * )
{
generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
}
rule run ( project name ? : property-set : sources * )
{
if ! $(sources[2])
{
# Accept only single source.
local t = [ $(sources[1]).type ] ;
if $(t) = GCI
{
# The type is correct.
# If no output name is specified, guess it from sources.
if ! $(name)
{
name = [ generator.determine-output-name $(sources) ] ;
}
# Produce one output, using just copy.
local a = [ new action $(sources[1])
: common.copy : $(property-set) ] ;
local t = [ new file-target $(name) : CPP : $(project)
: $(a) ] ;
# If in server mode, create another output -- an
# empty file. If this were a real SOAP generator, we
# might have created a single action, and two targets
# both using that action.
local t2 ;
if [ $(property-set).get <server> ] = "on"
{
local a = [ new action : soap.touch : $(property-set) ] ;
t2 = [ new file-target $(name)_server : CPP : $(project)
: $(a) ] ;
}
return [ virtual-target.register $(t) ]
[ virtual-target.register $(t2) ] ;
}
}
}
}
generators.register [ new soap-generator soap.soap : GCI : CPP ] ;
TOUCH = [ common.file-touch-command ] ;
actions touch
{
$(TOUCH) $(<)
}
if [ os.name ] = VMS
{
actions touch
{
$(TOUCH) $(<:W)
}
}

View File

@@ -0,0 +1,26 @@
# Copyright 2003, 2006 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
# Declare a main target.
exe main : main.cpp ;
# Declare an action for updating translations
# After changing main.cpp, invocation of
#
# bjam update-russian
#
# will update translations in russian.po
gettext.update update-russian : russian.po main ;
# Compiled message catalog.
gettext.catalog russian : russian.po ;
# A stage rule which installs message catalog to the
# location gettext expects.
stage messages-russian : russian
: <location>messages/ru_RU.KOI8-R/LC_MESSAGES
<name>main.mo
;

View File

@@ -0,0 +1,6 @@
# Copyright 2003 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
using gettext ;

Some files were not shown because too many files have changed in this diff Show More