 |
|
| |
b(1) |
FreeBSD General Commands Manual |
b(1) |
b --help
b --version
b [options] [variables] [buildspec]
buildspec =
meta-operation(operation(target...[,parameters])...)...
The build2 build system driver executes a set of
meta-operations on operations on targets according to the build
specification, or buildspec for short. This process can be controlled
by specifying driver options and build system variables.
Note that options, variables, and buildspec
fragments can be specified in any order. To avoid treating an argument that
starts with '-' as an option, add the '--' separator. To avoid
treating an argument that contains '=' as a variable, add the second
'--' separator.
All components in the buildspec can be omitted. If
meta-operation is omitted, then it defaults to perform. If
operation is omitted, then it defaults to the default operation for
this meta-operation. For perform it is update. Finally, if
target is omitted, then it defaults to the current working directory.
A meta-operation on operation is called an action. Some operations
and meta-operations may take additional parameters. For example:
$ b # perform(update(./))
$ b foo/ # perform(update(foo/))
$ b foo/ bar/ # perform(update(foo/ bar/))
$ b update # perform(update(./))
$ b 'clean(../)' # perform(clean(../))
$ b perform # perform(update(./))
$ b configure # configure(?(./))
$ b 'configure(../)' # configure(?(../))
$ b clean update # perform(clean(./) update(./))
$ b configure update # configure(?(./)) perform(update(./))
$ b 'create(conf/, cxx)' # create(?(conf/), cxx)
Notice the question mark used to show the (imaginary) default
operation for the configure meta-operation. For configure the
default operation is "all operations". That is, it will configure
all the operations for the specified target.
You can also "generate" multiple operations for the same
set of targets. Compare:
$ b 'clean(foo/ bar/)' 'update(foo/ bar/)'
$ b '{clean update}(foo/ bar/)'
Some more useful buildspec examples:
$ b '{clean update}(...)' # rebuild
$ b '{clean update clean}(...)' # make sure builds
$ b '{clean test clean}(...)' # make sure passes tests
$ b '{clean disfigure}(...)' # similar to distclean
In POSIX shells parenthesis are special characters and must be
quoted when used in a buildspec. Besides being an inconvenience in itself,
quoting also inhibits path auto-completion. To help with this situation a
shortcut syntax is available for executing a single operation or
meta-operation, for example:
$ b clean: foo/ bar/ # clean(foo/ bar/)
$ b configure: src/@out/ # configure(src/@out/)
$ b create: conf/, cxx # create(conf/, cxx)
$ b configure: config.cxx=g++ src/ # configure(src/) config.cxx=g++
To activate the shortcut syntax the first buildspec argument must
start with an operation or meta-operation name and end with a colon
(:). To transform the shortcut syntax to the normal buildspec syntax
the colon is replaced with the opening parenthesis ('('), the rest of
the buildspec arguments are treated as is, and the final closing parenthesis
(')') is added.
For each target the driver expects to find buildfile
either in the target's directory or, if the directory is part of the
out tree (out_base), in the corresponding src directory
(src_base).
For example, assuming foo/ is the source directory of a
project:
$ b foo/ # out_base=src_base=foo/
$ b foo-out/ # out_base=foo-out/ src_base=foo/
$ b foo-out/exe{foo} # out_base=foo-out/ src_base=foo/
An exception to this requirement is a directory target in which
case, provided the directory has subdirectories, an implied
buildfile with the following content is assumed:
# Implied directory buildfile: build all subdirectories.
#
./: */
In the above example, we assumed that the build system driver was
able to determine the association between out_base and
src_base. In case src_base and out_base are not the
same directory, this is achieved in one of two ways: the config
module (which implements the configure, disfigure, and
create meta-operations) saves this association as part of the
configuration process. If, however, the association hasn't been saved, then
we have to specify src_base explicitly using the following extended
target syntax:
src-base/@target
Continuing with the previous example:
$ b foo/@foo-out/exe{foo} # out_base=foo-out/ src_base=foo/
Normally, you would need to specify src_base explicitly
only once, during configuration. For example, a typical usage would be:
$ b configure: foo/@foo-out/ # src_base is saved
$ b foo-out/ # no need to specify src_base
$ b clean: foo-out/exe{foo} # no need to specify src_base
Besides in and out of source builds, build2 also supports
configuring a project's source directory as forwarded to an out of
source build. With such a forwarded configuration in place, if we run the
build system driver from the source directory, it will automatically build
in the output directory and backlink (using symlinks or another
suitable mechanism) certain "interesting" targets (executables,
documentation, etc) to the source directory for easy access. Continuing with
the previous example:
$ b configure: foo/@foo-out/,forward # foo/ forwarded to foo-out/
$ cd foo/
$ b # build in foo-out/
$ ./foo # symlink to foo-out/foo
The ability to specify build2 variables as part of the
command line is normally used to pass configuration values, for example:
$ b config.cxx=clang++ config.cxx.coptions=-O3
Similar to buildspec, POSIX shells often inhibit path
auto-completion on the right hand side of a variable assignment. To help
with this situation the assignment can be broken down into three separate
command line arguments, for example:
$ b config.import.libhello = ../libhello/
The build system has the following built-in and pre-defined
meta-operations:
- perform
-
Perform an operation.
- configure
-
Configure all operations supported by a project and save the result in the
project's build/config.build file. Implemented by the config
module. For example:
$ b configure \
config.cxx=clang++ \
config.cxx.coptions=-O3 \
config.install.root=/usr/local \
config.install.root.sudo=sudo
Use the forward parameter to instead configure a source
directory as forwarded to an out of source build. For example:
$ b configure: src/@out/,forward
- disfigure
-
Disfigure all operations supported by a project and remove the project's
build/config.build file. Implemented by the config module.
Use the forward parameter to instead disfigure
forwarding of a source directory to an out of source build. For
example:
$ b disfigure: src/,forward
- create
-
Create and configure a configuration project. Implemented by the
config module.
Normally a build2 project is created manually by
writing the bootstrap.build and config.build files, adding
source files, and so on. However, a special kind of project, which we
call configuration, is often useful. Such a project doesn't have
any source files of its own. Instead, it serves as an amalgamation for
building other projects as part of it. Doing it this way has two major
benefits: sub-projects automatically resolve their imports to other
projects in the amalgamation and sub-projects inherits their
configuration from the amalgamation (which means if we want to change
something, we only need to do it in one place).
As an example, let's assume we have two C++ projects: the
libhello library in libhello/ and the hello
executable that imports it in hello/. And we want to build
hello with clang++.
One way to do it would be to configure and build each project
in its own directory, for example:
$ b configure: libhello/@libhello-clang/ config.cxx=clang++
$ b configure: hello/@hello-clang/ config.cxx=clang++ \
config.import.libhello=libhello-clang/
The two drawbacks, as mentioned above, are the need to
explicitly resolve the import and having to make changes in multiple
places should, for example, we want to switch from clang++ to
g++.
We can, however, achieve the same end result but without any
of the drawbacks using the configuration project:
$ b create: clang/,cxx config.cxx=clang++ # Creates clang/.
$ b configure: libhello/@clang/libhello/
$ b configure: hello/@clang/hello/
The targets passed to the create meta-operation must be
directories which should either not exist or be empty. For each such
directory create first initializes a project as described below
and then configures it by executing the configure
meta-operation.
The first optional parameter to create is the list of
modules to load in root.build. By default, create appends
.config to the names of these modules so that only their
configurations are loaded. You can override this behavior by specifying
the period (.) after the module name. You can also instruct
create to use the optional module load by prefixing the module
name with the question mark (?).
The second optional parameter is the list of modules to load
in bootstrap.build. If not specified, then the test,
dist, and install modules are loaded by default. The
config module is always loaded first.
Besides creating project's bootstrap.build and
root.build, create also writes the root buildfile
with the following contents:
./: {*/ -build/}
If used, this buildfile will build all the sub-projects
currently present in the configuration.
- dist
-
Prepare a distribution containing all files necessary to perform all
operations in a project. Implemented by the dist module.
- info
-
Print basic information (name, version, source and output directories, etc)
about one or more projects to stdout, separating multiple projects
with a blank line. Each project is identified by its root directory
target. For example (some output is omitted):
$ b info: libfoo/ libbar/
project: libfoo
version: 1.0.0
src_root: /tmp/libfoo
out_root: /tmp/libfoo
subprojects: @tests
project: libbar
version: 2.0.0
src_root: /tmp/libbar
out_root: /tmp/libbar-out
subprojects: @tests
To omit discovering and printing subprojects information, use
the no_subprojects parameter, for example:
$ b info: libfoo/,no_subprojects
To instead print this information in the JSON format, use the
json parameter, for example:
$ b info: libfoo/,json
In this case the output is a JSON array of objects which are
the serialized representation of the following C++ struct
project_info:
struct subproject
{
string path;
optional<string> name;
};
struct project_info
{
optional<string> project;
optional<string> version;
optional<string> summary;
optional<string> url;
string src_root;
string out_root;
optional<string> amalgamation;
vector<subproject> subprojects;
vector<string> operations;
vector<string> meta_operations;
vector<string> modules;
};
For example:
[
{
"project": "libfoo",
"version": "1.0.0",
"summary": "libfoo C++ library",
"src_root": "/tmp/libfoo",
"out_root": "/tmp/gcc-debug/libfoo",
"amalgamation": "..",
"subprojects": [
{
"path": "tests"
}
],
"operations": [
"update",
"clean",
"test",
"update-for-test",
"install",
"uninstall",
"update-for-install"
],
"meta-operations": [
"perform",
"configure",
"disfigure",
"dist",
"info"
],
"modules": [
"version",
"config",
"test",
"install",
"dist"
]
}
]
See the JSON OUTPUT section below for details on the overall
properties of this format and the semantics of the struct
serialization.
The build system has the following built-in and pre-defined
operations:
- update
-
Update a target.
- clean
-
Clean a target.
- test
-
Test a target. Performs update as a pre-operation. Implemented by the
test module.
- update-for-test
-
Update a target for testing. This operation is equivalent to the
update pre-operation as executed by the test operation and
can be used to only update what is necessary for testing. Implemented by
the test module.
- install
-
Install a target. Performs update as a pre-operation. Implemented by
the install module.
- uninstall
-
Uninstall a target. Performs update as a pre-operation. Implemented
by the install module.
- update-for-install
-
Update a target for installation. This operation is equivalent to the
update pre-operation as executed by the install operation
and can be used to only update what is necessary for installation.
Implemented by the install module.
Note that buildspec and command line variable values are treated
as buildfile fragments and so can use quoting and escaping as well as
contain variable expansions and evaluation contexts. However, to be more
usable on various platforms, escaping in these two situations is limited to
the effective sequences of \', \", \\,
\$, and \( with all other sequences interpreted as is.
Together with double-quoting this is sufficient to represent any value. For
example:
$ b config.install.root=c:\projects\install
$ b "config.install.root='c:\Program Files\test\'"
$ b 'config.cxx.poptions=-DFOO_STR="foo"'
- -v
- Print actual commands being executed. This options is equivalent to
--verbose 2.
- -V
- Print all underlying commands being executed. This options is equivalent
to --verbose 3.
- --quiet|-q
- Run quietly, only printing error messages in most contexts. In certain
contexts (for example, while updating build system modules) this verbosity
level may be ignored. Use --silent to run quietly in all contexts.
This option is equivalent to --verbose 0.
- --silent
- Run quietly, only printing error messages in all contexts.
- --verbose
level
- Set the diagnostics verbosity to level between 0 and 6. Level 0
disables any non-error messages (but see the difference between
--quiet and --silent) while level 6 produces lots of
information, with level 1 being the default. The following additional
types of diagnostics are produced at each level:
- 1.
- High-level information messages.
- 2.
- Essential underlying commands being executed.
- 3.
- All underlying commands being executed.
- 4.
- Information that could be helpful to the user.
- 5.
- Information that could be helpful to the developer.
- 6.
- Even more detailed information.
- --stat
- Display build statistics.
- --progress
- Display build progress. If printing to a terminal the progress is
displayed by default for low verbosity levels. Use --no-progress to
suppress.
- --no-progress
- Don't display build progress.
- --diag-color
- Use color in diagnostics. If printing to a terminal the color is used by
default provided the terminal is not dumb. Use --no-diag-color to
suppress.
This option affects the diagnostics printed by the build
system itself. Some rules may also choose to propagate its value to
tools (such as compilers) that they invoke.
- --no-diag-color
- Don't use color in diagnostics.
- --jobs|-j
num
- Number of active jobs to perform in parallel. This includes both the
number of active threads inside the build system as well as the number of
external commands (compilers, linkers, etc) started but not yet finished.
If this option is not specified or specified with the 0 value, then
the number of available hardware threads is used.
- --max-jobs|-J
num
- Maximum number of jobs (threads) to create. The default is 8x the number
of active jobs (--jobs|j) on 32-bit architectures and 32x on
64-bit. See the build system scheduler implementation for details.
- --queue-depth|-Q
num
- The queue depth as a multiplier over the number of active jobs. Normally
we want a deeper queue if the jobs take long (for example, compilation)
and shorter if they are quick (for example, simple tests). The default is
4. See the build system scheduler implementation for details.
- --file-cache
impl
- File cache implementation to use for intermediate build results. Valid
values are noop (no caching or compression) and sync-lz4 (no
caching with synchronous LZ4 on-disk compression). If this option is not
specified, then a suitable default implementation is used (currently
sync-lz4).
- --max-stack
num
- The maximum stack size in KBytes to allow for newly created threads. For
pthreads-based systems the driver queries the stack size of the
main thread and uses the same size for creating additional threads. This
allows adjusting the stack size using familiar mechanisms, such as
ulimit. Sometimes, however, the stack size of the main thread is
excessively large. As a result, the driver checks if it is greater than a
predefined limit (64MB on 64-bit systems and 32MB on 32-bit ones) and caps
it to a more sensible value (8MB) if that's the case. This option allows
you to override this check with the special zero value indicating that the
main thread stack size should be used as is.
- --serial-stop|-s
- Run serially and stop at the first error. This mode is useful to
investigate build failures that are caused by build system errors rather
than compilation errors. Note that if you don't want to keep going but
still want parallel execution, add --jobs|-j (for example
-j 0 for default concurrency). Note also that during serial
execution there is no diagnostics buffering and child process'
stderr is a terminal (unless redirected; see
--no-diag-buffer for details).
- --dry-run|-n
- Print commands without actually executing them. Note that commands that
are required to create an accurate build state will still be executed and
the extracted auxiliary dependency information saved. In other words, this
is not the "don't touch the filesystem" mode but rather
"do minimum amount of work to show what needs to be
done". Note also that only the perform meta-operation
supports this mode.
- --no-diag-buffer
- Do not buffer diagnostics from child processes. By default, unless running
serially, such diagnostics is buffered and printed all at once after each
child exits in order to prevent interleaving. However, this can have
side-effects since the child process' stderr is no longer a
terminal. Most notably, the use of color in diagnostics may be disabled by
some programs. On the other hand, depending on the platform and programs
invoked, the interleaving diagnostics may not break lines and thus could
be tolerable.
- --match-only
- Match the rules without executing the operation. This mode is primarily
useful for profiling and dumping the build system state.
- --load-only
- Match the rules only to alias{} targets ignoring other targets and
without executing the operation. In particular, this has the effect of
loading all the subdirectory buildfiles that are not explicitly
included. Note that this option can only be used with the
perform(update) action on an alias{} target, usually
dir{}.
- --no-external-modules
- Don't load external modules during project bootstrap. Note that this
option can only be used with meta-operations that do not load the
project's buildfiles, such as info.
- --structured-result
fmt
- Write the result of execution in a structured form. In this mode, instead
of printing to stderr diagnostics messages about the outcome of
executing actions on targets, the driver writes to stdout a
machine-readable result description in the specified format. Valid values
for this option are lines and json. Note that currently only
the perform meta-operation supports the structured result output.
If the output format is lines, then the result is
written one line per the buildspec action/target pair. Each line has the
following form:
state meta-operation operation
target
Where state can be one of unchanged,
changed, or failed. If the action is a pre or post
operation, then the outer operation is specified in parenthesis. For
example:
unchanged perform update(test) /tmp/hello/hello/exe{hello}
changed perform test /tmp/hello/hello/exe{hello}
If the output format is json, then the output is a JSON
array of objects which are the serialized representation of the
following C++ struct target_action_result:
struct target_action_result
{
string target;
string display_target;
string target_type;
optional<string> target_path;
string meta_operation;
string operation;
optional<string> outer_operation;
string state;
};
For example:
[
{
"target": "/tmp/hello/hello/exe{hello.}",
"display_target": "/tmp/hello/hello/exe{hello}",
"target_type": "exe",
"target_path": "/tmp/hello/hello/hello",
"meta_operation": "perform",
"operation": "update",
"outer_operation": "test",
"state": "unchanged"
},
{
"target": "/tmp/hello/hello/exe{hello.}",
"display_target": "/tmp/hello/hello/exe{hello}",
"target_type": "exe",
"target_path": "/tmp/hello/hello/hello",
"meta_operation": "perform",
"operation": "test",
"state": "changed"
}
]
See the JSON OUTPUT section below for details on the overall
properties of this format and the semantics of the struct
serialization.
The target member is the target name that is qualified
with the extension (if applicable) and, if required, is quoted so that
it can be passed back to the build system driver on the command line.
The display_target member is the unqualified and unquoted
"display" target name, the same as in the lines format.
The target_type member is the type of target. The
target_path member is an absolute path to the target if the
target type is path-based or dir.
- --mtime-check
- Perform file modification time sanity checks. These checks can be helpful
in diagnosing spurious rebuilds and are enabled by default on Windows
(which is known not to guarantee monotonically increasing mtimes) and for
the staged version of the build system on other platforms. Use
--no-mtime-check to disable.
- --no-mtime-check
- Don't perform file modification time sanity checks. See
--mtime-check for details.
- --dump
phase
- Dump the build system state after the specified phase. Valid phase
values are load (after loading buildfiles) and match
(after matching rules to targets). The match value also has the
match-pre and match-post variants to dump the state for the
pre/post-operations (match dumps the main operation only). Repeat
this option to dump the state after multiple phases/variants. By default
the entire build state is dumped but this behavior can be altered with the
--dump-scope and --dump-target options. See also the
--match-only and --load-only options.
- --dump-format
format
- Representation format and output stream to use when dumping the build
system state. Valid values for this option are buildfile (a
human-readable, Buildfile-like format written to stderr; this is
the default), and json-v0.1 (machine-readable, JSON-based format
written to stdout). For details on the buildfile format, see
Diagnostics and Debugging (#intro-diag-debug). For details on the
json-v0.1 format, see the JSON OUTPUT section below (overall
properties) and JSON Dump Format (#json-dump) (format specifics). Note
that the JSON format is currently unstable (thus the temporary
-v0.1 suffix).
Note that because it's possible to end up with multiple dumps
(for example, by specifying the --dump-scope and/or
--dump-target options multiple times), the JSON output is in the
"JSON Lines" form, that is, without pretty-printing and with
the top-level JSON objects delimited by newlines. Note also that if the
JSON dump output is combined with --structured-result=json, then
the structured result is the last line.
- --dump-scope
dir
- Dump the build system state for the specified scope only. Repeat this
option to dump the state of multiple scopes.
- --dump-target
target
- Dump the build system state for the specified target only. Repeat this
option to dump the state of multiple targets.
- --trace-match
target
- Trace rule matching for the specified target. This is primarily useful
during troubleshooting. Repeat this option to trace multiple targets.
- --trace-execute
target
- Trace rule execution for the specified target. This is primarily useful
during troubleshooting. Repeat this option to trace multiple targets.
- --no-column
- Don't print column numbers in diagnostics.
- --no-line
- Don't print line and column numbers in diagnostics.
- --buildfile
path
- The alternative file to read build information from. The default is
buildfile or build2file, depending on the project's build
file/directory naming scheme. If path is '-', then read from
stdin. Note that this option only affects the files read as part of
the buildspec processing. Specifically, it has no effect on the
source and include directives. As a result, this option is
primarily intended for testing rather than changing the build file names
in real projects.
- --config-guess
path
- The path to the config.guess(1) script that should be used to guess
the host machine triplet. If this option is not specified, then b
will fall back on to using the target it was built for as host.
- --config-sub
path
- The path to the config.sub(1) script that should be used to
canonicalize machine triplets. If this option is not specified, then
b will use its built-in canonicalization support which should be
sufficient for commonly-used platforms.
- The pager program to be used to show long text. Commonly used pager
programs are less and more. You can also specify additional
options that should be passed to the pager program with
--pager-option. If an empty string is specified as the pager
program, then no pager will be used. If the pager program is not
explicitly specified, then b will try to use less. If it is
not available, then no pager will be used.
- Additional option to be passed to the pager program. See --pager
for more information on the pager program. Repeat this option to specify
multiple pager options.
- --options-file
file
- Read additional options from file. Each option should appear on a
separate line optionally followed by space or equal sign (=) and an
option value. Empty lines and lines starting with # are ignored.
Option values can be enclosed in double (") or single
(') quotes to preserve leading and trailing whitespaces as well as
to specify empty values. If the value itself contains trailing or leading
quotes, enclose it with an extra pair of quotes, for example
'"x"'. Non-leading and non-trailing quotes are
interpreted as being part of the option value.
The semantics of providing options in a file is equivalent to
providing the same set of options in the same order on the command line
at the point where the --options-file option is specified except
that the shell escaping and quoting is not required. Repeat this option
to specify more than one options file.
- --default-options
dir
- The directory to load additional default options files from.
- --no-default-options
- Don't load default options files.
- --help
- Print usage information and exit.
- --version
- Print version and exit.
Instead of having a separate config file format for tool
configuration, the build2 toolchain uses default options files
which contain the same options as what can be specified on the command line.
The default options files are like options files that one can specify with
--options-file except that they are loaded by default.
The default options files for the build system driver are called
b.options and are searched for in the .build2/ subdirectory of
the home directory and in the system directory (for example,
/etc/build2/) if configured. Note that besides options these files
can also contain global variable overrides.
Once the search is complete, the files are loaded in the reverse
order, that is, beginning from the system directory (if any), followed by
the home directory, and finishing off with the options specified on the
command line. In other words, the files are loaded from the more generic to
the more specific with the command line options having the ability to
override any values specified in the default options files.
If a default options file contains --no-default-options,
then the search is stopped at the directory containing this file and no
outer files are loaded. If this option is specified on the command line,
then none of the default options files are searched for or loaded.
An additional directory containing default options files can be
specified with --default-options. Its configuration files are loaded
after the home directory.
The order in which default options files are loaded is traced at
the verbosity level 3 (-V option) or higher.
Commands that support the JSON output specify their formats as a
serialized representation of a C++ struct or an array thereof. For
example:
struct package
{
string name;
};
struct configuration
{
uint64_t id;
string path;
optional<string> name;
bool default;
vector<package> packages;
};
An example of the serialized JSON representation of struct
configuration:
{
"id": 1,
"path": "/tmp/hello-gcc",
"name": "gcc",
"default": true,
"packages": [
{
"name": "hello"
}
]
}
This sections provides details on the overall properties of such
formats and the semantics of the struct serialization.
The order of members in a JSON object is fixed as specified in the
corresponding struct. While new members may be added in the future
(and should be ignored by older consumers), the semantics of the existing
members (including whether the top-level entry is an object or array) may
not change.
An object member is required unless its type is
optional<>, bool, or vector<> (array). For
bool members absent means false. For vector<>
members absent means empty. An empty top-level array is always present.
For example, the following JSON text is a possible serialization
of the above struct configuration:
{
"id": 1,
"path": "/tmp/hello-gcc"
}
Non-zero exit status is returned in case of an error.
The HOME environment variable is used to determine the
user's home directory. If it is not set, then getpwuid(3) is used
instead. This value is used to shorten paths printed in diagnostics by
replacing the home directory with ~/. It is also made available to
buildfile's as the build.home variable.
The BUILD2_VAR_OVR environment variable is used to
propagate global variable overrides to nested build system driver
invocations. Its value is a list of global variable assignments separated
with newlines.
The BUILD2_DEF_OPT environment variable is used to suppress
loading of default options files in nested build system driver invocations.
Its values are false or 0 to suppress and true or
1 to load.
Send bug reports to the users@build2.org mailing list.
Copyright (c) 2014-2024 the build2 authors.
Permission is granted to copy, distribute and/or modify this
document under the terms of the MIT License.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc.
|