[build2] build2 0.17.0 released
Boris Kolpackov
boris at codesynthesis.com
Tue Jun 18 13:13:40 UTC 2024
We have released build2 toolchain version 0.17.0.
The main area of focus in this release was again more advanced functionality
for more complex projects. There are also notable improvements in C++20
modules support, including for `import std;` in Clang and MSVC. On the
documentation front, we now have a comprehensive, step-by-step guide for
packaging third-party projects for build2:
https://build2.org/build2-toolchain/doc/build2-toolchain-packaging.xhtml
There are also quite a few smaller features in this release, such as new
buildfile value types and functions, including support for JSON.
Additionally, a large amount of maintenance work has been done, mostly in
the form of handling various corner cases and fixing bugs. For example,
there are about a hundred commit messages in this release that start with
"Fix".
A note on backwards compatibility: this release cannot be upgraded to from
0.16.0 and has to be installed from scratch.
Also note that build2 0.16.0 has a bug which will prevent it from working
with package repositories containing any packages with the build2 version
constraint greater than 0.16.0. As a result, we recommend that you upgrade
to 0.17.0 as soon as possible. To ease the impact of this bug we will embargo
publishing packages with such constraints to cppget.org for one month from
the date of this release (so until 18 July 2024).
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.17.0.xhtml
Additional notes for distribution package maintainers can be found in the
following pre-release announcement:
https://lists.build2.org/archives/users/2024-June/001117.html
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, and 17). A big thank you to everyone who
helped test the development snapshots and the release candidate.
The following new build configurations have been added to the CI service:
freebsd_13.3-clang_17
freebsd_14.1-clang_18
linux_debian_12-gcc_14 (x86_64 and aarch64)
linux_debian_12-clang_17[_libc++] (x86_64 and aarch64)
linux_debian_12-clang_18[_libc++] (x86_64 and aarch64)
macos_14-clang_15.0 (Xcode 15.3, Apple Clang 1500.3.9.4)
macos_14-gcc_14_homebrew
windows_10-msvc_17.8 (LTSC)
windows_10-msvc_17.10
windows_10-clang_17_msvc_msvc_17.10
windows_10-clang_18_llvm_msvc_17.10
windows_10-gcc_13.2_mingw_w64
Note also that we have removed the Emscripten configuration
(linux_debian_11-emcc_3.1.6) from the `all` and `experimental` classes. So
if you want your packages to continue building in this configuration, you
will need to add it explicitly, for example, using the `wasm` class or,
alternatively, with build-include manifest value.
Additionally, the following new configurations have been added to the
`bindist` class:
linux_ubuntu_22.04-gcc_11-bindist
linux_ubuntu_24.04-gcc_13-bindist
linux_fedora_39-gcc_13-bindist
linux_fedora_40-gcc_14-bindist
linux_rhel_9.2-gcc_11-bindist
macos_13-clang_15.0-bindist
windows_10-msvc_17.8-bindist
All in all, there are now 100 build configurations. For the complete list,
see:
https://ci.cppget.org/?build-configs
Installation instructions:
https://build2.org/install.xhtml
Download directory:
https://download.build2.org/0.17.0/
SHA256 checksums:
b84e4114c61aa94c3f6278f010a0dc0536dda65ac39d3863152ec9b64510b86e *build2-install-0.17.0.sh
9af34586cbe32360fa783883446cd90033152a1225c73acd92b45a95beafa695 *build2-install-msvc-0.17.0.bat
a612a7761774c4602a7633eb9b1acc791f8c51771fdb59c7b43a878ffec5d7fc *build2-install-clang-0.17.0.bat
ddd3cbfbc5927cc1736cadf3bdb6395c8261a3bebfedb2bb83e72f3964ad1bb8 *build2-install-mingw-0.17.0.bat
5c7d4a797c252e4516d1e913e50d6cf4d461d340d1e4fa295c878667e6b8bab0 *build2-toolchain-0.17.0.tar.gz
3722a89ea86df742539d0f91bb4429fd46bbf668553a350780a63411b648bf5d *build2-toolchain-0.17.0.tar.xz
2e64660c38cea2a9ef81c367ec80af4aa9ff606c6bb6ad0f9647b80909648bea *build2-baseutils-0.17.0-x86_64-windows.zip
f95c894573c271f1bc51e059dc1b3287f6111d06ed099b0e596053af6f0b4675 *build2-mingw-0.17.0-x86_64-windows.tar.xz
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.17.0
---------------------
* C++20 modules support improvements:
- Named modules support in Clang, including automatic building of the
`std` and `std.compat` standard library modules from libc++ with Clang
18 or later.
- Named modules support in MSVC, including automatic building of the `std`
and `std.compat` standard library modules.
Note: if combining the standard library modules importation with the
standard library headers inclusion, MSVC 17.10 or later is recommended.
- Modules support can now be enabled for any std.cxx value greater or
equal 20 (including `latest`).
- The "C++ Modules Support" section in the manual has been updated to
match the current state of the implementation.
* The `latest` and `experimental` cxx.std values are now mapped to C++26
from GCC 14 and Clang 18.
* The 23 and 2x c.std values are now mapped to /std:clatest starting from
MSVC 17.9. In particular, this option enables C23 typeof support.
* /Zc:preprocessor is now added for the `experimental` cxx.std value from
MSVC 17.9.
* New string_set buildfile value type.
This exposes the std::set<std::string> type to buildfiles.
New functions:
$size(<string-set>)
Subscript returns true if the value is present and false otherwise (so it
is mapped to std::set::contains()). For example:
set = [string_set] a b c
if ($set[b]) ...
Note that append (+=) and prepend (=+) have the same semantics
(std::set::insert()). For example:
set = [string_set] a b set += c b # a b c set =+ d b # a b c d
Example of iteration:
set = [string_set] a b c for k: $set ...
* New string_map buildfile value type.
This exposes the std::map<std::string,std::string> type to buildfiles.
New functions:
$size(<string-map>) $keys(<string-map>)
Subscript can be used to look up a value by key. The result is [null] if
there is no value associated with the specified key. For example:
map = [string_map] a at 1 b at 2 c at 3
b = ($map[b]) # 2
if ($map[z] == [null]) ...
Note that append (+=) is overriding (like std::map::insert_or_assign())
while prepend (=+) is not (like std::map::insert()). In a sense, whatever
appears last (from left to right) is kept, which is consistent with what
we expect to happen when specifying the same key repeatedly in a literal
representation. For example:
map = [string_map] a at 0 b at 2 a at 1 # a at 1 b at 2 map += b at 0 c at 3 # a at 1 b at 0 c at 3 map
=+ b at 1 d at 4 # a at 1 b at 0 c at 3 d at 4
Example of iteration:
map = [string_map] a at 1 b at 2 c at 3 for p: $map { k = $first($p) v =
$second($p) }
While the subscript is mapped to key lookup only, index-based access can
be implemented (with a bit of overhead) using the $keys() function:
map = [string_map] a at 1 b at 2 c at 3 keys = $keys($m) for i:
$integer_sequence(0, $size($keys)) { k = ($keys[$i]) v = ($map[$k]) }
* New JSON buildfile value types.
New types:
json json_array json_object
New functions:
$json.value_type(<json>) $json.value_size(<json>)
$json.member_{name,value}(<json-member>)
$json.object_names(<json-object>) $json.array_size(<json-array>)
$json.array_find(<json-array>, <json>)
$json.array_find_index(<json-array>, <json>) $json.load(<path>)
$json.parse(<text>) $json.serialize(<json>[, <indentation>])
See "JSON Functions" in the manual for details.
For example, to load a JSON value from a file:
j = $json.load($src_base/board.json)
Or to construct it in a buildfile:
j = [json] one at 1 two@([json] 2 3 4) three@([json] x at 1 y at -1)
This can also be done incrementally with append/prepend:
j = [json_object] j += one at 1 j += two@([json] 2 3 4) j += three@([json]
x at 1 y at -1)
Instead of using this JSON-like syntax, one can also specify valid JSON
input text:
j = [json] '{"one":1, "two":[2, 3, 4], "three":{"x":1, "y":-1}'
Besides the above set of functions, other handy ways to access components
in a JSON value are iteration and subscript. For example:
for m: $j print $member_name($m) $member_value($m)
print ($j[three])
A subscript can be nested:
print ($j[two][1]) print ($j[three][x])
While a JSON value can be printed directly like any other value, the
representation will not be pretty-printed. As a result, for complex JSON
values, printing a serialized representation might be a more readable
option:
info $serialize($j)
* New json_map and json_set buildfile value types.
These expose the std::map<json_value,json_value> and std::set<json_value>
types to buildfiles.
New functions:
$size(<json-set>) $size(<json-map>) $keys(<json-map>)
Note that the $keys() function returns the list of map key as a json
array.
For example:
m = [json_map] 2@([json] a at 1 b at 2) 1@([json] 1 2) s = [json_set] ([json]
x at 1 y at 2) ([json] a at 1 b at 2)
print ($m[2][b]) # 2 print ($s[([json] y at 2 x at 1)]) # true
* New $first() and $second() functions which return the first and second
halves of a pair, respectively.
* New string functions:
$string.contains() $string.starts_with() $string.ends_with()
$string.replace()
See "String Functions" in the manual for details.
* New path functions:
$path.absolute() $path.simple() $path.sub_path() $path.super_path()
$path.complete() $path.try_normalize() $path.try_actualize()
See "Path Functions" in the manual for details.
* New filesystem functions:
$filesystem.file_exists() $filesystem.directory_exists()
See "Filesystem Functions" in the manual for details.
* Runtime/buildtime distinction when installing libraries.
Specifically, now, if a library is installed solely as a prerequisite of
an executable (potentially recursively), then only its runtime files are
installed omitting everything buildtime-related (static/import libraries,
non-versioned symlinks for shared libraries, pkg-config files, headers,
etc). If you are familiar with the runtime and -dev/-devel package splits
for libraries in Debian/Fedora, this is the analogous semantics.
* Support for extracting C and C++ predefined macros (predefs).
Specifically, the c and cxx modules now provide the c.predefs and
cxx.predefs submodules which can be loaded in order to register a rule
that generates a C or C++ header with the predefined compiler macros,
respectively. For details, refer to "C Compiler Predefined Macro
Extraction" and "C++ Compiler Predefined Macro Extraction" in the manual.
* Ability to serialize compilation/linking in C/C++ rules.
Specifically, both the C/C++ compile and link rules now recognize the
cc.serialize boolean variable which instructs them to compile/link
serially with regards to any other recipe.
This is primarily useful when compiling large translation units or linking
large binaries that require so much memory that doing that in parallel
with other compilation/linking jobs is likely to summon the OOM killer.
For example:
obj{memory-hog}: cc.serialize = true
* Ability to specify compiler mode options in a buildfile.
Now the configured mode options are appended to buildfile-specified (which
must be specified before loading the guess module).
In particular, this ability to specify the compiler mode in a buildfile is
useful in embedded development where the project may need to hardcode
options like -target, -nostdinc, etc. For example:
cxx.std = 20 cxx.mode = -target riscv32-unknown-unknown -nostdinc using
cxx
* New ~host-no-warnings and ~build2-no-warnings special configurations.
These are parallel to ~host and ~build2 but with suppressed C/C++ compiler
warnings.
Note also that the C++ ad hoc recipes are now by default built in
~build2-no-warnings instead of ~build2 unless the project is configured
for development with config.<project>.develop=true.
* New {bin,c,cxx}.types submodules that only register target types.
This is primarily useful when providing custom C/C++ compilation/linking
rules.
* New -s|--timeout-success option in the `env` script builtin.
The semantics is equivalent to the --success option in the `timeout`
builtin.
* Ability to specify alternative sysroot for pkg-config files.
Specifically, the new config.cc.pkgconfig.sysroot variable provides
roughly equivalent functionality to PKG_CONFIG_SYSROOT_DIR in
pkg-config. For details and limitations, see "Rewriting Installed
Libraries System Root (sysroot)" in the manual for details.
* Ability to alias a target type from another project.
The syntax is:
define <type> = <proj-scope>/<type>
For example:
sdk_proj = ... # Root directory of the SDK. define ldscript =
$sdk_proj/ldscript
Additionally, unknown target types of imported targets are now aliased
automatically.
* New no_default_target attribute for source, buildfile import directives.
This attribute can be used to disable the default target semantics for the
sources/imported buildfile.
* Allow imported buildfiles to use config.* variables from own projects
(that is, the project from which the buildfile is imported).
* The fsdir{} targets are now usable in ad hoc recipes.
In particular, they can now be used to represent directory symlinks. For
example:
exe{hello}: ... fsdir{assets}
fsdir{assets}: % update {{ ln -s $src_base/assets $out_base/assets }} %
clean {{ rm $out_base/assets }}
Likewise, file{} targets can now be used to represent file symlinks
created in ad hoc recipes.
* Ability to specify ad hoc recipes in separate files.
This can now be achieved with the new `recipe` directive:
recipe <language> <file>
Note that similar to the use of if-else and switch directives with
recipes, this directive requires explicit % recipe header. For example,
instead of:
file{foo.output}: {{ echo 'hello' >$path($>) }}
We can now write:
file{foo.output}: % recipe buildscript hello.buildscript
With hello.buildscript containing:
echo 'hello' >$path($>)
Similarly, for C++ recipes (this time for a pattern rule), instead of:
[rule_name=hello] file{~'/(.+)\.output/'}: % update clean {{ c++ 1 --
--
...
}}
We can now write:
[rule_name=hello] file{~'/(.+)\.output/'}: % update clean recipe c++
hello.cxx
With hello.cxx containing:
// c++ 1 --
--
...
Relative <file> paths are resolved using the buildfile directory that
contains the `recipe` directive as a base.
Note also that this mechanism can be used in exported buildfiles with
recipe files placed into build/export/ together with buildfiles.
bpkg version 0.17.0
-------------------
* Support for preserving existing package configuration on up/downgrade
and reconfiguration.
* Support for the enable clause in the `tests` package manifest value.
* New per package configuration *-build-*email manifest values.
* New build-bot package manifest value allows specifying package-custom
build bots.
* Support for specifying package archives and directories as dependencies
for pkg-build.
* New `none` value for the --recursive option in pkg-bindist.
* Empty --archive-lang* option values in pkg-bindist are now treated as a
request to clear previous entries.
bdep version 0.17.0
-------------------
* New `third-party` library and executable sub-option in bdep-new.
This sub-option is meant for converting an existing third-party project
to build2. It automatically enables a number of other sub-options (such
as no-version, no-readme, and no-symexport). It also adds a number of
values to manifest that makes sense to specify in a package of a third-
party project and, unless no-package-readme is specified, generates the
PACKAGE-README.md template.
* New buildfile-in-prefix library and executable sub-option in bdep-new.
* New export-stub executable sub-option in bdep-new.
* New no-symexport and auto-symexport library sub-options in bdep-new.
* New no-subdir-include library sub-option in bdep-new.
More information about the users
mailing list