build2 | 0.11.0 Release Notes

These notes provide a more detailed discussion of major new features, including the motivation for implementing them and their usage examples. For the complete list of changes, refer to the Release Announcement or the NEWS files in the individual packages. See also the discussion of these release notes on r/cpp/ and r/programming/.

This release contains a large number of new features across all the tools (build system, package and project dependency managers, etc). It also includes experimental support for C++ modules header unit importation and include translation.

A note on backwards compatibility: in this release we have extended the numeric representation of the standard versioning scheme. As a result, this release cannot be upgraded to from 0.10.0 and has to be installed from scratch. Additionally, while existing libraries created with bdep-new will continue to work, the comment that describes the versioning scheme in version.hxx.in (or equivalent) will no longer be accurate. The easiest way to fix this is to run bdep-new on the side to create an identically-named project and copy the new version.hxx.in over.

In addition to the toolchain changes, the CI service now offers the following new build configurations:

linux_debian_9-gcc_9.1
linux_debian_9-clang_8.0

macos_10.14-clang_10.0
macos_10.14-gcc_9.1_homebrew

windows_10-msvc_16.1

The total now stands at 35 build configurations and covers a wide range of versions for all the major compilers (GCC, Clang, and MSVC) on all the major platforms (Linux, Mac OS, Windows, and FreeBSD).

Build System

A major chunk of build system work went into support for C++ modules, specifically, header unit importation and include translation. Because there are still some loose ends to tie up on the compiler front, there will be a separate announcement in the coming weeks. However, as a sneak peek, soon you should be able to write:

import <vector>;
#include <iostream>

...

And then build:

$ b config.cxx.importable_headers='<iostream>'

Another major new build system feature is support for generalized target/prerequisite variable blocks. For example, now instead of:

exe{foo}: cxx{foo}
exe{foo}: cc.loptions += -rdynamic

Or:

exe{foo}: cxx{foo}
exe{foo}:
{
  cc.loptions += -rdynamic
  cc.libs += -ldl
}

We can write:

 exe{foo}: cxx{foo}
 {
   cc.loptions += -rdynamic
   cc.libs += -ldl
 }

In certain cases we may need to instruct the underlying tool (compiler, linker, etc) to produce additional outputs. For example, we may want to request the compiler to produce an assembler listing or the linker to produce a map file. While we could already pass the required options, the resulting files will not be part of the build state. Specifically, they will not be cleaned up and we cannot use them as prerequisites of other targets.

To support such use cases the build system now has a notion of ad hoc target groups which allow us to specify that updating a target produces additional outputs, called ad hoc group members. For example:

<exe{hello} file{hello.map}>: cxx{hello}
{
  cc.loptions += "-Wl,-Map=$out_base/hello.map"
}

<obje{hello} file{hello.lst}>:
{
  cc.coptions += "-Wa,-amhls=$out_base/hello.lst"
}

Note also that all things ad hoc (prerequisites, targets, rules) are still under active development so further improvements (such as not having to repeat names twice) are likely.

Project Dependency Manager

On the bdep front, the new command now by default adds a README.md template. And to complement this functionality, the repository web interface now supports displaying Markdown package descriptions. To see what it all looks like, check out the libstud-uuid package (and its GitHub page for comparison).

Another improvement to the new command is the --post-hook option which allows executing arbitrary customization commands in the newly created project. For example, here is how we can add something to the project's .gitignore file:

$ bdep new --post-hook "echo .idea/ >>.gitignore" hello

See the bdep-new(1) man pages for details.

Another bdep command that added a significant new feature is ci. It now allows overriding certain manifest values in packages being submitted for testing. This is primarily useful for specifying alternative build configurations and/or build notification emails. For example, if we are only interested in GCC builds, then we can do:

$ bdep ci --builds gcc

See the bdep-ci(1) man pages for details.

Package Dependency Manager

In bpkg the build command can now "build" a system package that doesn't have a stub provided its version is specified explicitly. For example:

$ bpkg build ... ?sys:libsqlite3/* ?sys:libcurl/7.47.0

Naturally, this also extends to the relevant bdep commands, for example:

$ bdep sync ?sys:libsqlite3/*

See Using System-Installed Dependencies for details.