[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