General Buildroot usage

'make' tips

This is a collection of tips that help you make the most of Buildroot.

Display all commands executed by make:
 $ make V=1 <target>
Display the list of boards with a defconfig:
 $ make list-defconfigs
Display all available targets:
 $ make help

Not all targets are always available, some settings in the .config file may hide some targets:

  • busybox-menuconfig only works when busybox is enabled;

  • linux-menuconfig and linux-savedefconfig only work when linux is enabled;

  • uclibc-menuconfig is only available when the uClibc C library is selected in the internal toolchain backend;

  • barebox-menuconfig and barebox-savedefconfig only work when the barebox bootloader is enabled.

  • uboot-menuconfig and uboot-savedefconfig only work when the U-Boot bootloader is enabled and the uboot build system is set to Kconfig.

Cleaning:

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
Generating the manual:

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'.

Notes
Resetting Buildroot for a new target:

To delete all build products as well as the configuration:

 $ make distclean
Notes

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.

Dumping the internal make variables:

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 to YES, will single-quote the value

  • RAW_VARS, if set to YES, 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 without openssl. Your system works, but you realize you would like to have SSL support in ctorrent, so you enable the openssl package in Buildroot configuration and restart the build. Buildroot will detect that openssl should be built and will be build it, but it will not detect that ctorrent should be rebuilt to benefit from openssl to add OpenSSL support. You will either have to do a full rebuild, or rebuild ctorrent 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 package foo is not automatically rebuilt. For example, if a package bar is listed in FOO_DEPENDENCIES with FOO_DEPENDENCIES = bar` and the configuration of the `bar package is changed, the configuration change would not result in a rebuild of package foo automatically. In this scenario, you may need to either rebuild any packages in your build which reference bar in their DEPENDENCIES, or perform a full rebuild to ensure any bar 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, either pdf (the default), or png.

  • 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 the dot 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 of auto, never or always):

    • cp --sparse=always source.file dest.file will make dest.file a sparse file if source.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 to N levels. The default, 0, means no limit.

  • --stop-on PKG, -s PKG, to stop the graph on the package PKG. 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 omits PKG 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 below X 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.

Note

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

Note

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:

  1. Enable the option BR2_PER_PACKAGE_DIRECTORIES in the Buildroot configuration

  2. 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 and BR2_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

source

Fetch the source (download the tarball, clone the source repository, etc)

depends

Build and install all dependencies required to build the package

extract

Put the source in the package build directory (extract the tarball, copy the source, etc)

patch

Apply the patches, if any

configure

Run the configure commands, if any

build

Run the compilation commands

install-staging

target package: Run the installation of the package in the staging directory, if necessary

install-target

target package: Run the installation of the package in the target directory, if necessary

install

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

show-depends

Displays the first-order dependencies required to build the package

show-recursive-depends

Recursively displays the dependencies required to build the package

show-rdepends

Displays the first-order reverse dependencies of the package (i.e packages that directly depend on it)

show-recursive-rdepends

Recursively displays the reverse dependencies of the package (i.e the packages that depend on it, directly or indirectly)

graph-depends

Generate a dependency graph of the package, in the context of the current Buildroot configuration. See this section for more details about dependency graphs.

graph-rdepends

Generate a graph of this package reverse dependencies (i.e the packages that depend on it, directly or indirectly)

dirclean

Remove the whole package build directory

reinstall

Re-run the install commands

rebuild

Re-run the compilation commands - this only makes sense when using the OVERRIDE_SRCDIR feature or when you modified a file directly in the build directory

reconfigure

Re-run the configure commands, then rebuild - this only makes sense when using the OVERRIDE_SRCDIR feature or when you modified a file directly in the build directory

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