Project-specific customization

Typical actions you may need to perform for a given project are:

  • configuring Buildroot (including build options and toolchain, bootloader, kernel, package and filesystem image type selection)

  • configuring other components, like the Linux kernel and BusyBox

  • customizing the generated target filesystem

    • adding or overwriting files on the target filesystem (using BR2_ROOTFS_OVERLAY)

    • modifying or deleting files on the target filesystem (using BR2_ROOTFS_POST_BUILD_SCRIPT)

    • running arbitrary commands prior to generating the filesystem image (using BR2_ROOTFS_POST_BUILD_SCRIPT)

    • setting file permissions and ownership (using BR2_ROOTFS_DEVICE_TABLE)

    • adding custom devices nodes (using BR2_ROOTFS_STATIC_DEVICE_TABLE)

  • adding custom user accounts (using BR2_ROOTFS_USERS_TABLES)

  • running arbitrary commands after generating the filesystem image (using BR2_ROOTFS_POST_IMAGE_SCRIPT)

  • adding project-specific patches to some packages (using BR2_GLOBAL_PATCH_DIR)

  • adding project-specific packages

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!

Recommended directory structure

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 file>
|           +-- patches/
|               +-- foo/
|               |   +-- <some patch>
|               +-- 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.

==== Implementing layered customizations

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.

// -*- mode:doc -*- ;
// vim: set syntax=asciidoc:

[[outside-br-custom]]
=== Keeping customizations outside of Buildroot

As already briefly mentioned in xref:customize-dir-structure[], you can
place project-specific customizations in two locations:

 * directly within the Buildroot tree, typically maintaining them using
   branches in a version control system so that upgrading to a newer
   Buildroot release is easy.

 * outside of the Buildroot tree, using the _br2-external_ mechanism.
   This mechanism allows to keep package recipes, board support and
   configuration files outside of the Buildroot tree, while still
   having them nicely integrated in the build logic. We call this
   location a _br2-external tree_. This section explains how to use
   the br2-external mechanism and what to provide in a br2-external
   tree.

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
xref:br2-external-converting[] 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

==== Layout of a br2-external tree

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.

===== The `external.desc` file

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.

===== The `Config.in` and `external.mk` files

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 xref:adding-packages[].
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`.

===== The `configs/` directory

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.

===== The `provides/` directory

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

===== Free-form content

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

Additional Linux kernel extensions (see xref:linux-kernel-ext[]) can
be added by storing them in the `linux/` directory at the root of a
br2-external tree.

===== Example layout

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.

// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

[[customize-store-buildroot-config]]
=== Storing the Buildroot configuration

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

[[customize-store-package-config]]
=== Storing the configuration of other components

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 xref:customize-dir-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`.
* For at91bootstrap3, no helper exists so you have to copy the config
  file manually to `BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILE`.



// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

[[rootfs-custom]]
=== Customizing the generated target filesystem

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

Root filesystem overlays (`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 xref:customize-dir-structure[], the recommended path for
  this overlay is `board/<company>/<boardname>/rootfs-overlay`.

Post-build scripts (`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 xref:customize-dir-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.
+
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
    xref: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

Below three more methods of customizing the target filesystem are
described, but they are not recommended.

Direct modification of the target filesystem::
+
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 xref:full-rebuild[] 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.

Custom target skeleton (`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.

Post-fakeroot scripts (`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 xref:customize-device-permission[]) or
  to create users (see xref:customize-users[])
+
.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.

// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

[[customize-device-permission]]
==== Setting file permissions and ownership and adding custom devices nodes

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 xref:makedev-syntax[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 xref:customize-dir-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 xref:generic-package-reference[]).

// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

[[customize-users]]
=== Adding custom user accounts

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 xref:makeuser-syntax[makeusers syntax].

As shown in xref:customize-dir-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 xref:generic-package-reference[]).

// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

=== Customization _after_ the images have been created

While post-build scripts (xref:rootfs-custom[]) 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.

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` and
`BASE_DIR`.

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.

// -*- mode:doc -*- ;
// vim: set syntax=asciidoc:

[[customize-patches]]
=== Adding project-specific patches

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.
+
* Otherwise, `<global-patch-dir>/<packagename>` if the directory
  exists.

. Patches will then be applied from a `<package-patch-dir>` as
  follows:
+
* If a `series` file exists in the package directory, then patches are
  applied according to the `series` file;
+
* Otherwise, patch files matching `*.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
xref:patch-apply-order[]

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.


// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

[[customize-packages]]
=== Adding project-specific packages

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
xref:adding-packages[] 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 xref:customize-dir-structure[], the recommended location for
project-specific packages is `package/<company>/`. If you are using the
br2-external tree feature (see xref:outside-br-custom[]) 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
xref:adding-packages[], 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 xref:outside-br-custom[] for how
to fill in those files.

// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

=== Quick guide to storing your project-specific customizations

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.

1. `make menuconfig` to configure toolchain, packages and kernel.
1. `make linux-menuconfig` to update the kernel config, similar for
   other configuration like busybox, uclibc, ...
1. `mkdir -p board/<manufacturer>/<boardname>`
1. 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`
1. 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`
1. Create `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`.
1. Create a post-build script
   `board/<manufacturer>/<boardname>/post_build.sh`. Set
   `BR2_ROOTFS_POST_BUILD_SCRIPT` to
   `board/<manufacturer>/<boardname>/post_build.sh`
1. If additional setuid permissions have to be set or device nodes have
   to be created, create `board/<manufacturer>/<boardname>/device_table.adoc`
   and add that path to `BR2_ROOTFS_DEVICE_TABLE`.
1. If additional user accounts have to be created, create
   `board/<manufacturer>/<boardname>/users_table.adoc` and add that path
   to `BR2_ROOTFS_USERS_TABLES`.
1. To add custom patches to certain packages, set `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`.
1. Specifically for the Linux kernel, there also exists the option
   `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.
1. If you need to add project-specific packages, create
   `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.
1. `make savedefconfig` to save the buildroot configuration.
1. `cp defconfig configs/<boardname>_defconfig`