Typical actions you may need to perform for a given project are:
customizing the generated target filesystem
BR2_ROOTFS_OVERLAY
)
BR2_ROOTFS_POST_BUILD_SCRIPT
)
BR2_ROOTFS_POST_BUILD_SCRIPT
)
BR2_ROOTFS_DEVICE_TABLE
)
BR2_ROOTFS_STATIC_DEVICE_TABLE
)
BR2_ROOTFS_USERS_TABLES
)
BR2_ROOTFS_POST_IMAGE_SCRIPT
)
BR2_GLOBAL_PATCH_DIR
)
An important note regarding such project-specific customizations: please carefully consider which changes are indeed project-specific and which changes are also useful to developers outside your project. The Buildroot community highly recommends and encourages the upstreaming of improvements, packages and board support to the official Buildroot project. Of course, it is sometimes not possible or desirable to upstream because the changes are highly specific or proprietary.
This chapter describes how to make such project-specific customizations in Buildroot and how to store them in a way that you can build the same image in a reproducible way, even after running make clean. By following the recommended strategy, you can even use the same Buildroot tree to build multiple distinct projects!
When customizing Buildroot for your project, you will be creating one or more project-specific files that need to be stored somewhere. While most of these files could be placed in any location as their path is to be specified in the Buildroot configuration, the Buildroot developers recommend a specific directory structure which is described in this section.
Orthogonal to this directory structure, you can choose where you place this structure itself: either inside the Buildroot tree, or outside of it using a br2-external tree. Both options are valid, the choice is up to you.
+-- board/ | +-- <company>/ | +-- <boardname>/ | +-- linux.config | +-- busybox.config | +-- <other configuration files> | +-- post_build.sh | +-- post_image.sh | +-- rootfs_overlay/ | | +-- etc/ | | +-- <some files> | +-- patches/ | +-- foo/ | | +-- <some patches> | +-- libbar/ | +-- <some other patches> | +-- configs/ | +-- <boardname>_defconfig | +-- package/ | +-- <company>/ | +-- Config.in (if not using a br2-external tree) | +-- <company>.mk (if not using a br2-external tree) | +-- package1/ | | +-- Config.in | | +-- package1.mk | +-- package2/ | +-- Config.in | +-- package2.mk | +-- Config.in (if using a br2-external tree) +-- external.mk (if using a br2-external tree) +-- external.desc (if using a br2-external tree)
Details on the files shown above are given further in this chapter.
Note: if you choose to place this structure outside of the Buildroot tree but in a br2-external tree, the <company> and possibly <boardname> components may be superfluous and can be left out.
It is quite common for a user to have several related projects that partly need the same customizations. Instead of duplicating these customizations for each project, it is recommended to use a layered customization approach, as explained in this section.
Almost all of the customization methods available in Buildroot, like
post-build scripts and root filesystem overlays, accept a
space-separated list of items. The specified items are always treated in
order, from left to right. By creating more than one such item, one for
the common customizations and another one for the really
project-specific customizations, you can avoid unnecessary duplication.
Each layer is typically embodied by a separate directory inside
board/<company>/
. Depending on your projects, you could even introduce
more than two layers.
An example directory structure for where a user has two customization layers common and fooboard is:
+-- board/ +-- <company>/ +-- common/ | +-- post_build.sh | +-- rootfs_overlay/ | | +-- ... | +-- patches/ | +-- ... | +-- fooboard/ +-- linux.config +-- busybox.config +-- <other configuration files> +-- post_build.sh +-- rootfs_overlay/ | +-- ... +-- patches/ +-- ...
For example, if the user has the BR2_GLOBAL_PATCH_DIR
configuration
option set as:
BR2_GLOBAL_PATCH_DIR="board/<company>/common/patches board/<company>/fooboard/patches"
then first the patches from the common layer would be applied, followed by the patches from the fooboard layer.
As already briefly mentioned in Section 9.1, “Recommended directory structure”, you can place project-specific customizations in two locations:
One can tell Buildroot to use one or more br2-external trees by setting
the BR2_EXTERNAL
make variable set to the path(s) of the br2-external
tree(s) to use. It can be passed to any Buildroot make
invocation. It
is automatically saved in the hidden .br2-external.mk
file in the output
directory. Thanks to this, there is no need to pass BR2_EXTERNAL
at
every make
invocation. It can however be changed at any time by
passing a new value, and can be removed by passing an empty value.
Note. The path to a br2-external tree can be either absolute or relative. If it is passed as a relative path, it is important to note that it is interpreted relative to the main Buildroot source directory, not to the Buildroot output directory.
Note: If using an br2-external tree from before Buildroot 2016.11, you need to convert it before you can use it with Buildroot 2016.11 onward. See Section 27.2, “Migrating to 2016.11” for help on doing so.
Some examples:
buildroot/ $ make BR2_EXTERNAL=/path/to/foo menuconfig
From now on, definitions from the /path/to/foo
br2-external tree
will be used:
buildroot/ $ make buildroot/ $ make legal-info
We can switch to another br2-external tree at any time:
buildroot/ $ make BR2_EXTERNAL=/where/we/have/bar xconfig
We can also use multiple br2-external trees:
buildroot/ $ make BR2_EXTERNAL=/path/to/foo:/where/we/have/bar menuconfig
Or disable the usage of any br2-external tree:
buildroot/ $ make BR2_EXTERNAL= xconfig
A br2-external tree must contain at least those three files, described in the following chapters:
external.desc
external.mk
Config.in
Apart from those mandatory files, there may be additional and optional
content that may be present in a br2-external tree, like the configs/
or provides/
directories. They are described in the following chapters
as well.
A complete example br2-external tree layout is also described later.
That file describes the br2-external tree: the name and description for that br2-external tree.
The format for this file is line based, with each line starting by a keyword, followed by a colon and one or more spaces, followed by the value assigned to that keyword. There are two keywords currently recognised:
name
, mandatory, defines the name for that br2-external tree. That
name must only use ASCII characters in the set [A-Za-z0-9_]
; any
other character is forbidden. Buildroot sets the variable
BR2_EXTERNAL_$(NAME)_PATH
to the absolute path of the br2-external
tree, so that you can use it to refer to your br2-external tree. This
variable is available both in Kconfig, so you can use it to source your
Kconfig files (see below) and in the Makefile, so that you can use it
to include other Makefiles (see below) or refer to other files (like
data files) from your br2-external tree.
Note: Since it is possible to use multiple br2-external trees at once, this name is used by Buildroot to generate variables for each of those trees. That name is used to identify your br2-external tree, so try to come up with a name that really describes your br2-external tree, in order for it to be relatively unique, so that it does not clash with another name from another br2-external tree, especially if you are planning on somehow sharing your br2-external tree with third parties or using br2-external trees from third parties.
desc
, optional, provides a short description for that br2-external
tree. It shall fit on a single line, is mostly free-form (see below),
and is used when displaying information about a br2-external tree (e.g.
above the list of defconfig files, or as the prompt in the menuconfig);
as such, it should relatively brief (40 chars is probably a good upper
limit). The description is available in the BR2_EXTERNAL_$(NAME)_DESC
variable.
Examples of names and the corresponding BR2_EXTERNAL_$(NAME)_PATH
variables:
FOO
→ BR2_EXTERNAL_FOO_PATH
BAR_42
→ BR2_EXTERNAL_BAR_42_PATH
In the following examples, it is assumed the name to be set to BAR_42
.
Note: Both BR2_EXTERNAL_$(NAME)_PATH
and BR2_EXTERNAL_$(NAME)_DESC
are
available in the Kconfig files and the Makefiles. They are also
exported in the environment so are available in post-build, post-image
and in-fakeroot scripts.
Those files (which may each be empty) can be used to define package
recipes (i.e. foo/Config.in
and foo/foo.mk
like for packages bundled
in Buildroot itself) or other custom configuration options or make logic.
Buildroot automatically includes the Config.in
from each br2-external
tree to make it appear in the top-level configuration menu, and includes
the external.mk
from each br2-external tree with the rest of the
makefile logic.
The main usage of this is to store package recipes. The recommended way
to do this is to write a Config.in
file that looks like:
source "$BR2_EXTERNAL_BAR_42_PATH/package/package1/Config.in" source "$BR2_EXTERNAL_BAR_42_PATH/package/package2/Config.in"
Then, have an external.mk
file that looks like:
include $(sort $(wildcard $(BR2_EXTERNAL_BAR_42_PATH)/package/*/*.mk))
And then in $(BR2_EXTERNAL_BAR_42_PATH)/package/package1
and
$(BR2_EXTERNAL_BAR_42_PATH)/package/package2
create normal
Buildroot package recipes, as explained in Chapter 18, Adding new packages to Buildroot.
If you prefer, you can also group the packages in subdirectories
called <boardname> and adapt the above paths accordingly.
You can also define custom configuration options in Config.in
and
custom make logic in external.mk
.
One can store Buildroot defconfigs in the configs
subdirectory of
the br2-external tree. Buildroot will automatically show them in the
output of make list-defconfigs
and allow them to be loaded with the
normal make <name>_defconfig
command. They will be visible in the
make list-defconfigs output, below an External configs
label that
contains the name of the br2-external tree they are defined in.
Note: If a defconfig file is present in more than one br2-external tree, then the one from the last br2-external tree is used. It is thus possible to override a defconfig bundled in Buildroot or another br2-external tree.
For some packages, Buildroot provides a choice between two (or more) implementations of API-compatible such packages. For example, there is a choice to choose either libjpeg or jpeg-turbo; there is one between openssl or libressl; there is one to select one of the known, pre-configured toolchains…
It is possible for a br2-external to extend those choices, by providing a set of files that define those alternatives:
provides/toolchains.in
defines the pre-configured toolchains, which
will then be listed in the toolchain selection;
provides/jpeg.in
defines the alternative libjpeg implementations;
provides/openssl.in
defines the alternative openssl implementations;
provides/skeleton.in
defines the alternative skeleton implementations;
provides/init.in
defines the alternative init system implementations, this
can be used to select a default skeleton for your init.
One can store all the board-specific configuration files there, such
as the kernel configuration, the root filesystem overlay, or any other
configuration file for which Buildroot allows to set the location (by
using the BR2_EXTERNAL_$(NAME)_PATH
variable). For example, you
could set the paths to a global patch directory, to a rootfs overlay
and to the kernel configuration file as follows (e.g. by running
make menuconfig
and filling in these options):
BR2_GLOBAL_PATCH_DIR=$(BR2_EXTERNAL_BAR_42_PATH)/patches/ BR2_ROOTFS_OVERLAY=$(BR2_EXTERNAL_BAR_42_PATH)/board/<boardname>/overlay/ BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=$(BR2_EXTERNAL_BAR_42_PATH)/board/<boardname>/kernel.config
Additional Linux kernel extensions (see Section 18.22.2, “linux-kernel-extensions”) can
be added by storing them in the linux/
directory at the root of a
br2-external tree.
Here is an example layout using all features of br2-external (the sample content is shown for the file above it, when it is relevant to explain the br2-external tree; this is all entirely made up just for the sake of illustration, of course):
/path/to/br2-ext-tree/ |- external.desc | |name: BAR_42 | |desc: Example br2-external tree | `---- | |- Config.in | |source "$BR2_EXTERNAL_BAR_42_PATH/toolchain/toolchain-external-mine/Config.in.options" | |source "$BR2_EXTERNAL_BAR_42_PATH/package/pkg-1/Config.in" | |source "$BR2_EXTERNAL_BAR_42_PATH/package/pkg-2/Config.in" | |source "$BR2_EXTERNAL_BAR_42_PATH/package/my-jpeg/Config.in" | | | |config BAR_42_FLASH_ADDR | | hex "my-board flash address" | | default 0x10AD | `---- | |- external.mk | |include $(sort $(wildcard $(BR2_EXTERNAL_BAR_42_PATH)/package/*/*.mk)) | |include $(sort $(wildcard $(BR2_EXTERNAL_BAR_42_PATH)/toolchain/*/*.mk)) | | | |flash-my-board: | | $(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/flash-image \ | | --image $(BINARIES_DIR)/image.bin \ | | --address $(BAR_42_FLASH_ADDR) | `---- | |- package/pkg-1/Config.in | |config BR2_PACKAGE_PKG_1 | | bool "pkg-1" | | help | | Some help about pkg-1 | `---- |- package/pkg-1/pkg-1.hash |- package/pkg-1/pkg-1.mk | |PKG_1_VERSION = 1.2.3 | |PKG_1_SITE = /some/where/to/get/pkg-1 | |PKG_1_LICENSE = blabla | | | |define PKG_1_INSTALL_INIT_SYSV | | $(INSTALL) -D -m 0755 $(PKG_1_PKGDIR)/S99my-daemon \ | | $(TARGET_DIR)/etc/init.d/S99my-daemon | |endef | | | |$(eval $(autotools-package)) | `---- |- package/pkg-1/S99my-daemon | |- package/pkg-2/Config.in |- package/pkg-2/pkg-2.hash |- package/pkg-2/pkg-2.mk | |- provides/jpeg.in | |config BR2_PACKAGE_MY_JPEG | | bool "my-jpeg" | `---- |- package/my-jpeg/Config.in | |config BR2_PACKAGE_PROVIDES_JPEG | | default "my-jpeg" if BR2_PACKAGE_MY_JPEG | `---- |- package/my-jpeg/my-jpeg.mk | |# This is a normal package .mk file | |MY_JPEG_VERSION = 1.2.3 | |MY_JPEG_SITE = https://example.net/some/place | |MY_JPEG_PROVIDES = jpeg | |$(eval $(autotools-package)) | `---- | |- provides/init.in | |config BR2_INIT_MINE | | bool "my custom init" | | select BR2_PACKAGE_MY_INIT | | select BR2_PACKAGE_SKELETON_INIT_MINE if BR2_ROOTFS_SKELETON_DEFAULT | `---- | |- provides/skeleton.in | |config BR2_ROOTFS_SKELETON_MINE | | bool "my custom skeleton" | | select BR2_PACKAGE_SKELETON_MINE | `---- |- package/skeleton-mine/Config.in | |config BR2_PACKAGE_SKELETON_MINE | | bool | | select BR2_PACKAGE_HAS_SKELETON | | | |config BR2_PACKAGE_PROVIDES_SKELETON | | default "skeleton-mine" if BR2_PACKAGE_SKELETON_MINE | `---- |- package/skeleton-mine/skeleton-mine.mk | |SKELETON_MINE_ADD_TOOLCHAIN_DEPENDENCY = NO | |SKELETON_MINE_ADD_SKELETON_DEPENDENCY = NO | |SKELETON_MINE_PROVIDES = skeleton | |SKELETON_MINE_INSTALL_STAGING = YES | |$(eval $(generic-package)) | `---- | |- provides/toolchains.in | |config BR2_TOOLCHAIN_EXTERNAL_MINE | | bool "my custom toolchain" | | depends on BR2_some_arch | | select BR2_INSTALL_LIBSTDCPP | `---- |- toolchain/toolchain-external-mine/Config.in.options | |if BR2_TOOLCHAIN_EXTERNAL_MINE | |config BR2_TOOLCHAIN_EXTERNAL_PREFIX | | default "arch-mine-linux-gnu" | |config BR2_PACKAGE_PROVIDES_TOOLCHAIN_EXTERNAL | | default "toolchain-external-mine" | |endif | `---- |- toolchain/toolchain-external-mine/toolchain-external-mine.mk | |TOOLCHAIN_EXTERNAL_MINE_SITE = https://example.net/some/place | |TOOLCHAIN_EXTERNAL_MINE_SOURCE = my-toolchain.tar.gz | |$(eval $(toolchain-external-package)) | `---- | |- linux/Config.ext.in | |config BR2_LINUX_KERNEL_EXT_EXAMPLE_DRIVER | | bool "example-external-driver" | | help | | Example external driver | |--- |- linux/linux-ext-example-driver.mk | |- configs/my-board_defconfig | |BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_BAR_42_PATH)/patches/" | |BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/overlay/" | |BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/post-image.sh" | |BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/kernel.config" | `---- | |- patches/linux/0001-some-change.patch |- patches/linux/0002-some-other-change.patch |- patches/busybox/0001-fix-something.patch | |- board/my-board/kernel.config |- board/my-board/overlay/var/www/index.html |- board/my-board/overlay/var/www/my.css |- board/my-board/flash-image `- board/my-board/post-image.sh |#!/bin/sh |generate-my-binary-image \ | --root ${BINARIES_DIR}/rootfs.tar \ | --kernel ${BINARIES_DIR}/zImage \ | --dtb ${BINARIES_DIR}/my-board.dtb \ | --output ${BINARIES_DIR}/image.bin `----
The br2-external tree will then be visible in the menuconfig (with the layout expanded):
External options ---> *** Example br2-external tree (in /path/to/br2-ext-tree/) [ ] pkg-1 [ ] pkg-2 (0x10AD) my-board flash address
If you are using more than one br2-external tree, it would look like
(with the layout expanded and the second one with name FOO_27
but no
desc:
field in external.desc
):
External options ---> Example br2-external tree ---> *** Example br2-external tree (in /path/to/br2-ext-tree) [ ] pkg-1 [ ] pkg-2 (0x10AD) my-board flash address FOO_27 ---> *** FOO_27 (in /path/to/another-br2-ext) [ ] foo [ ] bar
Additionally, the jpeg provider will be visible in the jpeg choice:
Target packages ---> Libraries ---> Graphics ---> [*] jpeg support jpeg variant () ---> ( ) jpeg ( ) jpeg-turbo *** jpeg from: Example br2-external tree *** (X) my-jpeg *** jpeg from: FOO_27 *** ( ) another-jpeg
And similarly for the toolchains:
Toolchain ---> Toolchain () ---> ( ) Custom toolchain *** Toolchains from: Example br2-external tree *** (X) my custom toolchain
Note. The toolchain options in toolchain/toolchain-external-mine/Config.in.options
will not appear in the Toolchain
menu. They must be explicitly included
from within the br2-external’s top-level Config.in
and will thus appear
in the External options
menu.
The Buildroot configuration can be stored using the command
make savedefconfig
.
This strips the Buildroot configuration down by removing configuration
options that are at their default value. The result is stored in a file
called defconfig
. If you want to save it in another place, change the
BR2_DEFCONFIG
option in the Buildroot configuration itself, or call
make with make savedefconfig BR2_DEFCONFIG=<path-to-defconfig>
.
The recommended place to store this defconfig is
configs/<boardname>_defconfig
. If you follow this recommendation, the
configuration will be listed in make list-defconfigs
and can be set
again by running make <boardname>_defconfig
.
Alternatively, you can copy the file to any other place and rebuild with
make defconfig BR2_DEFCONFIG=<path-to-defconfig-file>
.
The configuration files for BusyBox, the Linux kernel, Barebox, U-Boot
and uClibc should be stored as well if changed. For each of these
components, a Buildroot configuration option exists to point to an input
configuration file, e.g. BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
. To store
their configuration, set these configuration options to a path where you
want to save the configuration files, and then use the helper targets
described below to actually store the configuration.
As explained in Section 9.1, “Recommended directory structure”, the recommended path to
store these configuration files is
board/<company>/<boardname>/foo.config
.
Make sure that you create a configuration file before changing
the BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
etc. options. Otherwise,
Buildroot will try to access this config file, which doesn’t exist
yet, and will fail. You can create the configuration file by running
make linux-menuconfig
etc.
Buildroot provides a few helper targets to make the saving of configuration files easier.
make linux-update-defconfig
saves the linux configuration to the
path specified by BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
. It
simplifies the config file by removing default values. However,
this only works with kernels starting from 2.6.33. For earlier
kernels, use make linux-update-config
.
make busybox-update-config
saves the busybox configuration to the
path specified by BR2_PACKAGE_BUSYBOX_CONFIG
.
make uclibc-update-config
saves the uClibc configuration to the
path specified by BR2_UCLIBC_CONFIG
.
make barebox-update-defconfig
saves the barebox configuration to the
path specified by BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE
.
make uboot-update-defconfig
saves the U-Boot configuration to the
path specified by BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
.
BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILE
.
Besides changing the configuration through make *config
,
there are a few other ways to customize the resulting target filesystem.
The two recommended methods, which can co-exist, are root filesystem overlay(s) and post build script(s).
BR2_ROOTFS_OVERLAY
)
A filesystem overlay is a tree of files that is copied directly
over the target filesystem after it has been built. To enable this
feature, set config option BR2_ROOTFS_OVERLAY
(in the System
configuration
menu) to the root of the overlay. You can even specify
multiple overlays, space-separated. If you specify a relative path,
it will be relative to the root of the Buildroot tree. Hidden
directories of version control systems, like .git
, .svn
, .hg
,
etc., files called .empty
and files ending in ~
are excluded from
the copy.
When BR2_ROOTFS_MERGED_USR
is enabled, then the overlay must not
contain the /bin, /lib or /sbin directories, as Buildroot will
create them as symbolic links to the relevant folders in /usr. In
such a situation, should the overlay have any programs or libraries,
they should be placed in /usr/bin, /usr/sbin and /usr/lib.
As shown in Section 9.1, “Recommended directory structure”, the recommended path for
this overlay is board/<company>/<boardname>/rootfs-overlay
.
BR2_ROOTFS_POST_BUILD_SCRIPT
)
Post-build scripts are shell scripts called after Buildroot builds
all the selected software, but before the rootfs images are
assembled. To enable this feature, specify a space-separated list of
post-build scripts in config option BR2_ROOTFS_POST_BUILD_SCRIPT
(in
the System configuration
menu). If you specify a relative path, it
will be relative to the root of the Buildroot tree.
Using post-build scripts, you can remove or modify any file in your target filesystem. You should, however, use this feature with care. Whenever you find that a certain package generates wrong or unneeded files, you should fix that package rather than work around it with some post-build cleanup scripts.
As shown in Section 9.1, “Recommended directory structure”, the recommended path for
this script is board/<company>/<boardname>/post_build.sh
.
The post-build scripts are run with the main Buildroot tree as current
working directory. The path to the target filesystem is passed as the
first argument to each script. If the config option
BR2_ROOTFS_POST_SCRIPT_ARGS
is not empty, these arguments will be
passed to the script too. All the scripts will be passed the exact
same set of arguments, it is not possible to pass different sets of
arguments to each script.
Note that the arguments from +BR2_ROOTFS_POST_SCRIPT_ARGS+ will also be passed to post-image and post-fakeroot scripts. If you want to use arguments that are only used for the post-build scripts you can use +BR2_ROOTFS_POST_BUILD_SCRIPT_ARGS+.
+ In addition, you may also use these environment variables:
BR2_CONFIG
: the path to the Buildroot .config file
CONFIG_DIR
: the directory containing the .config file, and
therefore the top-level Buildroot Makefile to use (which is
correct for both in-tree and out-of-tree builds)
HOST_DIR
, STAGING_DIR
, TARGET_DIR
: see
Section 18.6.2, “generic-package
reference”
BUILD_DIR
: the directory where packages are extracted and built
BINARIES_DIR
: the place where all binary files (aka images) are
stored
BASE_DIR
: the base output directory
PARALLEL_JOBS
: the number of jobs to use when running parallel processes.
Below three more methods of customizing the target filesystem are described, but they are not recommended.
For temporary modifications, you can modify the target filesystem
directly and rebuild the image. The target filesystem is available
under output/target/
. After making your changes, run make
to
rebuild the target filesystem image.
This method allows you to do anything to the target filesystem, but if
you need to clean your Buildroot tree using make clean
, these
changes will be lost. Such cleaning is necessary in several cases,
refer to Section 8.2, “Understanding when a full rebuild is necessary” for details. This solution is therefore
only useful for quick tests: changes do not survive the make clean
command. Once you have validated your changes, you should make sure
that they will persist after a make clean
, using a root filesystem
overlay or a post-build script.
BR2_ROOTFS_SKELETON_CUSTOM
)
The root filesystem image is created from a target skeleton, on top of
which all packages install their files. The skeleton is copied to the
target directory output/target
before any package is built and
installed. The default target skeleton provides the standard Unix
filesystem layout and some basic init scripts and configuration files.
If the default skeleton (available under system/skeleton
) does not
match your needs, you would typically use a root filesystem overlay or
post-build script to adapt it. However, if the default skeleton is
entirely different than what you need, using a custom skeleton may be
more suitable.
To enable this feature, enable config option
BR2_ROOTFS_SKELETON_CUSTOM
and set BR2_ROOTFS_SKELETON_CUSTOM_PATH
to the path of your custom skeleton. Both options are available in the
System configuration
menu. If you specify a relative path, it will
be relative to the root of the Buildroot tree.
Custom skeletons don’t need to contain the /bin, /lib or /sbin
directories, since they are created automatically during the build.
When BR2_ROOTFS_MERGED_USR
is enabled, then the custom skeleton must
not contain the /bin, /lib or /sbin directories, as Buildroot
will create them as symbolic links to the relevant folders in /usr.
In such a situation, should the skeleton have any programs or
libraries, they should be placed in /usr/bin, /usr/sbin and
/usr/lib.
This method is not recommended because it duplicates the entire skeleton, which prevents taking advantage of the fixes or improvements brought to the default skeleton in later Buildroot releases.
BR2_ROOTFS_POST_FAKEROOT_SCRIPT
)
When aggregating the final images, some parts of the process requires
root rights: creating device nodes in /dev
, setting permissions or
ownership to files and directories… To avoid requiring actual root
rights, Buildroot uses fakeroot
to simulate root rights. This is not
a complete substitute for actually being root, but is enough for what
Buildroot needs.
Post-fakeroot scripts are shell scripts that are called at the end of the fakeroot phase, right before the filesystem image generator is called. As such, they are called in the fakeroot context.
Post-fakeroot scripts can be useful in case you need to tweak the filesystem to do modifications that are usually only available to the root user.
Note: It is recommended to use the existing mechanisms to set file permissions
or create entries in /dev
(see Section 9.5.1, “Setting file permissions and ownership and adding custom devices nodes”) or
to create users (see Section 9.6, “Adding custom user accounts”)
Note: The difference between post-build scripts (above) and fakeroot scripts, is that post-build scripts are not called in the fakeroot context.
Note: Using fakeroot
is not an absolute substitute for actually being root.
fakeroot
only ever fakes the file access rights and types (regular,
block-or-char device…) and uid/gid; these are emulated in-memory.
Sometimes it is needed to set specific permissions or ownership on files or device nodes. For example, certain files may need to be owned by root. Since the post-build scripts are not run as root, you cannot do such changes from there unless you use an explicit fakeroot from the post-build script.
Instead, Buildroot provides support for so-called permission tables.
To use this feature, set config option BR2_ROOTFS_DEVICE_TABLE
to a
space-separated list of permission tables, regular text files following
the makedev syntax.
If you are using a static device table (i.e. not using devtmpfs
,
mdev
, or (e)udev
) then you can add device nodes using the same
syntax, in so-called device tables. To use this feature, set config
option BR2_ROOTFS_STATIC_DEVICE_TABLE
to a space-separated list of
device tables.
As shown in Section 9.1, “Recommended directory structure”, the recommended location for
such files is board/<company>/<boardname>/
.
It should be noted that if the specific permissions or device nodes are
related to a specific application, you should set variables
FOO_PERMISSIONS
and FOO_DEVICES
in the package’s .mk
file instead
(see Section 18.6.2, “generic-package
reference”).
Sometimes it is needed to add specific users in the target system.
To cover this requirement, Buildroot provides support for so-called
users tables. To use this feature, set config option
BR2_ROOTFS_USERS_TABLES
to a space-separated list of users tables,
regular text files following the makeusers syntax.
As shown in Section 9.1, “Recommended directory structure”, the recommended location for
such files is board/<company>/<boardname>/
.
It should be noted that if the custom users are related to a specific
application, you should set variable FOO_USERS
in the package’s .mk
file instead (see Section 18.6.2, “generic-package
reference”).
While post-build scripts (Section 9.5, “Customizing the generated target filesystem”) are run before building the filesystem image, kernel and bootloader, post-image scripts can be used to perform some specific actions after all images have been created.
Post-image scripts can for example be used to automatically extract your root filesystem tarball in a location exported by your NFS server, or to create a special firmware image that bundles your root filesystem and kernel image, or any other custom action required for your project.
To enable this feature, specify a space-separated list of post-image
scripts in config option BR2_ROOTFS_POST_IMAGE_SCRIPT
(in the System
configuration
menu). If you specify a relative path, it will be
relative to the root of the Buildroot tree.
Just like post-build scripts, post-image scripts are run with the main
Buildroot tree as current working directory. The path to the images
output directory is passed as the first argument to each script. If the
config option BR2_ROOTFS_POST_SCRIPT_ARGS
is not empty, these
arguments will be passed to the script too. All the scripts will be
passed the exact same set of arguments, it is not possible to pass
different sets of arguments to each script.
Note that the arguments from BR2_ROOTFS_POST_SCRIPT_ARGS
will also be
passed to post-build and post-fakeroot scripts. If you want to use
arguments that are only used for the post-image scripts you can use
BR2_ROOTFS_POST_IMAGE_SCRIPT_ARGS
.
Again just like for the post-build scripts, the scripts have access to
the environment variables BR2_CONFIG
, HOST_DIR
, STAGING_DIR
,
TARGET_DIR
, BUILD_DIR
, BINARIES_DIR
, CONFIG_DIR
, BASE_DIR
,
and PARALLEL_JOBS
.
The post-image scripts will be executed as the user that executes Buildroot, which should normally not be the root user. Therefore, any action requiring root permissions in one of these scripts will require special handling (usage of fakeroot or sudo), which is left to the script developer.
It is sometimes useful to apply extra patches to packages - on top of those provided in Buildroot. This might be used to support custom features in a project, for example, or when working on a new architecture.
The BR2_GLOBAL_PATCH_DIR
configuration option can be used to specify
a space separated list of one or more directories containing package
patches.
For a specific version <packageversion>
of a specific package
<packagename>
, patches are applied from BR2_GLOBAL_PATCH_DIR
as
follows:
For every directory - <global-patch-dir>
- that exists in
BR2_GLOBAL_PATCH_DIR
, a <package-patch-dir>
will be determined as
follows:
<global-patch-dir>/<packagename>/<packageversion>/
if the
directory exists.
<global-patch-dir>/<packagename>
if the directory
exists.
Patches will then be applied from a <package-patch-dir>
as
follows:
series
file exists in the package directory, then patches are
applied according to the series
file;
*.patch
are applied in
alphabetical order. So, to ensure they are applied in the right
order, it is highly recommended to name the patch files like this:
<number>-<description>.patch
, where <number>
refers to the
apply order.
For information about how patches are applied for a package, see Section 19.2, “How patches are applied”
The BR2_GLOBAL_PATCH_DIR
option is the preferred method for
specifying a custom patch directory for packages. It can be used to
specify a patch directory for any package in buildroot. It should also
be used in place of the custom patch directory options that are
available for packages such as U-Boot and Barebox. By doing this, it
will allow a user to manage their patches from one top-level
directory.
The exception to BR2_GLOBAL_PATCH_DIR
being the preferred method for
specifying custom patches is BR2_LINUX_KERNEL_PATCH
.
BR2_LINUX_KERNEL_PATCH
should be used to specify kernel patches that
are available at a URL. Note: BR2_LINUX_KERNEL_PATCH
specifies kernel
patches that are applied after patches available in BR2_GLOBAL_PATCH_DIR
,
as it is done from a post-patch hook of the Linux package.
Buildroot bundles a list of hashes against which it checks the integrity of the downloaded archives, or of those it generates locally from VCS checkouts. However, it can only do so for the known versions; for packages where it is possible to specify a custom version (e.g. a custom version string, a remote tarball URL, or a VCS repository location and changeset), Buildroot can’t carry hashes for those.
For users concerned with the integrity of such downloads, it is possible
to provide a list of hashes that Buildroot can use to check arbitrary
downloaded files. Those extra hashes are looked up similarly to the
extra patches (above); for each directory in BR2_GLOBAL_PATCH_DIR
,
the first file to exist is used to check a package download:
<global-patch-dir>/<packagename>/<packageversion>/<packagename>.hash
<global-patch-dir>/<packagename>/<packagename>.hash
The utils/add-custom-hashes
script can be used to generate these files.
In general, any new package should be added directly in the package
directory and submitted to the Buildroot upstream project. How to add
packages to Buildroot in general is explained in full detail in
Chapter 18, Adding new packages to Buildroot and will not be repeated here. However, your
project may need some proprietary packages that cannot be upstreamed.
This section will explain how you can keep such project-specific
packages in a project-specific directory.
As shown in Section 9.1, “Recommended directory structure”, the recommended location for
project-specific packages is package/<company>/
. If you are using the
br2-external tree feature (see Section 9.2, “Keeping customizations outside of Buildroot”) the recommended
location is to put them in a sub-directory named package/
in your
br2-external tree.
However, Buildroot will not be aware of the packages in this location,
unless we perform some additional steps. As explained in
Chapter 18, Adding new packages to Buildroot, a package in Buildroot basically consists of two
files: a .mk
file (describing how to build the package) and a
Config.in
file (describing the configuration options for this
package).
Buildroot will automatically include the .mk
files in first-level
subdirectories of the package
directory (using the pattern
package/*/*.mk
). If we want Buildroot to include .mk
files from
deeper subdirectories (like package/<company>/package1/
) then we
simply have to add a .mk
file in a first-level subdirectory that
includes these additional .mk
files. Therefore, create a file
package/<company>/<company>.mk
with following contents (assuming you
have only one extra directory level below package/<company>/
):
include $(sort $(wildcard package/<company>/*/*.mk))
For the Config.in
files, create a file package/<company>/Config.in
that includes the Config.in
files of all your packages. An exhaustive
list has to be provided since wildcards are not supported in the source command of kconfig.
For example:
source "package/<company>/package1/Config.in" source "package/<company>/package2/Config.in"
Include this new file package/<company>/Config.in
from
package/Config.in
, preferably in a company-specific menu to make
merges with future Buildroot versions easier.
If using a br2-external tree, refer to Section 9.2, “Keeping customizations outside of Buildroot” for how to fill in those files.
Earlier in this chapter, the different methods for making project-specific customizations have been described. This section will now summarize all this by providing step-by-step instructions to storing your project-specific customizations. Clearly, the steps that are not relevant to your project can be skipped.
make menuconfig
to configure toolchain, packages and kernel.
make linux-menuconfig
to update the kernel config, similar for
other configuration like busybox, uclibc, …
mkdir -p board/<manufacturer>/<boardname>
Set the following options to board/<manufacturer>/<boardname>/<package>.config
(as far as they are relevant):
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
BR2_PACKAGE_BUSYBOX_CONFIG
BR2_UCLIBC_CONFIG
BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILE
BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE
BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
Write the configuration files:
make linux-update-defconfig
make busybox-update-config
make uclibc-update-config
cp <output>/build/at91bootstrap3-*/.config
board/<manufacturer>/<boardname>/at91bootstrap3.config
make barebox-update-defconfig
make uboot-update-defconfig
board/<manufacturer>/<boardname>/rootfs-overlay/
and fill it
with additional files you need on your rootfs, e.g.
board/<manufacturer>/<boardname>/rootfs-overlay/etc/inittab
.
Set BR2_ROOTFS_OVERLAY
to board/<manufacturer>/<boardname>/rootfs-overlay
.
board/<manufacturer>/<boardname>/post_build.sh
. Set
BR2_ROOTFS_POST_BUILD_SCRIPT
to
board/<manufacturer>/<boardname>/post_build.sh
board/<manufacturer>/<boardname>/device_table.txt
and add that path to BR2_ROOTFS_DEVICE_TABLE
.
board/<manufacturer>/<boardname>/users_table.txt
and add that path
to BR2_ROOTFS_USERS_TABLES
.
BR2_GLOBAL_PATCH_DIR
to board/<manufacturer>/<boardname>/patches/
and add your patches
for each package in a subdirectory named after the package. Each
patch should be called <packagename>-<num>-<description>.patch
.
BR2_LINUX_KERNEL_PATCH
with as main advantage that it can also
download patches from a URL. If you do not need this,
BR2_GLOBAL_PATCH_DIR
is preferred. U-Boot, Barebox, at91bootstrap
and at91bootstrap3 also have separate options, but these do not
provide any advantage over BR2_GLOBAL_PATCH_DIR
and will likely be
removed in the future.
package/<manufacturer>/
and place your packages in that
directory. Create an overall <manufacturer>.mk
file that
includes the .mk
files of all your packages. Create an overall
Config.in
file that sources the Config.in
files of all your
packages. Include this Config.in
file from Buildroot’s
package/Config.in
file.
make savedefconfig
to save the buildroot configuration.
cp defconfig configs/<boardname>_defconfig