[build2-announce] build2 0.18.1 released
Boris Kolpackov
boris at codesynthesis.com
Thu Apr 16 12:29:55 UTC 2026
We have released build2 toolchain version 0.18.1 (0.18.0 had regressions
and was not published).
While this version again contains a large number of new features, especially
in the build system, another area of focus for this release was performance
work across the toolchain. The package manager can now fetch, unpack, and
configure packages faster, thanks, in particular, to the new fetch cache.
The build system also saw a number of performance improvements, including
optimized builds for read-only projects (such as dependencies).
This release makes available the official binary packages for Windows and
a number of Linux distributions (Debian, Ubuntu, Fedora, RHEL, generic
Linux) with packages for Mac OS available from Homebrew and for FreeBSD --
from ports.
The corresponding NEWS file entries are included below with a more detailed
discussion of the major new features available in the release notes:
https://build2.org/release/0.18.0.xhtml
This release has been tested on Windows, Linux (x86_64 and aarch64), Mac OS
(x86_64 and aarch64), and FreeBSD with GCC, Clang (both vanilla and Apple's),
MinGW GCC, and MSVC (14, 15, 16, 17, 18). A big thank you to everyone who
helped test the development snapshots and the release candidate.
Installing from the binary packages:
https://build2.org/install.xhtml
Installing from source:
https://build2.org/install-src.xhtml
A note on backwards compatibility: if building from source, this release
cannot be upgraded to from 0.17.0 and has to be installed from scratch.
Download page:
https://build2.org/download.xhtml
SHA256 checksums for the toolchain source packages:
22b5e8e51fba6461954d2363884969ad760ee031b5b1a024c7e0b4913a2125f1 *build2-install-0.18.1.sh
0f3d5afdfbcd8f400a75ff548c82eaac58644f7f2757fb9448daf2a97510a0fe *build2-install-msvc-0.18.1.bat
5f05a19691eac317ffea46870f9191a5c948eb22774b5ed14c26c256178a0d0c *build2-install-clang-0.18.1.bat
71ea9dc27b6ddfbbe12f5a8fb59bf46a21b75c53d0e7d85f6627dd391195a27c *build2-install-mingw-0.18.1.bat
23b1719f1d8d1ef1957c2b28bc12177aa70d23d73de79889c2f5041d293692bc *build2-toolchain-0.18.1.tar.gz
a5f3eab9d4522bc22704899593dd6c7013349a1b8c37278c8b2321073e25ff16 *build2-toolchain-0.18.1.tar.xz
894603fb64c0d4c405d6d6d33be60a1f8f78e8a8446d869387b3794ee38f6631 *build2-baseutils-0.18.1-x86_64-windows.zip
a303ff26a7e5de6a4be4c818fc7a9cb3e0e4beb7d7302aea69388c95985dad76 *build2-mingw-0.18.1-x86_64-windows.tar.xz
SHA256 checksums for the toolchain binary packages:
fe9300de9afb21d6c8c032955979ab85389597b621e3170c70cd3c1a0e89a2aa *build2-toolchain_0.18.1-0~ubuntu24.04_amd64.deb
ead587ac6ffbff2e678b7b68648b12c5f21324fb01cfb3d7cd86dc486355b389 *build2-toolchain_0.18.1-0~ubuntu22.04_amd64.deb
b600b87425ecf37ec28c258aae9ec3fddb63de2e48a4afe45892519562f60ccd *build2-toolchain_0.18.1-0~debian13_amd64.deb
285db3c375bd8d2f650dd16932cd55706a569c15c21ce2f0d82bbdf7819fc811 *build2-toolchain_0.18.1-0~debian11_amd64.deb
20a979e034ca69ed65d06c7baa471bc986d62259ff5ef8c4a4898d37be0a741b *build2-toolchain_0.18.1-0~debian12_amd64.deb
d2576766e5bef9331596ca9ae1482a1ae93c7ffad37d29648d72f32160270009 *build2-toolchain-0.18.1-x86_64-linux-glibc2.31-gcc10.tar.xz
d6b34bcc492d83e6f6a267f7a980a1508850b832a1ef1eed09eaa4b71f02ecfe *build2-toolchain-0.18.1-x86_64-windows10-msvc17.zip
bc6e12a44bc0c2903bcfe34316334bb5ecc5aeddba105b328bcb18bec0cbeba1 *build2-toolchain-0.18.1-x86_64-windows10-mingw-gcc14.zip
280f67f43d87ac19d7ec2dc00584bb3b2508e1703f7f08eef1e59c38629ccf25 *build2-toolchain-0.18.1-1.el9.x86_64.rpm
b800877a7b0eb7a7a466002b81803a071e1a346881771f075eb8d991755a0f8f *build2-toolchain-0.18.1-1.el8.x86_64.rpm
a1f5d8c3298d3fc097c460ad5fda850d06cc8ab43f0a15c05f5a0168bd7b2648 *build2-toolchain-0.18.1-1.fc42.x86_64.rpm
9ec47178a0dfd8507966dafe56fbe724db7c93730a780400441acbc887cf276f *build2-toolchain-0.18.1-1.fc43.x86_64.rpm
Repository certificate fingerprint for cppget.org:
70:64:FE:E4:E0:F3:60:F1:B4:51:E1:FA:12:5C:E0:B3:DB:DF:96:33:39:B9:2E:E5:C2:68:63:4C:A6:47:39:43
NEWS file entries:
build2 version 0.18.0
---------------------
* Support for `while`-loop in the Buildfile language.
See the "Buildfile Language" section in the manual for details.
* Support for `continue` and `break` in loops in the Buildfile and scripting
languages.
* `ifn` and `ife` shortcuts in the Buildfile and scripting languages.
These flow control shortcuts allow more succinct expression of is/is-not
\c{null} and empty checks. They are equivalent to the following more
verbose expressions:
ifn ... ~ if $null(...)
ife ... ~ if $empty(...)
ifn! ... ~ if! $null(...)
ife! ... ~ if! $empty(...)
elifn ... ~ elif $null(...)
elife ... ~ elif $empty(...)
elifn! ... ~ elif! $null(...)
elife! ... ~ elif! $empty(...)
* New Buildfile and scripting language functions:
- $front(), $back() and $json.array_front(), $json.array_back()
Return first/last element in a sequence.
- $sha256sum(), $xxh64sum()
Compute SHA256 and XXH64 checksums of a string.
- $builtin.generate_uuid()
Generate UUID.
- $string.{compare,filter,filter_out}()
Compare or filter/filter out strings.
There is now also support for the `contains`, `contains_once`,
`starts_with`, and `ends_with` flags in $string.{find,find_index}().
- $process.search()
Search in PATH to determine absolute executable path.
* New scripting languages builtins:
- sha256sum
Compute SHA256 checksum of a file or stdin.
- xxh64sum
Compute XXH64 checksum of a file or stdin.
Also, the `ln` builtin now supports creating hard links in addition to
symbolic.
* New json{} builtin target type.
It represents a JSON text file and has the .json default extension.
* Shell script and task runner executable.
The portable scripting language that is used for buildfile recipes
(Buildscript) and test scripts (Testscript) has been generalized to also
provide a general-purpose shell scripting flavor (Shellscript). Such shell
scripts can be executed with the `bx` executable which is now provided
alongside the build system driver (`b`). See the bx(1) man page for
details.
* Buildscript/Testscript/Shellscript syntax version 2.
The version 2 is an improved syntax that should be used in new projects.
Existing projects should also be eventually migrated to the new syntax.
The syntax changes in version 2 compared to version 1 are:
- Flow-control constructs (`if`, `for`, etc) are no longer terminated with
the `end` line. Instead, the commands inside need to be enclosed into
curly braces, which can be omitted for a single command. For example,
syntax 1:
if true
echo one
echo two
end
if true
echo one
end
Syntax 2:
if true
{
echo one
echo two
}
if true
echo one
- Testscript groups are now enclosed into double curly braces ({{ }}).
For example, syntax 1:
: basics
:
{
: test1
:
$* test1
: test2
:
$* test2
}
Syntax 2:
: basics
:
{{
: test1
:
$* test1
: test2
:
$* test2
}}
- Testscript commands in explicit test scopes are no longer separated with
semicolons. For example, syntax 1:
: test1
:
{
$* pre;
$* test1;
$* post
}
Syntax 2:
: test1
:
{
$* pre
$* test1
$* post
}
The syntax version is selected based on the project's build2 version
constraint in the manifest (`depends: build2 >= X.Y.Z`). Specifically, if
the required version is equal to or great than 0.18.0, then syntax 2 is
automatically selected. Otherwise, version 1 is used for backwards
compatibility.
The desired syntax can also be specified explicitly, both at the buildfile
and script levels, with the {shellscript,buildscript,testscript}.syntax
variables. For example:
# root.build
#
testscript.syntax = 1
* Support for JSON compilation database generation and maintenance.
See the "Compilation Database" section in the "cc Module" chapter of
the manual for details.
* Support for specifying compile options on exe/lib{} targets
It is now possible to specify compile option (*.poptions and *.coptions)
on the exe/lib{} targets (we call them "binary-specific compile
options"). Such options are propagated to obj/bmi{} targets that are
synthesized for source prerequisites of the binary. Note that this
propagation does not apply to explicit (non-synthesized) obj/bmi{}
prerequisites. For example:
exe{foo}: cxx{foo} obj{common}
{
cxx.poptions += -DFOO
}
exe{bar}: cxx{bar} obj{common}
{
cxx.poptions += -DBAR
}
obj{common}: cxx{common}
{
cxx.poptions += -DCOMMON
}
In this example, cxx{foo} will be compiled with -DFOO, cxx{bar} -- with
-DBAR, and cxx{common} -- with -DCOMMON. Refer to the "C-Common
Configuration Variables" section in the manual for details.
* Support for JSON5 and JSON5E.
The existing JSON support has been extended to additionally cover JSON5[1]
and JSON5E[2]. Specifically, the $json.parse() and $json.load() functions
can now be instructed with flags to parse in the JSON5 or JSON5E mode
(JSON is the default). For example:
j = $json.load($src_root/test.json5, json5)
j = $json.parse('{line: 10, column: 20}', json5)
j = $json.parse('line: 10, column: 20', json5e)
Additionally, when constructing a JSON value in buildfiles, the input
text is parsed as JSON5E, not as JSON. For example, before we had to
write:
j = [json] '{"one":255, "two":[2, 3, 4], "three":{"x":1, "y":-1}}'
Now we can rewrite it as:
j = [json] '{one:0xff, two:[2, 3, 4], three:{x:1, y:-1}}'
Or in the multi-line form (notice the trailing comma which is allowed in
JSON5):
j = [json] '{
one : 0xff,
two : [2, 3, 4],
three : {x:1, y:-1},
}'
While JSON5 has a number of extensions compared to JSON (and JSON5E
adds a few more), the most useful in buildfiles will likely be:
- Ability to use unquoted object member names.
- Ability to use hexadecimal numbers.
- Ability to use single-quoted strings in addition to double-quoted.
The last one (single-quoted string) can be especially handy if you need to
perform expansions in the input text and thus need to use double outer
quotes. For example:
n = 123
s = abc
j = [json] "{number:$n, string:'$s'}"
Note that the implied top-level object feature of JSON5E is not supported
in the construction syntax but is supported by $json.parser() and
$json.load() when parsing in the JSON5E mode.
[1] https://json5.org
[2] https://github.com/boris-kolpackov/libpdjson5/blob/master/JSON5E.md
* Ability to specify negative values for the -j|--jobs option.
If the value is negative, then the number of available hardware threads
is reduced by this value.
* Support for updating targets during buildfile load.
Updating a target during load is primarily useful when the information it
contains is required in the buildfile itself. For example, we may need to
know the target architecture byte-order in order to decide which source
files must be included into the build. And, at least in case of the C/C++
compilation, the only reliable source of this information are the compiler
macros. To extract this information from the compiler and make it
available during the buildfile evaluation, we can generate a buildfile
fragment during load and then source it into the main buildfile (or,
alternatively, generate a JSON file and load it into a buildfile
variable). See the `update` directive in the manual for details.
* Ability to mark projects as readonly.
Each project now automatically gets the config.<project>.build.readonly
special configuration variable. If this variable is set to true or if the
parent project is marked readonly, then the project's sources are assumed
to be readonly.
Note that this is not a guarantee, just an assumption that they are not
routinely or frequently changed and that an mtime-based change detection
is sufficient. Note also that we make the same assumption about files
outside of any project.
The effective value (specified or inherited) is also available (starting
from root.build) as the build.readonly project-specific variable.
* Revamped C++ standard library modules discovery.
Specifically, for both Clang and GCC we now use -fprint-file-name to find
a suitable .module.json file.
* Generalized {c,cxx}.predefs rule.
The rule now allows specifying custom input to process and is able to
produce JSON and buildfile output. See the "Compiler Predefined Macro
Extraction" section in the manual for details.
* GNU make jobserver support.
On POSIX platforms the build system driver now starts a GNU make-
compatible jobserver of the `fifo` type and passes the jobserver
information to all external commands (compilers, linkers, etc) as part of
the MAKEFLAGS environment variable. The jobserver can be disabled with the
--jobserver=none option.
Note that the `fifo` jobserver type is only supported since GNU make 4.4.
Note also that only the server side of the jobserver is supported and the
build system driver does not act as a jobserver client.
* Variable names with intermediate components called 'build' are now
reserved by the build system core. For example:
x.build.y = 1 # error
* Ability to override imported installed library path/name.
Specifically, the config.import.<proj>.<name>.{lib,liba,libs} variables
can be used to specify alternative location and/or name for an installed
library. This, in particular, can be useful when trying to use a library
installed with a prefix or suffix. For example, if the library was
installed with the `D` suffix:
config.import.libfoo.foo.lib=fooD
For the config.*.lib variable, the valid values are a simple path (which
is used as a library name base), an absolute directory (which is used as a
library location), or both. For example:
config.import.libfoo.foo.lib=/tmp/lib/
config.import.libfoo.foo.lib=/tmp/lib/fooD
For the config.*.{liba,libs} variables, the valid values are a simple name
(which is used as a library name), or an absolute path (which is used as a
library location and name). For example:
config.import.libfoo.foo.libs=libfooD.so
config.import.libfoo.foo.liba=/tmp/lib/libfooD.a
Note that on Windows, the shared library name/path should refer to the
import library, not the DLL.
* Ability to mark an executable as always built for install during the
update-for-install operation.
Specifically, it is now possible to set the for_install=true target-
specific variable on an executable to signal that it should be built for
install during update-for-install even if it would otherwise be built for
plain update, which happens if the executable is also executed during the
build. See GitHub issue #472 for details and implications.
bpkg version 0.18.0
-------------------
* Fetch cache and offline mode.
The fetch cache stores downloaded resources (repository metadata, package
archives, etc) which are then reused whenever appropriate. This can speed
up operations like rep-fetch and pkg-build substantially. If all the
resources are cached, then bpkg can now be instructed to run offline
without making any network requests.
Relevant new options:
--offline
--no-fetch-cache
--fetch-cache <mode>
--fetch-cache-path <dir>
--fetch-cache-session
See bpkg-common-options(1) for detail.
* Support for the `constrains` package manifest value in addition to
`depends`.
See the `constrains` package manifest value documentation in the manual
for details.
* Non-external packages are now by default configured as read-only.
For details, refer to the config.*.build.readonly variable documentation
in the build system.
* Ability to specify negative values for the -j|--jobs option.
If the value is negative, then the number of available hardware threads
is reduced by this value.
* New --sqlite-synchronous option and BUILD2_SQLITE_SYNCHRONOUS environment
variable.
These option and environment variable can be used to set the filesystem
synchronization mode for the fetch cache and configuration SQLite
databases. See bpkg-common-options(1) for detail.
* Data and documentation are now installed into a subdirectory for recursive
pkg-bindist.
If the installation is not private and the --recursive auto or full mode
of pkg-bindist is used, then all the data, documentation, and legal files
are now installed into an additional, named as the main bpkg package,
subdirectory.
* New pkg-bindist command options:
--debian-no-debug
--fedora-no-debug
--archive-strip-comps <num>
--recursive [?]<pkg>=<mode>
See bpkg-pkg-bindist(1) for details.
* The rep-create command now generates the signature.manifest file even for
unsigned repositories.
bdep version 0.18.0
-------------------
* Fetch cache and offline mode.
The fetch cache stores downloaded resources (repository metadata, package
archives, etc) which are then reused whenever appropriate. This can speed
up operations like bdep-init substantially. If all the resources are
cached, then bdep can now be instructed to run offline without making any
network requests.
Relevant new options:
--offline
--no-fetch-cache
--fetch-cache <mode>
--fetch-cache-session
See bdep-common-options(1) for detail.
* Ability to use package names in addition to package directories in
commands other than bdep-init.
Once a package is initialized, it is now possible to refer to it using
its name rather than its directory. For example:
bdep init @gcc -d libfoo -d foo
bdep ci -d libfoo # Old way (package directory).
bdep ci libfoo # New way (package name).
* Ability to specify negative values for the -j|--jobs option.
If the value is negative, then the number of available hardware threads
is reduced by this value.
* New bdep-ci command --force option that can be used to force the
submission in the presence of uncommitted changes.
* The bdep-publish command now publishes all project packages if none are
specified explicitly.
* The bdep-publish command now prompts the user to confirm if the alpha
section is appropriate for a package version 0.X.Y.
* New --sqlite-synchronous option and BUILD2_SQLITE_SYNCHRONOUS environment
variable.
These option and environment variable can be used to set the filesystem
synchronization mode for the project SQLite database. Note also that the
WAL (Write-Ahead Logging) journaling mode is now used for the project
database. See bdep-common-options(1) for detail.
More information about the announce
mailing list