General Buildroot usage
'make' tips
This is a collection of tips that help you make the most of Buildroot.
$ make V=1 <target>
$ make list-defconfigs
$ make help
Not all targets are always available,
some settings in the .config
file may hide some targets:
-
busybox-menuconfig
only works whenbusybox
is enabled; -
linux-menuconfig
andlinux-savedefconfig
only work whenlinux
is enabled; -
uclibc-menuconfig
is only available when the uClibc C library is selected in the internal toolchain backend; -
barebox-menuconfig
andbarebox-savedefconfig
only work when thebarebox
bootloader is enabled. -
uboot-menuconfig
anduboot-savedefconfig
only work when theU-Boot
bootloader is enabled and theuboot
build system is set toKconfig
.
Explicit cleaning is required when any of the architecture or toolchain configuration options are changed.
To delete all build products (including build directories, host, staging and target trees, the images and the toolchain):
$ make clean
The present manual sources are located in the 'docs/manual' directory. To generate the manual:
$ make manual-clean $ make manual
The manual outputs will be generated in 'output/docs/manual'.
-
A few tools are required to build the documentation (see: [requirement-optional]).
To delete all build products as well as the configuration:
$ make distclean
If ccache
is enabled, running make clean
or distclean
does
not empty the compiler cache used by Buildroot. To delete it, refer
to Using ccache
in Buildroot.
One can dump the variables known to make, along with their values:
$ make -s printvars VARS='VARIABLE1 VARIABLE2' VARIABLE1=value_of_variable VARIABLE2=value_of_variable
It is possible to tweak the output using some variables:
-
VARS
will limit the listing to variables which names match the specified make-patterns - this must be set else nothing is printed -
QUOTED_VARS
, if set toYES
, will single-quote the value -
RAW_VARS
, if set toYES
, will print the unexpanded value
For example:
$ make -s printvars VARS=BUSYBOX_%DEPENDENCIES BUSYBOX_DEPENDENCIES=skeleton toolchain BUSYBOX_FINAL_ALL_DEPENDENCIES=skeleton toolchain BUSYBOX_FINAL_DEPENDENCIES=skeleton toolchain BUSYBOX_FINAL_PATCH_DEPENDENCIES= BUSYBOX_RDEPENDENCIES=ncurses util-linux
$ make -s printvars VARS=BUSYBOX_%DEPENDENCIES QUOTED_VARS=YES BUSYBOX_DEPENDENCIES='skeleton toolchain' BUSYBOX_FINAL_ALL_DEPENDENCIES='skeleton toolchain' BUSYBOX_FINAL_DEPENDENCIES='skeleton toolchain' BUSYBOX_FINAL_PATCH_DEPENDENCIES='' BUSYBOX_RDEPENDENCIES='ncurses util-linux'
$ make -s printvars VARS=BUSYBOX_%DEPENDENCIES RAW_VARS=YES BUSYBOX_DEPENDENCIES=skeleton toolchain BUSYBOX_FINAL_ALL_DEPENDENCIES=$(sort $(BUSYBOX_FINAL_DEPENDENCIES) $(BUSYBOX_FINAL_PATCH_DEPENDENCIES)) BUSYBOX_FINAL_DEPENDENCIES=$(sort $(BUSYBOX_DEPENDENCIES)) BUSYBOX_FINAL_PATCH_DEPENDENCIES=$(sort $(BUSYBOX_PATCH_DEPENDENCIES)) BUSYBOX_RDEPENDENCIES=ncurses util-linux
The output of quoted variables can be reused in shell scripts, for example:
$ eval $(make -s printvars VARS=BUSYBOX_DEPENDENCIES QUOTED_VARS=YES) $ echo $BUSYBOX_DEPENDENCIES skeleton toolchain
Understanding when a full rebuild is necessary
Buildroot does not attempt to detect what parts of the system should be rebuilt when the system configuration is changed through make menuconfig`, `make xconfig or one of the other configuration tools. In some cases, Buildroot should rebuild the entire system, in some cases, only a specific subset of packages. But detecting this in a completely reliable manner is very difficult, and therefore the Buildroot developers have decided to simply not attempt to do this.
Instead, it is the responsibility of the user to know when a full rebuild is necessary. As a hint, here are a few rules of thumb that can help you understand how to work with Buildroot:
-
When the target architecture configuration is changed, a complete rebuild is needed. Changing the architecture variant, the binary format or the floating point strategy for example has an impact on the entire system.
-
When the toolchain configuration is changed, a complete rebuild generally is needed. Changing the toolchain configuration often involves changing the compiler version, the type of C library or its configuration, or some other fundamental configuration item, and these changes have an impact on the entire system.
-
When an additional package is added to the configuration, a full rebuild is not necessarily needed. Buildroot will detect that this package has never been built, and will build it. However, if this package is a library that can optionally be used by packages that have already been built, Buildroot will not automatically rebuild those. Either you know which packages should be rebuilt, and you can rebuild them manually, or you should do a full rebuild. For example, let’s suppose you have built a system with the
ctorrent
package, but withoutopenssl
. Your system works, but you realize you would like to have SSL support inctorrent
, so you enable theopenssl
package in Buildroot configuration and restart the build. Buildroot will detect thatopenssl
should be built and will be build it, but it will not detect thatctorrent
should be rebuilt to benefit fromopenssl
to add OpenSSL support. You will either have to do a full rebuild, or rebuildctorrent
itself. -
When a package is removed from the configuration, Buildroot does not do anything special. It does not remove the files installed by this package from the target root filesystem or from the toolchain sysroot. A full rebuild is needed to get rid of this package. However, generally you don’t necessarily need this package to be removed right now: you can wait for the next lunch break to restart the build from scratch.
-
When the sub-options of a package are changed, the package is not automatically rebuilt. After making such changes, rebuilding only this package is often sufficient, unless enabling the package sub-option adds some features to the package that are useful for another package which has already been built. Again, Buildroot does not track when a package should be rebuilt: once a package has been built, it is never rebuilt unless explicitly told to do so.
-
When a change to the root filesystem skeleton is made, a full rebuild is needed. However, when changes to the root filesystem overlay, a post-build script or a post-image script are made, there is no need for a full rebuild: a simple
make
invocation will take the changes into account. -
When a package listed in
FOO_DEPENDENCIES
is rebuilt or removed, the packagefoo
is not automatically rebuilt. For example, if a packagebar
is listed inFOO_DEPENDENCIES
with FOO_DEPENDENCIES = bar` and the configuration of the `bar package is changed, the configuration change would not result in a rebuild of packagefoo
automatically. In this scenario, you may need to either rebuild any packages in your build which referencebar
in theirDEPENDENCIES
, or perform a full rebuild to ensure anybar
dependent packages are up to date.
Generally speaking, when you’re facing a build error and you’re unsure of the potential consequences of the configuration changes you’ve made, do a full rebuild. If you get the same build error, then you are sure that the error is not related to partial rebuilds of packages, and if this error occurs with packages from the official Buildroot, do not hesitate to report the problem! As your experience with Buildroot progresses, you will progressively learn when a full rebuild is really necessary, and you will save more and more time.
For reference, a full rebuild is achieved by running:
$ make clean all
Understanding how to rebuild packages
One of the most common questions asked by Buildroot users is how to rebuild a given package or how to remove a package without rebuilding everything from scratch.
Removing a package is unsupported by Buildroot without
rebuilding from scratch. This is because Buildroot doesn’t keep track
of which package installs what files in the output/staging
and
output/target
directories, or which package would be compiled differently
depending on the availability of another package.
The easiest way to rebuild a single package from scratch is to remove
its build directory in output/build
. Buildroot will then re-extract,
re-configure, re-compile and re-install this package from scratch. You
can ask buildroot to do this with the make <package>-dirclean
command.
On the other hand, if you only want to restart the build process of a
package from its compilation step, you can run make <package>-rebuild
. It
will restart the compilation and installation of the package, but not from
scratch: it basically re-executes make
and make install
inside the package,
so it will only rebuild files that changed.
If you want to restart the build process of a package from its configuration
step, you can run make <package>-reconfigure
. It will restart the
configuration, compilation and installation of the package.
While <package>-rebuild
implies <package>-reinstall
and
<package>-reconfigure
implies <package>-rebuild
, these targets as well
as <package>
only act on the said package, and do not trigger re-creating
the root filesystem image. If re-creating the root filesystem in necessary,
one should in addition run make
or make all
.
Internally, Buildroot creates so-called stamp files to keep track of
which build steps have been completed for each package. They are
stored in the package build directory,
output/build/<package>-<version>/
and are named
.stamp_<step-name>
. The commands detailed above simply manipulate
these stamp files to force Buildroot to restart a specific set of
steps of a package build process.
Further details about package special make targets are explained in Package-specific make targets.
Offline builds
If you intend to do an offline build and just want to download all sources that you previously selected in the configurator ('menuconfig', 'nconfig', 'xconfig' or 'gconfig'), then issue:
$ make source
You can now disconnect or copy the content of your dl
directory to the build-host.
Building out-of-tree
As default, everything built by Buildroot is stored in the directory
output
in the Buildroot tree.
Buildroot also supports building out of tree with a syntax similar to
the Linux kernel. To use it, add O=<directory>
to the make command
line:
$ make O=/tmp/build
Or:
$ cd /tmp/build; make O=$PWD -C path/to/buildroot
All the output files will be located under /tmp/build
. If the O
path does not exist, Buildroot will create it.
Note: the O
path can be either an absolute or a relative path, but if it’s
passed as a relative path, it is important to note that it is interpreted
relative to the main Buildroot source directory, not the current working
directory.
When using out-of-tree builds, the Buildroot .config
and temporary
files are also stored in the output directory. This means that you can
safely run multiple builds in parallel using the same source tree as
long as they use unique output directories.
For ease of use, Buildroot generates a Makefile wrapper in the output
directory - so after the first run, you no longer need to pass O=<…>
and -C <…>
, simply run (in the output directory):
$ make <target>
Environment variables
Buildroot also honors some environment variables, when they are passed
to make
or set in the environment:
-
HOSTCXX
, the host C`` compiler to use -
HOSTCC
, the host C compiler to use -
UCLIBC_CONFIG_FILE=<path/to/.config>
, path to the uClibc configuration file, used to compile uClibc, if an internal toolchain is being built. + Note that the uClibc configuration file can also be set from the configuration interface, so through the Buildroot.config
file; this is the recommended way of setting it. + -
BUSYBOX_CONFIG_FILE=<path/to/.config>
, path to the BusyBox configuration file. + Note that the BusyBox configuration file can also be set from the configuration interface, so through the Buildroot.config
file; this is the recommended way of setting it. + -
BR2_CCACHE_DIR
to override the directory where Buildroot stores the cached files when using ccache. + -
BR2_DL_DIR
to override the directory in which Buildroot stores/retrieves downloaded files. + Note that the Buildroot download directory can also be set from the configuration interface, so through the Buildroot.config
file. See Location of downloaded packages for more details on how you can set the download directory. -
BR2_GRAPH_ALT
, if set and non-empty, to use an alternate color-scheme in build-time graphs -
BR2_GRAPH_OUT
to set the filetype of generated graphs, eitherpdf
(the default), orpng
. -
BR2_GRAPH_DEPS_OPTS
to pass extra options to the dependency graph; see [graph-depends] for the accepted options -
BR2_GRAPH_DOT_OPTS
is passed verbatim as options to thedot
utility to draw the dependency graph. -
BR2_GRAPH_SIZE_OPTS
to pass extra options to the size graph; see Graphing the filesystem size contribution of packages for the acepted options
An example that uses config files located in the toplevel directory and in your $HOME:
$ make UCLIBC_CONFIG_FILE=uClibc.config BUSYBOX_CONFIG_FILE=$HOME/bb.config
If you want to use a compiler other than the default gcc
or g``
for building helper-binaries on your host, then do
$ make HOSTCXX=g``-4.3-HEAD HOSTCC=gcc-4.3-HEAD
Dealing efficiently with filesystem images
Filesystem images can get pretty big, depending on the filesystem you choose, the number of packages, whether you provisioned free space… Yet, some locations in the filesystems images may just be empty (e.g. a long run of 'zeroes'); such a file is called a sparse file.
Most tools can handle sparse files efficiently, and will only store or write those parts of a sparse file that are not empty.
For example:
-
tar
accepts the-S
option to tell it to only store non-zero blocks of sparse files:-
tar cf archive.tar -S [files…]
will efficiently store sparse files in a tarball -
tar xf archive.tar -S
will efficiently store sparse files extracted from a tarball
-
-
cp
accepts the--sparse=WHEN
option (WHEN
is one ofauto
,never
oralways
):-
cp --sparse=always source.file dest.file
will makedest.file
a sparse file ifsource.file
has long runs of zeroes
-
Other tools may have similar options. Please consult their respective man pages.
You can use sparse files if you need to store the filesystem images (e.g. to transfer from one machine to another), or if you need to send them (e.g. to the Q&A team).
Note however that flashing a filesystem image to a device while using the
sparse mode of dd
may result in a broken filesystem (e.g. the block bitmap
of an ext2 filesystem may be corrupted; or, if you have sparse files in
your filesystem, those parts may not be all-zeroes when read back). You
should only use sparse files when handling files on the build machine, not
when transferring them to an actual device that will be used on the target.
Details about packages
Buildroot can produce a JSON blurb that describes the set of enabled
packages in the current configuration, together with their
dependencies, licenses and other metadata. This JSON blurb is produced
by using the show-info
make target:
make show-info
Buildroot can also produce details about packages as HTML and JSON
output using the pkg-stats
make target. Amongst other things, these
details include whether known CVEs (security vulnerabilities) affect
the packages in your current configuration. It also shows if there is
a newer upstream version for those packages.
make pkg-stats
Graphing the dependencies between packages
One of Buildroot’s jobs is to know the dependencies between packages, and make sure they are built in the right order. These dependencies can sometimes be quite complicated, and for a given system, it is often not easy to understand why such or such package was brought into the build by Buildroot.
In order to help understanding the dependencies, and therefore better understand what is the role of the different components in your embedded Linux system, Buildroot is capable of generating dependency graphs.
To generate a dependency graph of the full system you have compiled, simply run:
make graph-depends
You will find the generated graph in
output/graphs/graph-depends.pdf
.
If your system is quite large, the dependency graph may be too complex and difficult to read. It is therefore possible to generate the dependency graph just for a given package:
make <pkg>-graph-depends
You will find the generated graph in
output/graph/<pkg>-graph-depends.pdf
.
Note that the dependency graphs are generated using the dot
tool
from the Graphviz project, which you must have installed on your
system to use this feature. In most distributions, it is available as
the graphviz
package.
By default, the dependency graphs are generated in the PDF
format. However, by passing the BR2_GRAPH_OUT
environment variable, you
can switch to other output formats, such as PNG, PostScript or
SVG. All formats supported by the -T
option of the dot
tool are
supported.
BR2_GRAPH_OUT=svg make graph-depends
The graph-depends
behaviour can be controlled by setting options in the
BR2_GRAPH_DEPS_OPTS
environment variable. The accepted options are:
-
--depth N
,-d N
, to limit the dependency depth toN
levels. The default,0
, means no limit. -
--stop-on PKG
,-s PKG
, to stop the graph on the packagePKG
.PKG
can be an actual package name, a glob, the keyword 'virtual' (to stop on virtual packages), or the keyword 'host' (to stop on host packages). The package is still present on the graph, but its dependencies are not. -
--exclude PKG
,-x PKG
, like--stop-on
, but also omitsPKG
from the graph. -
--transitive
,--no-transitive
, to draw (or not) the transitive dependencies. The default is to not draw transitive dependencies. -
--colors R,T,H
, the comma-separated list of colors to draw the root package (R
), the target packages (T
) and the host packages (H
). Defaults to:lightblue,grey,gainsboro
BR2_GRAPH_DEPS_OPTS='-d 3 --no-transitive --colors=red,green,blue' make graph-depends
Graphing the build duration
When the build of a system takes a long time, it is sometimes useful to be able to understand which packages are the longest to build, to see if anything can be done to speed up the build. In order to help such build time analysis, Buildroot collects the build time of each step of each package, and allows to generate graphs from this data.
To generate the build time graph after a build, run:
make graph-build
This will generate a set of files in output/graphs
:
-
build.hist-build.pdf
, a histogram of the build time for each package, ordered in the build order. -
build.hist-duration.pdf
, a histogram of the build time for each package, ordered by duration (longest first) -
build.hist-name.pdf
, a histogram of the build time for each package, order by package name. -
build.pie-packages.pdf
, a pie chart of the build time per package -
build.pie-steps.pdf
, a pie chart of the global time spent in each step of the packages build process.
This graph-build
target requires the Python Matplotlib and Numpy
libraries to be installed (python-matplotlib
and python-numpy
on
most distributions), and also the argparse
module if you’re using a
Python version older than 2.7 (python-argparse
on most
distributions).
By default, the output format for the graph is PDF, but a different
format can be selected using the BR2_GRAPH_OUT
environment variable. The
only other format supported is PNG:
BR2_GRAPH_OUT=png make graph-build
Graphing the filesystem size contribution of packages
When your target system grows, it is sometimes useful to understand how much each Buildroot package is contributing to the overall root filesystem size. To help with such an analysis, Buildroot collects data about files installed by each package and using this data, generates a graph and CSV files detailing the size contribution of the different packages.
To generate these data after a build, run:
make graph-size
This will generate:
-
output/graphs/graph-size.pdf
, a pie chart of the contribution of each package to the overall root filesystem size -
output/graphs/package-size-stats.csv
, a CSV file giving the size contribution of each package to the overall root filesystem size -
output/graphs/file-size-stats.csv
, a CSV file giving the size contribution of each installed file to the package it belongs, and to the overall filesystem size.
This graph-size
target requires the Python Matplotlib library to be
installed (python-matplotlib
on most distributions), and also the
argparse
module if you’re using a Python version older than 2.7
(python-argparse
on most distributions).
Just like for the duration graph, a BR2_GRAPH_OUT
environment variable
is supported to adjust the output file format. See [graph-depends]
for details about this environment variable.
Additionally, one may set the environment variable BR2_GRAPH_SIZE_OPTS
to further control the generated graph. Accepted options are:
-
--size-limit X
,-l X
, will group all packages which individual contribution is belowX
percent, to a single entry labelled Others in the graph. By default,X=0.01
, which means packages each contributing less than 1% are grouped under Others. Accepted values are in the range[0.0..1.0]
. -
--iec
,--binary
,--si
,--decimal
, to use IEC (binary, powers of 1024) or SI (decimal, powers of 1000; the default) prefixes. -
--biggest-first
, to sort packages in decreasing size order, rather than in increasing size order.
The collected filesystem size data is only meaningful after a complete
clean rebuild. Be sure to run make clean all
before using make
graph-size.
To compare the root filesystem size of two different Buildroot compilations,
for example after adjusting the configuration or when switching to another
Buildroot release, use the size-stats-compare
script. It takes two
file-size-stats.csv
files (produced by make graph-size
) as input.
Refer to the help text of this script for more details:
utils/size-stats-compare -h
Top-level parallel build
This section deals with a very experimental feature, which is known to break even in some non-unusual situations. Use at your own risk.
Buildroot has always been capable of using parallel build on a per
package basis: each package is built by Buildroot using make -jN
(or
the equivalent invocation for non-make-based build systems). The level
of parallelism is by default number of CPUs + 1, but it can be
adjusted using the BR2_JLEVEL
configuration option.
Until 2020.02, Buildroot was however building packages in a serial fashion: each package was built one after the other, without parallelization of the build between packages. As of 2020.02, Buildroot has experimental support for top-level parallel build, which allows some signicant build time savings by building packages that have no dependency relationship in parallel. This feature is however marked as experimental and is known not to work in some cases.
In order to use top-level parallel build, one must:
-
Enable the option
BR2_PER_PACKAGE_DIRECTORIES
in the Buildroot configuration -
Use
make -jN
when starting the Buildroot build
Internally, the BR2_PER_PACKAGE_DIRECTORIES
will enable a mechanism
called per-package directories, which will have the following
effects:
-
Instead of a global target directory and a global host directory common to all packages, per-package target and host directories will be used, in
$(O)/per-package/<pkg>/target/
and$(O)/per-package/<pkg>/host/
respectively. Those folders will be populated from the corresponding folders of the package dependencies at the beginning of<pkg>
build. The compiler and all other tools will therefore only be able to see and access files installed by dependencies explicitly listed by<pkg>
. -
At the end of the build, the global target and host directories will be populated, located in
$(O)/target
and$(O)/host
respectively. This means that during the build, those folders will be empty and it’s only at the very end of the build that they will be populated.
Advanced usage
Using the generated toolchain outside Buildroot
You may want to compile, for your target, your own programs or other software that are not packaged in Buildroot. In order to do this you can use the toolchain that was generated by Buildroot.
The toolchain generated by Buildroot is located by default in
output/host/
. The simplest way to use it is to add
output/host/bin/
to your PATH environment variable and then to
use ARCH-linux-gcc
, ARCH-linux-objdump
, ARCH-linux-ld
, etc.
Alternatively, Buildroot can also export the toolchain and the development
files of all selected packages, as an SDK, by running the command
make sdk
. This generates a tarball of the content of the host directory
output/host/
, named <TARGET-TUPLE>_sdk-buildroot.tar.gz
(which can be
overriden by setting the environment variable BR2_SDK_PREFIX
) and
located in the output directory output/images/
.
This tarball can then be distributed to application developers, when they want to develop their applications that are not (yet) packaged as a Buildroot package.
Upon extracting the SDK tarball, the user must run the script
relocate-sdk.sh
(located at the top directory of the SDK), to make
sure all paths are updated with the new location.
Alternatively, if you just want to prepare the SDK without generating
the tarball (e.g. because you will just be moving the host
directory,
or will be generating the tarball on your own), Buildroot also allows
you to just prepare the SDK with make prepare-sdk
without actually
generating a tarball.
For your convenience, by selecting the option
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP
, you can get a
environment-setup
script installed in output/host/
and therefore
in your SDK. This script can be sourced with
. your/sdk/path/environment-setup
to export a number of environment
variables that will help cross-compile your projects using the
Buildroot SDK: the PATH
will contain the SDK binaries, standard
autotools variables will be defined with the appropriate values, and
CONFIGURE_FLAGS
will contain basic ./configure
options to
cross-compile autotools projects. It also provides some useful
commands. Note however that once this script is sourced, the
environment is setup only for cross-compilation, and no longer for
native compilation.
Using gdb
in Buildroot
Buildroot allows to do cross-debugging, where the debugger runs on the
build machine and communicates with gdbserver
on the target to
control the execution of the program.
To achieve this:
-
If you are using an internal toolchain (built by Buildroot), you must enable
BR2_PACKAGE_HOST_GDB
,BR2_PACKAGE_GDB
andBR2_PACKAGE_GDB_SERVER
. This ensures that both the cross gdb and gdbserver get built, and that gdbserver gets installed to your target. -
If you are using an external toolchain, you should enable
BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY
, which will copy the gdbserver included with the external toolchain to the target. If your external toolchain does not have a cross gdb or gdbserver, it is also possible to let Buildroot build them, by enabling the same options as for the internal toolchain backend.
Now, to start debugging a program called foo
, you should run on the
target:
gdbserver :2345 foo
This will cause gdbserver
to listen on TCP port 2345 for a connection
from the cross gdb.
Then, on the host, you should start the cross gdb using the following command line:
<buildroot>/output/host/bin/<tuple>-gdb -ix <buildroot>/output/staging/usr/share/buildroot/gdbinit foo
Of course, foo
must be available in the current directory, built
with debugging symbols. Typically you start this command from the
directory where foo
is built (and not from output/target/
as the
binaries in that directory are stripped).
The <buildroot>/output/staging/usr/share/buildroot/gdbinit
file will tell the
cross gdb where to find the libraries of the target.
Finally, to connect to the target from the cross gdb:
(gdb) target remote <target ip address>:2345
Using ccache
in Buildroot
ccache is a compiler cache. It stores the object files resulting from each compilation process, and is able to skip future compilation of the same source file (with same compiler and same arguments) by using the pre-existing object files. When doing almost identical builds from scratch a number of times, it can nicely speed up the build process.
ccache
support is integrated in Buildroot. You just have to enable
Enable compiler cache
in Build options
. This will automatically
build ccache
and use it for every host and target compilation.
The cache is located in the directory defined by the BR2_CCACHE_DIR
configuration option, which defaults to
$HOME/.buildroot-ccache
. This default location is outside of
Buildroot output directory so that it can be shared by separate
Buildroot builds. If you want to get rid of the cache, simply remove
this directory.
You can get statistics on the cache (its size, number of hits,
misses, etc.) by running make ccache-stats
.
The make target ccache-options
and the CCACHE_OPTIONS
variable
provide more generic access to the ccache. For example
# set cache limit size make CCACHE_OPTIONS="--max-size=5G" ccache-options # zero statistics counters make CCACHE_OPTIONS="--zero-stats" ccache-options
ccache
makes a hash of the source files and of the compiler options.
If a compiler option is different, the cached object file will not be
used. Many compiler options, however, contain an absolute path to the
staging directory. Because of this, building in a different output
directory would lead to many cache misses.
To avoid this issue, buildroot has the Use relative paths
option
(BR2_CCACHE_USE_BASEDIR
). This will rewrite all absolute paths that
point inside the output directory into relative paths. Thus, changing
the output directory no longer leads to cache misses.
A disadvantage of the relative paths is that they also end up to be relative paths in the object file. Therefore, for example, the debugger will no longer find the file, unless you cd to the output directory first.
See the ccache manual’s section on "Compiling in different directories" for more details about this rewriting of absolute paths.
When ccache
is enabled in Buildroot using the BR2_CCACHE=y
option:
-
ccache
is used during the Buildroot build itself -
ccache
is not used when building outside of Buildroot, for example when directly calling the cross-compiler or using the SDK
One can override this behavior using the BR2_USE_CCACHE
environment
variable: when set to 1
, usage of ccache is enabled (default during
the Buildroot build), when unset or set to a value different from 1
,
usage of ccache is disabled.
Location of downloaded packages
The various tarballs that are downloaded by Buildroot are all stored
in BR2_DL_DIR
, which by default is the dl
directory. If you want
to keep a complete version of Buildroot which is known to be working
with the associated tarballs, you can make a copy of this directory.
This will allow you to regenerate the toolchain and the target
filesystem with exactly the same versions.
If you maintain several Buildroot trees, it might be better to have a
shared download location. This can be achieved by pointing the
BR2_DL_DIR
environment variable to a directory. If this is
set, then the value of BR2_DL_DIR
in the Buildroot configuration is
overridden. The following line should be added to <~/.bashrc>
.
export BR2_DL_DIR=<shared download location>
The download location can also be set in the .config
file, with the
BR2_DL_DIR
option. Unlike most options in the .config file, this value
is overridden by the BR2_DL_DIR
environment variable.
Package-specific make targets
Running make <package>
builds and installs that particular package
and its dependencies.
For packages relying on the Buildroot infrastructure, there are numerous special make targets that can be called independently like this:
make <package>-<target>
The package build targets are (in the order they are executed):
command/target | Description |
---|---|
|
Fetch the source (download the tarball, clone the source repository, etc) |
|
Build and install all dependencies required to build the package |
|
Put the source in the package build directory (extract the tarball, copy the source, etc) |
|
Apply the patches, if any |
|
Run the configure commands, if any |
|
Run the compilation commands |
|
target package: Run the installation of the package in the staging directory, if necessary |
|
target package: Run the installation of the package in the target directory, if necessary |
|
target package: Run the 2 previous installation commands host package: Run the installation of the package in the host directory |
Additionally, there are some other useful make targets:
command/target | Description |
---|---|
|
Displays the first-order dependencies required to build the package |
|
Recursively displays the dependencies required to build the package |
|
Displays the first-order reverse dependencies of the package (i.e packages that directly depend on it) |
|
Recursively displays the reverse dependencies of the package (i.e the packages that depend on it, directly or indirectly) |
|
Generate a dependency graph of the package, in the context of the current Buildroot configuration. See this section for more details about dependency graphs. |
|
Generate a graph of this package reverse dependencies (i.e the packages that depend on it, directly or indirectly) |
|
Remove the whole package build directory |
|
Re-run the install commands |
|
Re-run the compilation commands - this only makes
sense when using the |
|
Re-run the configure commands, then rebuild - this only
makes sense when using the |
Using Buildroot during development
The normal operation of Buildroot is to download a tarball, extract
it, configure, compile and install the software component found inside
this tarball. The source code is extracted in
output/build/<package>-<version>
, which is a temporary directory:
whenever make clean
is used, this directory is entirely removed, and
re-created at the next make
invocation. Even when a Git or
Subversion repository is used as the input for the package source
code, Buildroot creates a tarball out of it, and then behaves as it
normally does with tarballs.
This behavior is well-suited when Buildroot is used mainly as an integration tool, to build and integrate all the components of an embedded Linux system. However, if one uses Buildroot during the development of certain components of the system, this behavior is not very convenient: one would instead like to make a small change to the source code of one package, and be able to quickly rebuild the system with Buildroot.
Making changes directly in output/build/<package>-<version>
is not
an appropriate solution, because this directory is removed on make
clean.
Therefore, Buildroot provides a specific mechanism for this use case:
the <pkg>_OVERRIDE_SRCDIR
mechanism. Buildroot reads an override
file, which allows the user to tell Buildroot the location of the
source for certain packages.
The default location of the override file is $(CONFIG_DIR)/local.mk
,
as defined by the BR2_PACKAGE_OVERRIDE_FILE
configuration option.
$(CONFIG_DIR)
is the location of the Buildroot .config
file, so
local.mk
by default lives side-by-side with the .config
file,
which means:
-
In the top-level Buildroot source directory for in-tree builds (i.e., when
O=
is not used) -
In the out-of-tree directory for out-of-tree builds (i.e., when
O=
is used)
If a different location than these defaults is required, it can be
specified through the BR2_PACKAGE_OVERRIDE_FILE
configuration
option.
In this override file, Buildroot expects to find lines of the form:
<pkg1>_OVERRIDE_SRCDIR = /path/to/pkg1/sources <pkg2>_OVERRIDE_SRCDIR = /path/to/pkg2/sources
For example:
LINUX_OVERRIDE_SRCDIR = /home/bob/linux/ BUSYBOX_OVERRIDE_SRCDIR = /home/bob/busybox/
When Buildroot finds that for a given package, an
<pkg>_OVERRIDE_SRCDIR
has been defined, it will no longer attempt to
download, extract and patch the package. Instead, it will directly use
the source code available in the specified directory and make clean
will not touch this directory. This allows to point Buildroot to your
own directories, that can be managed by Git, Subversion, or any other
version control system. To achieve this, Buildroot will use rsync to
copy the source code of the component from the specified
<pkg>_OVERRIDE_SRCDIR
to output/build/<package>-custom/
.
This mechanism is best used in conjunction with the make
<pkg>-rebuild` and `make <pkg>-reconfigure` targets. A `make
<pkg>-rebuild all sequence will rsync the source code from
<pkg>_OVERRIDE_SRCDIR
to output/build/<package>-custom
(thanks to
rsync, only the modified files are copied), and restart the build
process of just this package.
In the example of the linux
package above, the developer can then
make a source code change in /home/bob/linux
and then run:
make linux-rebuild all
and in a matter of seconds gets the updated Linux kernel image in
output/images
. Similarly, a change can be made to the BusyBox source
code in /home/bob/busybox
, and after:
make busybox-rebuild all
the root filesystem image in output/images
contains the updated
BusyBox.
Source trees for big projects often contain hundreds or thousands of
files which are not needed for building, but will slow down the process
of copying the sources with rsync. Optionally, it is possible define
<pkg>_OVERRIDE_SRCDIR_RSYNC_EXCLUSIONS
to skip syncing certain files
from the source tree. For example, when working on the webkitgtk
package, the following will exclude the tests and in-tree builds from
a local WebKit source tree:
WEBKITGTK_OVERRIDE_SRCDIR = /home/bob/WebKit WEBKITGTK_OVERRIDE_SRCDIR_RSYNC_EXCLUSIONS = \ --exclude JSTests --exclude ManualTests --exclude PerformanceTests \ --exclude WebDriverTests --exclude WebKitBuild --exclude WebKitLibraries \ --exclude WebKit.xcworkspace --exclude Websites --exclude Examples
By default, Buildroot skips syncing of VCS artifacts (e.g., the .git and .svn directories). Some packages prefer to have these VCS directories available during build, for example for automatically determining a precise commit reference for version information. To undo this built-in filtering at a cost of a slower speed, add these directories back:
LINUX_OVERRIDE_SRCDIR_RSYNC_EXCLUSIONS = --include .git