Adding new packages to Buildroot
This section covers how new packages (userspace libraries or applications) can be integrated into Buildroot. It also shows how existing packages are integrated, which is needed for fixing issues or tuning their configuration.
When you add a new package, be sure to test it in various conditions (see [testing-package]) and also check it for coding style (see [check-package]).
Package directory
First of all, create a directory under the package
directory for
your software, for example libfoo
.
Some packages have been grouped by topic in a sub-directory:
x11r7
, qt5
and gstreamer
. If your package fits in
one of these categories, then create your package directory in these.
New subdirectories are discouraged, however.
Config files
For the package to be displayed in the configuration tool, you need to
create a Config file in your package directory. There are two types:
Config.in
and Config.in.host
.
Config.in
file
For packages used on the target, create a file named Config.in
. This
file will contain the option descriptions related to our libfoo
software
that will be used and displayed in the configuration tool. It should basically
contain:
config BR2_PACKAGE_LIBFOO bool "libfoo" help This is a comment that explains what libfoo is. The help text should be wrapped. http://foosoftware.org/libfoo/
The bool
line, help
line and other metadata information about the
configuration option must be indented with one tab. The help text
itself should be indented with one tab and two spaces, lines should
be wrapped to fit 72 columns, where tab counts for 8, so 62 characters
in the text itself. The help text must mention the upstream URL of the
project after an empty line.
As a convention specific to Buildroot, the ordering of the attributes is as follows:
-
The type of option:
bool
,string
… with the prompt -
If needed, the
default
value(s) -
Any dependencies on the target in
depends on
form -
Any dependencies on the toolchain in
depends on
form -
Any dependencies on other packages in
depends on
form -
Any dependency of the
select
form -
The help keyword and help text.
You can add other sub-options into a if BR2_PACKAGE_LIBFOO…endif
statement to configure particular things in your software. You can look at
examples in other packages. The syntax of the Config.in
file is the same
as the one for the kernel Kconfig file. The documentation for this syntax is
available at http://kernel.org/doc/Documentation/kbuild/kconfig-language.adoc
Finally you have to add your new libfoo/Config.in
to
package/Config.in
(or in a category subdirectory if you decided to
put your package in one of the existing categories). The files
included there are 'sorted alphabetically' per category and are 'NOT'
supposed to contain anything but the 'bare' name of the package.
source "package/libfoo/Config.in"
Config.in.host
file
Some packages also need to be built for the host system. There are two options here:
-
The host package is only required to satisfy build-time dependencies of one or more target packages. In this case, add
host-foo
to the target package’sBAR_DEPENDENCIES
variable. NoConfig.in.host
file should be created. -
The host package should be explicitly selectable by the user from the configuration menu. In this case, create a
Config.in.host
file for that host package:config BR2_PACKAGE_HOST_FOO bool "host foo" help This is a comment that explains what foo for the host is. http://foosoftware.org/foo/
The same coding style and options as for the
Config.in
file are valid.Finally you have to add your new
libfoo/Config.in.host
topackage/Config.in.host
. The files included there are 'sorted alphabetically' and are 'NOT' supposed to contain anything but the 'bare' name of the package.source "package/foo/Config.in.host"
The host package will then be available from the
Host utilities
menu.
Choosing depends on
or select
The Config.in
file of your package must also ensure that
dependencies are enabled. Typically, Buildroot uses the following
rules:
-
Use a
select
type of dependency for dependencies on libraries. These dependencies are generally not obvious and it therefore make sense to have the kconfig system ensure that the dependencies are selected. For example, the libgtk2 package usesselect BR2_PACKAGE_LIBGLIB2
to make sure this library is also enabled. Theselect
keyword expresses the dependency with a backward semantic. -
Use a
depends on
type of dependency when the user really needs to be aware of the dependency. Typically, Buildroot uses this type of dependency for dependencies on target architecture, MMU support and toolchain options (see Dependencies on target and toolchain options), or for dependencies on "big" things, such as the X.org system. Thedepends on
keyword expresses the dependency with a forward semantic.
The current problem with the kconfig language is that these two dependency semantics are not internally linked. Therefore, it may be possible to select a package, whom one of its dependencies/requirement is not met.
An example illustrates both the usage of select
and depends on
.
config BR2_PACKAGE_RRDTOOL bool "rrdtool" depends on BR2_USE_WCHAR select BR2_PACKAGE_FREETYPE select BR2_PACKAGE_LIBART select BR2_PACKAGE_LIBPNG select BR2_PACKAGE_ZLIB help RRDtool is the OpenSource industry standard, high performance data logging and graphing system for time series data. http://oss.oetiker.ch/rrdtool/ comment "rrdtool needs a toolchain w/ wchar" depends on !BR2_USE_WCHAR
Note that these two dependency types are only transitive with the dependencies of the same kind.
This means, in the following example:
config BR2_PACKAGE_A bool "Package A" config BR2_PACKAGE_B bool "Package B" depends on BR2_PACKAGE_A config BR2_PACKAGE_C bool "Package C" depends on BR2_PACKAGE_B config BR2_PACKAGE_D bool "Package D" select BR2_PACKAGE_B config BR2_PACKAGE_E bool "Package E" select BR2_PACKAGE_D
-
Selecting
Package C
will be visible ifPackage B
has been selected, which in turn is only visible ifPackage A
has been selected. -
Selecting
Package E
will selectPackage D
, which will selectPackage B
, it will not check for the dependencies ofPackage B
, so it will not selectPackage A
. -
Since
Package B
is selected butPackage A
is not, this violates the dependency ofPackage B
onPackage A
. Therefore, in such a situation, the transitive dependency has to be added explicitly:
config BR2_PACKAGE_D bool "Package D" depends on BR2_PACKAGE_A select BR2_PACKAGE_B config BR2_PACKAGE_E bool "Package E" depends on BR2_PACKAGE_A select BR2_PACKAGE_D
Overall, for package library dependencies, select
should be
preferred.
Note that such dependencies will ensure that the dependency option
is also enabled, but not necessarily built before your package. To do
so, the dependency also needs to be expressed in the .mk
file of the
package.
Further formatting details: see the coding style.
Dependencies on target and toolchain options
Many packages depend on certain options of the toolchain: the choice of C library, C`` support, thread support, RPC support, wchar support, or dynamic library support. Some packages can only be built on certain target architectures, or if an MMU is available in the processor.
These dependencies have to be expressed with the appropriate 'depends
on' statements in the Config.in file. Additionally, for dependencies on
toolchain options, a comment
should be displayed when the option is
not enabled, so that the user knows why the package is not available.
Dependencies on target architecture or MMU support should not be
made visible in a comment: since it is unlikely that the user can
freely choose another target, it makes little sense to show these
dependencies explicitly.
The comment
should only be visible if the config
option itself would
be visible when the toolchain option dependencies are met. This means
that all other dependencies of the package (including dependencies on
target architecture and MMU support) have to be repeated on the
comment
definition. To keep it clear, the depends on
statement for
these non-toolchain option should be kept separate from the depends on
statement for the toolchain options.
If there is a dependency on a config option in that same file (typically
the main package) it is preferable to have a global if … endif
construct rather than repeating the depends on
statement on the
comment and other config options.
The general format of a dependency comment
for package foo is:
foo needs a toolchain w/ featA, featB, featC
for example:
mpd needs a toolchain w/ C``, threads, wchar
or
crda needs a toolchain w/ threads
Note that this text is kept brief on purpose, so that it will fit on a 80-character terminal.
The rest of this section enumerates the different target and toolchain options, the corresponding config symbols to depend on, and the text to use in the comment.
-
Target architecture
-
Dependency symbol:
BR2_powerpc
,BR2_mips
, … (seearch/Config.in
) -
Comment string: no comment to be added
-
-
MMU support
-
Dependency symbol:
BR2_USE_MMU
-
Comment string: no comment to be added
-
-
Gcc
_sync*
built-ins used for atomic operations. They are available in variants operating on 1 byte, 2 bytes, 4 bytes and 8 bytes. Since different architectures support atomic operations on different sizes, one dependency symbol is available for each size:-
Dependency symbol:
BR2_TOOLCHAIN_HAS_SYNC_1
for 1 byte,BR2_TOOLCHAIN_HAS_SYNC_2
for 2 bytes,BR2_TOOLCHAIN_HAS_SYNC_4
for 4 bytes,BR2_TOOLCHAIN_HAS_SYNC_8
for 8 bytes. -
Comment string: no comment to be added
-
-
Gcc
_atomic*
built-ins used for atomic operations.-
Dependency symbol:
BR2_TOOLCHAIN_HAS_ATOMIC
. -
Comment string: no comment to be added
-
-
Kernel headers
-
Dependency symbol:
BR2_TOOLCHAIN_HEADERS_AT_LEAST_X_Y
, (replaceX_Y
with the proper version, seetoolchain/Config.in
) -
Comment string:
headers >= X.Y
and/orheaders ⇐ X.Y
(replaceX.Y
with the proper version)
-
-
GCC version
-
Dependency symbol:
BR2_TOOLCHAIN_GCC_AT_LEAST_X_Y
, (replaceX_Y
with the proper version, seetoolchain/Config.in
) -
Comment string:
gcc >= X.Y
and/orgcc ⇐ X.Y
(replaceX.Y
with the proper version)
-
-
Host GCC version
-
Dependency symbol:
BR2_HOST_GCC_AT_LEAST_X_Y
, (replaceX_Y
with the proper version, seeConfig.in
) -
Comment string: no comment to be added
-
Note that it is usually not the package itself that has a minimum host GCC version, but rather a host-package on which it depends.
-
-
C library
-
Dependency symbol:
BR2_TOOLCHAIN_USES_GLIBC
,BR2_TOOLCHAIN_USES_MUSL
,BR2_TOOLCHAIN_USES_UCLIBC
-
Comment string: for the C library, a slightly different comment text is used:
foo needs a glibc toolchain
, orfoo needs a glibc toolchain w/ C``
-
-
C`` support
-
Dependency symbol:
BR2_INSTALL_LIBSTDCPP
-
Comment string:
C``
-
-
D support
-
Dependency symbol:
BR2_TOOLCHAIN_HAS_DLANG
-
Comment string:
Dlang
-
-
Fortran support
-
Dependency symbol:
BR2_TOOLCHAIN_HAS_FORTRAN
-
Comment string:
fortran
-
-
thread support
-
Dependency symbol:
BR2_TOOLCHAIN_HAS_THREADS
-
Comment string:
threads
(unlessBR2_TOOLCHAIN_HAS_THREADS_NPTL
is also needed, in which case, specifying onlyNPTL
is sufficient)
-
-
NPTL thread support
-
Dependency symbol:
BR2_TOOLCHAIN_HAS_THREADS_NPTL
-
Comment string:
NPTL
-
-
RPC support
-
Dependency symbol:
BR2_TOOLCHAIN_HAS_NATIVE_RPC
-
Comment string:
RPC
-
-
wchar support
-
Dependency symbol:
BR2_USE_WCHAR
-
Comment string:
wchar
-
-
dynamic library
-
Dependency symbol:
!BR2_STATIC_LIBS
-
Comment string:
dynamic library
-
Dependencies on a Linux kernel built by buildroot
Some packages need a Linux kernel to be built by buildroot. These are typically kernel modules or firmware. A comment should be added in the Config.in file to express this dependency, similar to dependencies on toolchain options. The general format is:
foo needs a Linux kernel to be built
If there is a dependency on both toolchain options and the Linux kernel, use this format:
foo needs a toolchain w/ featA, featB, featC and a Linux kernel to be built
Dependencies on udev /dev management
If a package needs udev /dev management, it should depend on symbol
BR2_PACKAGE_HAS_UDEV
, and the following comment should be added:
foo needs udev /dev management
If there is a dependency on both toolchain options and udev /dev management, use this format:
foo needs udev /dev management and a toolchain w/ featA, featB, featC
Dependencies on features provided by virtual packages
Some features can be provided by more than one package, such as the openGL libraries.
See [virtual-package-tutorial] for more on the virtual packages.
The .mk
file
Finally, here’s the hardest part. Create a file named libfoo.mk
. It
describes how the package should be downloaded, configured, built,
installed, etc.
Depending on the package type, the .mk
file must be written in a
different way, using different infrastructures:
-
Makefiles for generic packages (not using autotools or CMake): These are based on an infrastructure similar to the one used for autotools-based packages, but require a little more work from the developer. They specify what should be done for the configuration, compilation and installation of the package. This infrastructure must be used for all packages that do not use the autotools as their build system. In the future, other specialized infrastructures might be written for other build systems. We cover them through in a tutorial and a reference.
-
Makefiles for autotools-based software (autoconf, automake, etc.): We provide a dedicated infrastructure for such packages, since autotools is a very common build system. This infrastructure 'must' be used for new packages that rely on the autotools as their build system. We cover them through a tutorial and reference.
-
Makefiles for cmake-based software: We provide a dedicated infrastructure for such packages, as CMake is a more and more commonly used build system and has a standardized behaviour. This infrastructure 'must' be used for new packages that rely on CMake. We cover them through a tutorial and reference.
-
Makefiles for Python modules: We have a dedicated infrastructure for Python modules that use the
distutils
,flit
,pep517
orsetuptools
mechanisms. We cover them through a tutorial and a reference. -
Makefiles for Lua modules: We have a dedicated infrastructure for Lua modules available through the LuaRocks web site. We cover them through a tutorial and a reference.
Further formatting details: see the writing rules.
The .hash
file
When possible, you must add a third file, named libfoo.hash
, that
contains the hashes of the downloaded files for the libfoo
package. The only reason for not adding a .hash
file is when hash
checking is not possible due to how the package is downloaded.
When a package has a version selection choice, then the hash file may be
stored in a subdirectory named after the version, e.g.
package/libfoo/1.2.3/libfoo.hash
. This is especially important if the
different versions have different licensing terms, but they are stored
in the same file. Otherwise, the hash file should stay in the package’s
directory.
The hashes stored in that file are used to validate the integrity of the downloaded files and of the license files.
The format of this file is one line for each file for which to check the hash, each line with the following three fields separated by two spaces:
-
the type of hash, one of:
-
md5
,sha1
,sha224
,sha256
,sha384
,sha512
-
-
the hash of the file:
-
for
md5
, 32 hexadecimal characters -
for
sha1
, 40 hexadecimal characters -
for
sha224
, 56 hexadecimal characters -
for
sha256
, 64 hexadecimal characters -
for
sha384
, 96 hexadecimal characters -
for
sha512
, 128 hexadecimal characters
-
-
the name of the file:
-
for a source archive: the basename of the file, without any directory component,
-
for a license file: the path as it appears in
FOO_LICENSE_FILES
.
-
Lines starting with a #
sign are considered comments, and ignored. Empty
lines are ignored.
There can be more than one hash for a single file, each on its own line. In this case, all hashes must match.
Ideally, the hashes stored in this file should match the hashes published by
upstream, e.g. on their website, in the e-mail announcement… If upstream
provides more than one type of hash (e.g. sha1
and sha512
), then it is
best to add all those hashes in the .hash
file. If upstream does not
provide any hash, or only provides an md5
hash, then compute at least one
strong hash yourself (preferably sha256
, but not md5
), and mention
this in a comment line above the hashes.
The hashes for license files are used to detect a license change when a
package version is bumped. The hashes are checked during the make legal-info
target run. For a package with multiple versions (like Qt5),
create the hash file in a subdirectory <packageversion>
of that package
(see also [patch-apply-order]).
The example below defines a sha1
and a sha256
published by upstream for
the main libfoo-1.2.3.tar.bz2
tarball, an md5
from upstream and a
locally-computed sha256
hashes for a binary blob, a sha256
for a
downloaded patch, and an archive with no hash:
# Hashes from: http://www.foosoftware.org/download/libfoo-1.2.3.tar.bz2.{sha1,sha256}: sha1 486fb55c3efa71148fe07895fd713ea3a5ae343a libfoo-1.2.3.tar.bz2 sha256 efc8103cc3bcb06bda6a781532d12701eb081ad83e8f90004b39ab81b65d4369 libfoo-1.2.3.tar.bz2 # md5 from: http://www.foosoftware.org/download/libfoo-1.2.3.tar.bz2.md5, sha256 locally computed: md5 2d608f3c318c6b7557d551a5a09314f03452f1a1 libfoo-data.bin sha256 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b libfoo-data.bin # Locally computed: sha256 ff52101fb90bbfc3fe9475e425688c660f46216d7e751c4bbdb1dc85cdccacb9 libfoo-fix-blabla.patch # Hash for license files: sha256 a45a845012742796534f7e91fe623262ccfb99460a2bd04015bd28d66fba95b8 COPYING sha256 01b1f9f2c8ee648a7a596a1abe8aa4ed7899b1c9e5551bda06da6e422b04aa55 doc/COPYING.LGPL
If the .hash
file is present, and it contains one or more hashes for a
downloaded file, the hash(es) computed by Buildroot (after download) must
match the hash(es) stored in the .hash
file. If one or more hashes do
not match, Buildroot considers this an error, deletes the downloaded file,
and aborts.
If the .hash
file is present, but it does not contain a hash for a
downloaded file, Buildroot considers this an error and aborts. However,
the downloaded file is left in the download directory since this
typically indicates that the .hash
file is wrong but the downloaded
file is probably OK.
Hashes are currently checked for files fetched from http/ftp servers, Git repositories, files copied using scp and local files. Hashes are not checked for other version control systems (such as Subversion, CVS, etc.) because Buildroot currently does not generate reproducible tarballs when source code is fetched from such version control systems.
Hashes should only be added in .hash
files for files that are
guaranteed to be stable. For example, patches auto-generated by Github
are not guaranteed to be stable, and therefore their hashes can change
over time. Such patches should not be downloaded, and instead be added
locally to the package folder.
If the .hash
file is missing, then no check is done at all.
The SNNfoo
start script
Packages that provide a system daemon usually need to be started somehow at boot. Buildroot comes with support for several init systems, some are considered tier one (see [init-system]), while others are also available but do not have the same level of integration. Ideally, all packages providing a system daemon should provide a start script for BusyBox/SysV init and a systemd unit file.
For consistency, the start script must follow the style and composition
as shown in the reference: package/busybox/S01syslogd
. An annotated
example of this style is shown below. There is no specific coding style
for systemd unit files, but if a package comes with its own unit file,
that is preferred over a buildroot specific one, if it is compatible
with buildroot.
The name of the start script is composed of the SNN
and the daemon
name. The NN
is the start order number which needs to be carefully
chosen. For example, a program that requires networking to be up should
not start before S40network
. The scripts are started in alphabetical
order, so S01syslogd
starts before S01watchdogd
, and S02sysctl
start thereafter.
01: #!/bin/sh 02: 03: DAEMON="syslogd" 04: PIDFILE="/var/run/$DAEMON.pid" 05: 06: SYSLOGD_ARGS="" 07: 08: # shellcheck source=/dev/null 09: [ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON" 10: 11: # BusyBox' syslogd does not create a pidfile, so pass "-n" in the command line 12: # and use "-m" to instruct start-stop-daemon to create one. 13: start() { 14: printf 'Starting %s: ' "$DAEMON" 15: # shellcheck disable=SC2086 # we need the word splitting 16: start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON" \ 17: -- -n $SYSLOGD_ARGS 18: status=$? 19: if [ "$status" -eq 0 ]; then 20: echo "OK" 21: else 22: echo "FAIL" 23: fi 24: return "$status" 25: } 26: 27: stop() { 28: printf 'Stopping %s: ' "$DAEMON" 29: start-stop-daemon -K -q -p "$PIDFILE" 30: status=$? 31: if [ "$status" -eq 0 ]; then 32: rm -f "$PIDFILE" 33: echo "OK" 34: else 35: echo "FAIL" 36: fi 37: return "$status" 38: } 39: 40: restart() { 41: stop 42: sleep 1 43: start 44: } 45: 46: case "$1" in 47: start|stop|restart) 48: "$1";; 49: reload) 50: # Restart, since there is no true "reload" feature. 51: restart;; 52: *) 53: echo "Usage: $0 {start|stop|restart|reload}" 54: exit 1 55: esac
Note: programs that support reloading their configuration in some
fashion (SIGHUP
) should provide a reload()
function similar to
stop()
. The start-stop-daemon
supports -K -s HUP
for this.
It is recommended to always append -x "/sbin/$DAEMON"
to all the
start-stop-daemon
commands to ensure signals are set to a PID that
matches $DAEMON
.
Both start scripts and unit files can source command line arguments from
/etc/default/foo
, in general, if such a file does not exist it should
not block the start of the daemon, unless there is some site specirfic
command line argument the daemon requires to start. For start scripts a
FOO_ARGS="-s -o -m -e -args"
can be defined to a default value in and
the user can override this from /etc/default/foo
.
Infrastructure for packages with specific build systems
By 'packages with specific build systems' we mean all the packages whose build system is not one of the standard ones, such as 'autotools' or 'CMake'. This typically includes packages whose build system is based on hand-written Makefiles or shell scripts.
generic-package
tutorial
01: ################################################################################ 02: # 03: # libfoo 04: # 05: ################################################################################ 06: 07: LIBFOO_VERSION = 1.0 08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz 09: LIBFOO_SITE = http://www.foosoftware.org/download 10: LIBFOO_LICENSE = GPL-3.0+ 11: LIBFOO_LICENSE_FILES = COPYING 12: LIBFOO_INSTALL_STAGING = YES 13: LIBFOO_CONFIG_SCRIPTS = libfoo-config 14: LIBFOO_DEPENDENCIES = host-libaaa libbbb 15: 16: define LIBFOO_BUILD_CMDS 17: $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) all 18: endef 19: 20: define LIBFOO_INSTALL_STAGING_CMDS 21: $(INSTALL) -D -m 0755 $(@D)/libfoo.a $(STAGING_DIR)/usr/lib/libfoo.a 22: $(INSTALL) -D -m 0644 $(@D)/foo.h $(STAGING_DIR)/usr/include/foo.h 23: $(INSTALL) -D -m 0755 $(@D)/libfoo.so* $(STAGING_DIR)/usr/lib 24: endef 25: 26: define LIBFOO_INSTALL_TARGET_CMDS 27: $(INSTALL) -D -m 0755 $(@D)/libfoo.so* $(TARGET_DIR)/usr/lib 28: $(INSTALL) -d -m 0755 $(TARGET_DIR)/etc/foo.d 29: endef 30: 31: define LIBFOO_USERS 32: foo -1 libfoo -1 * - - - LibFoo daemon 33: endef 34: 35: define LIBFOO_DEVICES 36: /dev/foo c 666 0 0 42 0 - - - 37: endef 38: 39: define LIBFOO_PERMISSIONS 40: /bin/foo f 4755 foo libfoo - - - - - 41: endef 42: 43: $(eval $(generic-package))
The Makefile begins on line 7 to 11 with metadata information: the
version of the package (LIBFOO_VERSION
), the name of the
tarball containing the package (LIBFOO_SOURCE
) (xz-ed tarball recommended)
the Internet location at which the tarball can be downloaded from
(LIBFOO_SITE
), the license (LIBFOO_LICENSE
) and file with the
license text (LIBFOO_LICENSE_FILES
). All variables must start with
the same prefix, LIBFOO_
in this case. This prefix is always the
uppercased version of the package name (see below to understand where
the package name is defined).
On line 12, we specify that this package wants to install something to
the staging space. This is often needed for libraries, since they must
install header files and other development files in the staging space.
This will ensure that the commands listed in the
LIBFOO_INSTALL_STAGING_CMDS
variable will be executed.
On line 13, we specify that there is some fixing to be done to some
of the 'libfoo-config' files that were installed during
LIBFOO_INSTALL_STAGING_CMDS
phase.
These *-config files are executable shell script files that are
located in '$(STAGING_DIR)/usr/bin' directory and are executed
by other 3rd party packages to find out the location and the linking
flags of this particular package.
The problem is that all these *-config files by default give wrong, host system linking flags that are unsuitable for cross-compiling.
For example: '-I/usr/include' instead of '-I$(STAGING_DIR)/usr/include' or: '-L/usr/lib' instead of '-L$(STAGING_DIR)/usr/lib'
So some sed magic is done to these scripts to make them give correct
flags.
The argument to be given to LIBFOO_CONFIG_SCRIPTS
is the file name(s)
of the shell script(s) needing fixing. All these names are relative to
'$(STAGING_DIR)/usr/bin' and if needed multiple names can be given.
In addition, the scripts listed in LIBFOO_CONFIG_SCRIPTS
are removed
from $(TARGET_DIR)/usr/bin
, since they are not needed on the target.
Package divine installs shell script '$(STAGING_DIR)/usr/bin/divine-config'.
So its fixup would be:
DIVINE_CONFIG_SCRIPTS = divine-config
Package imagemagick installs the following scripts: '$(STAGING_DIR)/usr/bin/{Magick,Magick``,MagickCore,MagickWand,Wand}-config'
So it’s fixup would be:
IMAGEMAGICK_CONFIG_SCRIPTS = \ Magick-config Magick``-config \ MagickCore-config MagickWand-config Wand-config
On line 14, we specify the list of dependencies this package relies
on. These dependencies are listed in terms of lower-case package names,
which can be packages for the target (without the host-
prefix) or packages for the host (with the host-
) prefix).
Buildroot will ensure that all these packages are built and installed
'before' the current package starts its configuration.
The rest of the Makefile, lines 16..29, defines what should be done
at the different steps of the package configuration, compilation and
installation.
LIBFOO_BUILD_CMDS
tells what steps should be performed to
build the package. LIBFOO_INSTALL_STAGING_CMDS
tells what
steps should be performed to install the package in the staging space.
LIBFOO_INSTALL_TARGET_CMDS
tells what steps should be
performed to install the package in the target space.
All these steps rely on the $(@D)
variable, which
contains the directory where the source code of the package has been
extracted.
On lines 31..33, we define a user that is used by this package (e.g.
to run a daemon as non-root) (LIBFOO_USERS
).
On line 35..37, we define a device-node file used by this package
(LIBFOO_DEVICES
).
On line 39..41, we define the permissions to set to specific files
installed by this package (LIBFOO_PERMISSIONS
).
Finally, on line 43, we call the generic-package
function, which
generates, according to the variables defined previously, all the
Makefile code necessary to make your package working.
generic-package
reference
There are two variants of the generic target. The generic-package
macro is
used for packages to be cross-compiled for the target. The
host-generic-package
macro is used for host packages, natively compiled
for the host. It is possible to call both of them in a single .mk
file: once to create the rules to generate a target
package and once to create the rules to generate a host package:
$(eval $(generic-package)) $(eval $(host-generic-package))
This might be useful if the compilation of the target package requires
some tools to be installed on the host. If the package name is
libfoo
, then the name of the package for the target is also
libfoo
, while the name of the package for the host is
host-libfoo
. These names should be used in the DEPENDENCIES
variables of other packages, if they depend on libfoo
or
host-libfoo
.
The call to the generic-package
and/or host-generic-package
macro
must be at the end of the .mk
file, after all variable definitions.
The call to host-generic-package
must be after the call to
generic-package
, if any.
For the target package, the generic-package
uses the variables defined by
the .mk file and prefixed by the uppercased package name:
LIBFOO_*
. host-generic-package
uses the HOST_LIBFOO_*
variables. For
'some' variables, if the HOST_LIBFOO_
prefixed variable doesn’t
exist, the package infrastructure uses the corresponding variable
prefixed by LIBFOO_
. This is done for variables that are likely to
have the same value for both the target and host packages. See below
for details.
The list of variables that can be set in a .mk
file to give metadata
information is (assuming the package name is libfoo
) :
-
LIBFOO_VERSION
, mandatory, must contain the version of the package. Note that ifHOST_LIBFOO_VERSION
doesn’t exist, it is assumed to be the same asLIBFOO_VERSION
. It can also be a revision number or a tag for packages that are fetched directly from their version control system. Examples:-
a version for a release tarball:
LIBFOO_VERSION = 0.1.2
-
a sha1 for a git tree:
LIBFOO_VERSION = cb9d6aa9429e838f0e54faa3d455bcbab5eef057
-
a tag for a git tree
LIBFOO_VERSION = v0.1.2
Note:Using a branch name as
FOO_VERSION
is not supported, because it does not and can not work as people would expect it should:-
due to local caching, Buildroot will not re-fetch the repository, so people who expect to be able to follow the remote repository would be quite surprised and disappointed;
-
because two builds can never be perfectly simultaneous, and because the remote repository may get new commits on the branch anytime, two users, using the same Buildroot tree and building the same configuration, may get different source, thus rendering the build non reproducible, and people would be quite surprised and disappointed.
-
-
-
LIBFOO_SOURCE
may contain the name of the tarball of the package, which Buildroot will use to download the tarball fromLIBFOO_SITE
. IfHOST_LIBFOO_SOURCE
is not specified, it defaults toLIBFOO_SOURCE
. If none are specified, then the value is assumed to belibfoo-$(LIBFOO_VERSION).tar.gz
.
Example:LIBFOO_SOURCE = foobar-$(LIBFOO_VERSION).tar.bz2
-
LIBFOO_PATCH
may contain a space-separated list of patch file names, that Buildroot will download and apply to the package source code. If an entry contains://
, then Buildroot will assume it is a full URL and download the patch from this location. Otherwise, Buildroot will assume that the patch should be downloaded fromLIBFOO_SITE
. IfHOST_LIBFOO_PATCH
is not specified, it defaults toLIBFOO_PATCH
. Note that patches that are included in Buildroot itself use a different mechanism: all files of the form*.patch
present in the package directory inside Buildroot will be applied to the package after extraction (see patching a package). Finally, patches listed in theLIBFOO_PATCH
variable are applied before the patches stored in the Buildroot package directory. -
LIBFOO_SITE
provides the location of the package, which can be a URL or a local filesystem path. HTTP, FTP and SCP are supported URL types for retrieving package tarballs. In these cases don’t include a trailing slash: it will be added by Buildroot between the directory and the filename as appropriate. Git, Subversion, Mercurial, and Bazaar are supported URL types for retrieving packages directly from source code management systems. There is a helper function to make it easier to download source tarballs from GitHub (refer to [github-download-url] for details). A filesystem path may be used to specify either a tarball or a directory containing the package source code. SeeLIBFOO_SITE_METHOD
below for more details on how retrieval works.
Note that SCP URLs should be of the formscp://[user@]host:filepath
, and that filepath is relative to the user’s home directory, so you may want to prepend the path with a slash for absolute paths:scp://[user@]host:/absolutepath
. The same goes for SFTP URLs.
IfHOST_LIBFOO_SITE
is not specified, it defaults toLIBFOO_SITE
. Examples:
LIBFOO_SITE=http://www.libfoosoftware.org/libfoo
LIBFOO_SITE=http://svn.xiph.org/trunk/Tremor
LIBFOO_SITE=/opt/software/libfoo.tar.gz
LIBFOO_SITE=$(TOPDIR)/../src/libfoo
-
LIBFOO_DL_OPTS
is a space-separated list of additional options to pass to the downloader. Useful for retrieving documents with server-side checking for user logins and passwords, or to use a proxy. All download methods valid forLIBFOO_SITE_METHOD
are supported; valid options depend on the download method (consult the man page for the respective download utilities). -
LIBFOO_EXTRA_DOWNLOADS
is a space-separated list of additional files that Buildroot should download. If an entry contains://
then Buildroot will assume it is a complete URL and will download the file using this URL. Otherwise, Buildroot will assume the file to be downloaded is located atLIBFOO_SITE
. Buildroot will not do anything with those additional files, except download them: it will be up to the package recipe to use them from$(LIBFOO_DL_DIR)
. -
LIBFOO_SITE_METHOD
determines the method used to fetch or copy the package source code. In many cases, Buildroot guesses the method from the contents ofLIBFOO_SITE
and settingLIBFOO_SITE_METHOD
is unnecessary. WhenHOST_LIBFOO_SITE_METHOD
is not specified, it defaults to the value ofLIBFOO_SITE_METHOD
.
The possible values ofLIBFOO_SITE_METHOD
are:-
wget
for normal FTP/HTTP downloads of tarballs. Used by default whenLIBFOO_SITE
begins withhttp://
,https://
orftp://
. -
scp
for downloads of tarballs over SSH with scp. Used by default whenLIBFOO_SITE
begins withscp://
. -
sftp
for downloads of tarballs over SSH with sftp. Used by default whenLIBFOO_SITE
begins withsftp://
. -
svn
for retrieving source code from a Subversion repository. Used by default whenLIBFOO_SITE
begins withsvn://
. When ahttp://
Subversion repository URL is specified inLIBFOO_SITE
, one 'must' specifyLIBFOO_SITE_METHOD=svn
. Buildroot performs a checkout which is preserved as a tarball in the download cache; subsequent builds use the tarball instead of performing another checkout. -
cvs
for retrieving source code from a CVS repository. Used by default whenLIBFOO_SITE
begins withcvs://
. The downloaded source code is cached as with thesvn
method. Anonymous pserver mode is assumed otherwise explicitly defined onLIBFOO_SITE
. BothLIBFOO_SITE=cvs://libfoo.net:/cvsroot/libfoo
andLIBFOO_SITE=cvs://:ext:libfoo.net:/cvsroot/libfoo
are accepted, on the former anonymous pserver access mode is assumed.LIBFOO_SITE
'must' contain the source URL as well as the remote repository directory. The module is the package name.LIBFOO_VERSION
is 'mandatory' and 'must' be a tag, a branch, or a date (e.g. "2014-10-20", "2014-10-20 13:45", "2014-10-20 13:45+01" see "man cvs" for further details). -
git
for retrieving source code from a Git repository. Used by default whenLIBFOO_SITE
begins withgit://
. The downloaded source code is cached as with thesvn
method. -
hg
for retrieving source code from a Mercurial repository. One 'must' specifyLIBFOO_SITE_METHOD=hg
whenLIBFOO_SITE
contains a Mercurial repository URL. The downloaded source code is cached as with thesvn
method. -
bzr
for retrieving source code from a Bazaar repository. Used by default whenLIBFOO_SITE
begins withbzr://
. The downloaded source code is cached as with thesvn
method. -
file
for a local tarball. One should use this whenLIBFOO_SITE
specifies a package tarball as a local filename. Useful for software that isn’t available publicly or in version control. -
local
for a local source code directory. One should use this whenLIBFOO_SITE
specifies a local directory path containing the package source code. Buildroot copies the contents of the source directory into the package’s build directory. Note that forlocal
packages, no patches are applied. If you need to still patch the source code, useLIBFOO_POST_RSYNC_HOOKS
, see [hooks-rsync].
-
-
LIBFOO_GIT_SUBMODULES
can be set toYES
to create an archive with the git submodules in the repository. This is only available for packages downloaded with git (i.e. whenLIBFOO_SITE_METHOD=git
). Note that we try not to use such git submodules when they contain bundled libraries, in which case we prefer to use those libraries from their own package. -
LIBFOO_GIT_LFS
should be set toYES
if the Git repository uses Git LFS to store large files out of band. This is only available for packages downloaded with git (i.e. whenLIBFOO_SITE_METHOD=git
). -
LIBFOO_STRIP_COMPONENTS
is the number of leading components (directories) that tar must strip from file names on extraction. The tarball for most packages has one leading component named "<pkg-name>-<pkg-version>", thus Buildroot passes --strip-components=1 to tar to remove it. For non-standard packages that don’t have this component, or that have more than one leading component to strip, set this variable with the value to be passed to tar. Default: 1. -
LIBFOO_EXCLUDES
is a space-separated list of patterns to exclude when extracting the archive. Each item from that list is passed as a tar’s--exclude
option. By default, empty. -
LIBFOO_DEPENDENCIES
lists the dependencies (in terms of package name) that are required for the current target package to compile. These dependencies are guaranteed to be compiled and installed before the configuration of the current package starts. However, modifications to configuration of these dependencies will not force a rebuild of the current package. In a similar way,HOST_LIBFOO_DEPENDENCIES
lists the dependencies for the current host package. -
LIBFOO_EXTRACT_DEPENDENCIES
lists the dependencies (in terms of package name) that are required for the current target package to be extracted. These dependencies are guaranteed to be compiled and installed before the extract step of the current package starts. This is only used internally by the package infrastructure, and should typically not be used directly by packages. -
LIBFOO_PATCH_DEPENDENCIES
lists the dependencies (in terms of package name) that are required for the current package to be patched. These dependencies are guaranteed to be extracted and patched (but not necessarily built) before the current package is patched. In a similar way,HOST_LIBFOO_PATCH_DEPENDENCIES
lists the dependencies for the current host package. This is seldom used; usually,LIBFOO_DEPENDENCIES
is what you really want to use. -
LIBFOO_PROVIDES
lists all the virtual packageslibfoo
is an implementation of. See [virtual-package-tutorial]. -
LIBFOO_INSTALL_STAGING
can be set toYES
orNO
(default). If set toYES
, then the commands in theLIBFOO_INSTALL_STAGING_CMDS
variables are executed to install the package into the staging directory. -
LIBFOO_INSTALL_TARGET
can be set toYES
(default) orNO
. If set toYES
, then the commands in theLIBFOO_INSTALL_TARGET_CMDS
variables are executed to install the package into the target directory. -
LIBFOO_INSTALL_IMAGES
can be set toYES
orNO
(default). If set toYES
, then the commands in theLIBFOO_INSTALL_IMAGES_CMDS
variable are executed to install the package into the images directory. -
LIBFOO_CONFIG_SCRIPTS
lists the names of the files in '$(STAGING_DIR)/usr/bin' that need some special fixing to make them cross-compiling friendly. Multiple file names separated by space can be given and all are relative to '$(STAGING_DIR)/usr/bin'. The files listed inLIBFOO_CONFIG_SCRIPTS
are also removed from$(TARGET_DIR)/usr/bin
since they are not needed on the target. -
LIBFOO_DEVICES
lists the device files to be created by Buildroot when using the static device table. The syntax to use is the makedevs one. You can find some documentation for this syntax in the [makedev-syntax]. This variable is optional. -
LIBFOO_PERMISSIONS
lists the changes of permissions to be done at the end of the build process. The syntax is once again the makedevs one. You can find some documentation for this syntax in the [makedev-syntax]. This variable is optional. -
LIBFOO_USERS
lists the users to create for this package, if it installs a program you want to run as a specific user (e.g. as a daemon, or as a cron-job). The syntax is similar in spirit to the makedevs one, and is described in the [makeuser-syntax]. This variable is optional. -
LIBFOO_LICENSE
defines the license (or licenses) under which the package is released. This name will appear in the manifest file produced bymake legal-info
. If the license appears in the SPDX License List, use the SPDX short identifier to make the manifest file uniform. Otherwise, describe the license in a precise and concise way, avoiding ambiguous names such asBSD
which actually name a family of licenses. This variable is optional. If it is not defined,unknown
will appear in thelicense
field of the manifest file for this package.
The expected format for this variable must comply with the following rules:-
If different parts of the package are released under different licenses, then
comma
separate licenses (e.g. `LIBFOO_LICENSE = GPL-2.0`, LGPL-2.1``). If there is clear distinction between which component is licensed under what license, then annotate the license with that component, between parenthesis (e.g. `LIBFOO_LICENSE = GPL-2.0` (programs), LGPL-2.1` (libraries)`). -
If some licenses are conditioned on a sub-option being enabled, append the conditional licenses with a comma (e.g.:
FOO_LICENSE `= , GPL-2.0
(programs)`); the infrastructure will internally remove the space before the comma. -
If the package is dual licensed, then separate licenses with the
or
keyword (e.g.LIBFOO_LICENSE = AFL-2.1 or GPL-2.0
+).
-
-
LIBFOO_LICENSE_FILES
is a space-separated list of files in the package tarball that contain the license(s) under which the package is released.make legal-info
copies all of these files in thelegal-info
directory. See [legal-info] for more information. This variable is optional. If it is not defined, a warning will be produced to let you know, andnot saved
will appear in thelicense files
field of the manifest file for this package. -
LIBFOO_ACTUAL_SOURCE_TARBALL
only applies to packages whoseLIBFOO_SITE
/LIBFOO_SOURCE
pair points to an archive that does not actually contain source code, but binary code. This a very uncommon case, only known to apply to external toolchains which come already compiled, although theoretically it might apply to other packages. In such cases a separate tarball is usually available with the actual source code. SetLIBFOO_ACTUAL_SOURCE_TARBALL
to the name of the actual source code archive and Buildroot will download it and use it when you runmake legal-info
to collect legally-relevant material. Note this file will not be downloaded during regular builds nor bymake source
. -
LIBFOO_ACTUAL_SOURCE_SITE
provides the location of the actual source tarball. The default value isLIBFOO_SITE
, so you don’t need to set this variable if the binary and source archives are hosted on the same directory. IfLIBFOO_ACTUAL_SOURCE_TARBALL
is not set, it doesn’t make sense to defineLIBFOO_ACTUAL_SOURCE_SITE
. -
LIBFOO_REDISTRIBUTE
can be set toYES
(default) orNO
to indicate if the package source code is allowed to be redistributed. Set it toNO
for non-opensource packages: Buildroot will not save the source code for this package when collecting thelegal-info
. -
LIBFOO_FLAT_STACKSIZE
defines the stack size of an application built into the FLAT binary format. The application stack size on the NOMMU architecture processors can’t be enlarged at run time. The default stack size for the FLAT binary format is only 4k bytes. If the application consumes more stack, append the required number here. -
LIBFOO_BIN_ARCH_EXCLUDE
is a space-separated list of paths (relative to the target directory) to ignore when checking that the package installs correctly cross-compiled binaries. You seldom need to set this variable, unless the package installs binary blobs outside the default locations,/lib/firmware
,/usr/lib/firmware
,/lib/modules
,/usr/lib/modules
, and/usr/share
, which are automatically excluded. -
LIBFOO_IGNORE_CVES
is a space-separated list of CVEs that tells Buildroot CVE tracking tools which CVEs should be ignored for this package. This is typically used when the CVE is fixed by a patch in the package, or when the CVE for some reason does not affect the Buildroot package. A Makefile comment must always precede the addition of a CVE to this variable. Example:
# 0001-fix-cve-2020-12345.patch LIBFOO_IGNORE_CVES += CVE-2020-12345 # only when built with libbaz, which Buildroot doesn't support LIBFOO_IGNORE_CVES += CVE-2020-54321
-
LIBFOO_CPE_ID_*
variables is a set of variables that allows the package to define its CPE identifier. The available variables are:-
LIBFOO_CPE_ID_PREFIX
, specifies the prefix of the CPE identifier, i.e the first three fields. When not defined, the default value iscpe:2.3:a
. -
LIBFOO_CPE_ID_VENDOR
, specifies the vendor part of the CPE identifier. When not defined, the default value is<pkgname>_project
. -
LIBFOO_CPE_ID_PRODUCT
, specifies the product part of the CPE identifier. When not defined, the default value is<pkgname>
. -
LIBFOO_CPE_ID_VERSION
, specifies the version part of the CPE identifier. When not defined the default value is$(LIBFOO_VERSION)
. -
LIBFOO_CPE_ID_UPDATE
specifies the update part of the CPE identifier. When not defined the default value is*
.
If any of those variables is defined, then the generic package infrastructure assumes the package provides valid CPE information. In this case, the generic package infrastructure will define
LIBFOO_CPE_ID
.For a host package, if its
LIBFOO_CPE_ID_*
variables are not defined, it inherits the value of those variables from the corresponding target package. -
The recommended way to define these variables is to use the following syntax:
LIBFOO_VERSION = 2.32
Now, the variables that define what should be performed at the different steps of the build process.
-
LIBFOO_EXTRACT_CMDS
lists the actions to be performed to extract the package. This is generally not needed as tarballs are automatically handled by Buildroot. However, if the package uses a non-standard archive format, such as a ZIP or RAR file, or has a tarball with a non-standard organization, this variable allows to override the package infrastructure default behavior. -
LIBFOO_CONFIGURE_CMDS
lists the actions to be performed to configure the package before its compilation. -
LIBFOO_BUILD_CMDS
lists the actions to be performed to compile the package. -
HOST_LIBFOO_INSTALL_CMDS
lists the actions to be performed to install the package, when the package is a host package. The package must install its files to the directory given by$(HOST_DIR)
. All files, including development files such as headers should be installed, since other packages might be compiled on top of this package. -
LIBFOO_INSTALL_TARGET_CMDS
lists the actions to be performed to install the package to the target directory, when the package is a target package. The package must install its files to the directory given by$(TARGET_DIR)
. Only the files required for 'execution' of the package have to be installed. Header files, static libraries and documentation will be removed again when the target filesystem is finalized. -
LIBFOO_INSTALL_STAGING_CMDS
lists the actions to be performed to install the package to the staging directory, when the package is a target package. The package must install its files to the directory given by$(STAGING_DIR)
. All development files should be installed, since they might be needed to compile other packages. -
LIBFOO_INSTALL_IMAGES_CMDS
lists the actions to be performed to install the package to the images directory, when the package is a target package. The package must install its files to the directory given by$(BINARIES_DIR)
. Only files that are binary images (aka images) that do not belong in theTARGET_DIR
but are necessary for booting the board should be placed here. For example, a package should utilize this step if it has binaries which would be similar to the kernel image, bootloader or root filesystem images. -
LIBFOO_INSTALL_INIT_SYSV
,LIBFOO_INSTALL_INIT_OPENRC
andLIBFOO_INSTALL_INIT_SYSTEMD
list the actions to install init scripts either for the systemV-like init systems (busybox, sysvinit, etc.), openrc or for the systemd units. These commands will be run only when the relevant init system is installed (i.e. if systemd is selected as the init system in the configuration, onlyLIBFOO_INSTALL_INIT_SYSTEMD
will be run). The only exception is when openrc is chosen as init system andLIBFOO_INSTALL_INIT_OPENRC
has not been set, in such situationLIBFOO_INSTALL_INIT_SYSV
will be called, since openrc supports sysv init scripts. When systemd is used as the init system, buildroot will automatically enable all services using thesystemctl preset-all
command in the final phase of image building. You can add preset files to prevent a particular unit from being automatically enabled by buildroot. -
LIBFOO_HELP_CMDS
lists the actions to print the package help, which is included to the mainmake help
output. These commands can print anything in any format. This is seldom used, as packages rarely have custom rules. Do not use this variable, unless you really know that you need to print help. -
LIBFOO_LINUX_CONFIG_FIXUPS
lists the Linux kernel configuration options that are needed to build and use this package, and without which the package is fundamentally broken. This shall be a set of calls to one of the kconfig tweaking option:KCONFIG_ENABLE_OPT
,KCONFIG_DISABLE_OPT
, orKCONFIG_SET_OPT
. This is seldom used, as package usually have no strict requirements on the kernel options.
The preferred way to define these variables is:
define LIBFOO_CONFIGURE_CMDS action 1 action 2 action 3 endef
In the action definitions, you can use the following variables:
-
$(LIBFOO_PKGDIR)
contains the path to the directory containing thelibfoo.mk
andConfig.in
files. This variable is useful when it is necessary to install a file bundled in Buildroot, like a runtime configuration file, a splashscreen image… -
$(@D)
, which contains the directory in which the package source code has been uncompressed. -
$(LIBFOO_DL_DIR)
contains the path to the directory where all the downloads made by Buildroot forlibfoo
are stored in. -
$(TARGET_CC)
,$(TARGET_LD)
, etc. to get the target cross-compilation utilities -
$(TARGET_CROSS)
to get the cross-compilation toolchain prefix -
Of course the
$(HOST_DIR)
,$(STAGING_DIR)
and$(TARGET_DIR)
variables to install the packages properly. Those variables point to the global host, staging and target directories, unless per-package directory support is used, in which case they point to the current package host, staging and target directories. In both cases, it doesn’t make any difference from the package point of view: it should simply useHOST_DIR
,STAGING_DIR
andTARGET_DIR
. See [top-level-parallel-build] for more details about per-package directory support.
Finally, you can also use hooks. See [hooks] for more information.
Infrastructure for autotools-based packages
autotools-package
tutorial
First, let’s see how to write a .mk
file for an autotools-based
package, with an example :
01: ################################################################################ 02: # 03: # libfoo 04: # 05: ################################################################################ 06: 07: LIBFOO_VERSION = 1.0 08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz 09: LIBFOO_SITE = http://www.foosoftware.org/download 10: LIBFOO_INSTALL_STAGING = YES 11: LIBFOO_INSTALL_TARGET = NO 12: LIBFOO_CONF_OPTS = --disable-shared 13: LIBFOO_DEPENDENCIES = libglib2 host-pkgconf 14: 15: $(eval $(autotools-package))
On line 7, we declare the version of the package.
On line 8 and 9, we declare the name of the tarball (xz-ed tarball recommended) and the location of the tarball on the Web. Buildroot will automatically download the tarball from this location.
On line 10, we tell Buildroot to install the package to the staging
directory. The staging directory, located in output/staging/
is the directory where all the packages are installed, including their
development files, etc. By default, packages are not installed to the
staging directory, since usually, only libraries need to be installed in
the staging directory: their development files are needed to compile
other libraries or applications depending on them. Also by default, when
staging installation is enabled, packages are installed in this location
using the make install
command.
On line 11, we tell Buildroot to not install the package to the
target directory. This directory contains what will become the root
filesystem running on the target. For purely static libraries, it is
not necessary to install them in the target directory because they will
not be used at runtime. By default, target installation is enabled; setting
this variable to NO is almost never needed. Also by default, packages are
installed in this location using the make install
command.
On line 12, we tell Buildroot to pass a custom configure option, that
will be passed to the ./configure
script before configuring
and building the package.
On line 13, we declare our dependencies, so that they are built before the build process of our package starts.
Finally, on line line 15, we invoke the autotools-package
macro that generates all the Makefile rules that actually allows the
package to be built.
autotools-package
reference
The main macro of the autotools package infrastructure is
autotools-package
. It is similar to the generic-package
macro. The ability to
have target and host packages is also available, with the
host-autotools-package
macro.
Just like the generic infrastructure, the autotools infrastructure
works by defining a number of variables before calling the
autotools-package
macro.
First, all the package metadata information variables that exist in the
generic infrastructure also exist in the autotools infrastructure:
LIBFOO_VERSION
, LIBFOO_SOURCE
,
LIBFOO_PATCH
, LIBFOO_SITE
,
LIBFOO_SUBDIR
, LIBFOO_DEPENDENCIES
,
LIBFOO_INSTALL_STAGING
, LIBFOO_INSTALL_TARGET
.
A few additional variables, specific to the autotools infrastructure, can also be defined. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them.
-
LIBFOO_SUBDIR
may contain the name of a subdirectory inside the package that contains the configure script. This is useful, if for example, the main configure script is not at the root of the tree extracted by the tarball. IfHOST_LIBFOO_SUBDIR
is not specified, it defaults toLIBFOO_SUBDIR
. -
LIBFOO_CONF_ENV
, to specify additional environment variables to pass to the configure script. By default, empty. -
LIBFOO_CONF_OPTS
, to specify additional configure options to pass to the configure script. By default, empty. -
LIBFOO_MAKE
, to specify an alternatemake
command. This is typically useful when parallel make is enabled in the configuration (usingBR2_JLEVEL
) but that this feature should be disabled for the given package, for one reason or another. By default, set to$(MAKE)
. If parallel building is not supported by the package, then it should be set toLIBFOO_MAKE=$(MAKE1)
. -
LIBFOO_MAKE_ENV
, to specify additional environment variables to pass to make in the build step. These are passed before themake
command. By default, empty. -
LIBFOO_MAKE_OPTS
, to specify additional variables to pass to make in the build step. These are passed after themake
command. By default, empty. -
LIBFOO_AUTORECONF
, tells whether the package should be autoreconfigured or not (i.e. if the configure script and Makefile.in files should be re-generated by re-running autoconf, automake, libtool, etc.). Valid values areYES
andNO
. By default, the value isNO
-
LIBFOO_AUTORECONF_ENV
, to specify additional environment variables to pass to the 'autoreconf' program ifLIBFOO_AUTORECONF=YES
. These are passed in the environment of the 'autoreconf' command. By default, empty. -
LIBFOO_AUTORECONF_OPTS
to specify additional options passed to the 'autoreconf' program ifLIBFOO_AUTORECONF=YES
. By default, empty. -
LIBFOO_GETTEXTIZE
, tells whether the package should be gettextized or not (i.e. if the package uses a different gettext version than Buildroot provides, and it is needed to run 'gettextize'.) Only valid whenLIBFOO_AUTORECONF=YES
. Valid values areYES
andNO
. The default isNO
. -
LIBFOO_GETTEXTIZE_OPTS
, to specify additional options passed to the 'gettextize' program, ifLIBFOO_GETTEXTIZE=YES
. You may use that if, for example, the.po
files are not located in the standard place (i.e. inpo/
at the root of the package.) By default, '-f'. -
LIBFOO_LIBTOOL_PATCH
tells whether the Buildroot patch to fix libtool cross-compilation issues should be applied or not. Valid values areYES
andNO
. By default, the value isYES
-
LIBFOO_INSTALL_STAGING_OPTS
contains the make options used to install the package to the staging directory. By default, the value isDESTDIR=$(STAGING_DIR) install
, which is correct for most autotools packages. It is still possible to override it. -
LIBFOO_INSTALL_TARGET_OPTS
contains the make options used to install the package to the target directory. By default, the value isDESTDIR=$(TARGET_DIR) install
. The default value is correct for most autotools packages, but it is still possible to override it if needed.
With the autotools infrastructure, all the steps required to build and install the packages are already defined, and they generally work well for most autotools-based packages. However, when required, it is still possible to customize what is done in any particular step:
-
By adding a post-operation hook (after extract, patch, configure, build or install). See [hooks] for details.
-
By overriding one of the steps. For example, even if the autotools infrastructure is used, if the package
.mk
file defines its ownLIBFOO_CONFIGURE_CMDS
variable, it will be used instead of the default autotools one. However, using this method should be restricted to very specific cases. Do not use it in the general case.
Infrastructure for CMake-based packages
cmake-package
tutorial
First, let’s see how to write a .mk
file for a CMake-based package,
with an example :
01: ################################################################################ 02: # 03: # libfoo 04: # 05: ################################################################################ 06: 07: LIBFOO_VERSION = 1.0 08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz 09: LIBFOO_SITE = http://www.foosoftware.org/download 10: LIBFOO_INSTALL_STAGING = YES 11: LIBFOO_INSTALL_TARGET = NO 12: LIBFOO_CONF_OPTS = -DBUILD_DEMOS=ON 13: LIBFOO_DEPENDENCIES = libglib2 host-pkgconf 14: 15: $(eval $(cmake-package))
On line 7, we declare the version of the package.
On line 8 and 9, we declare the name of the tarball (xz-ed tarball recommended) and the location of the tarball on the Web. Buildroot will automatically download the tarball from this location.
On line 10, we tell Buildroot to install the package to the staging
directory. The staging directory, located in output/staging/
is the directory where all the packages are installed, including their
development files, etc. By default, packages are not installed to the
staging directory, since usually, only libraries need to be installed in
the staging directory: their development files are needed to compile
other libraries or applications depending on them. Also by default, when
staging installation is enabled, packages are installed in this location
using the make install
command.
On line 11, we tell Buildroot to not install the package to the
target directory. This directory contains what will become the root
filesystem running on the target. For purely static libraries, it is
not necessary to install them in the target directory because they will
not be used at runtime. By default, target installation is enabled; setting
this variable to NO is almost never needed. Also by default, packages are
installed in this location using the make install
command.
On line 12, we tell Buildroot to pass custom options to CMake when it is configuring the package.
On line 13, we declare our dependencies, so that they are built before the build process of our package starts.
Finally, on line line 15, we invoke the cmake-package
macro that generates all the Makefile rules that actually allows the
package to be built.
cmake-package
reference
The main macro of the CMake package infrastructure is
cmake-package
. It is similar to the generic-package
macro. The ability to
have target and host packages is also available, with the
host-cmake-package
macro.
Just like the generic infrastructure, the CMake infrastructure works
by defining a number of variables before calling the cmake-package
macro.
First, all the package metadata information variables that exist in
the generic infrastructure also exist in the CMake infrastructure:
LIBFOO_VERSION
, LIBFOO_SOURCE
, LIBFOO_PATCH
, LIBFOO_SITE
,
LIBFOO_SUBDIR
, LIBFOO_DEPENDENCIES
, LIBFOO_INSTALL_STAGING
,
LIBFOO_INSTALL_TARGET
.
A few additional variables, specific to the CMake infrastructure, can also be defined. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them.
-
LIBFOO_SUBDIR
may contain the name of a subdirectory inside the package that contains the main CMakeLists.adoc file. This is useful, if for example, the main CMakeLists.adoc file is not at the root of the tree extracted by the tarball. IfHOST_LIBFOO_SUBDIR
is not specified, it defaults toLIBFOO_SUBDIR
. -
LIBFOO_CONF_ENV
, to specify additional environment variables to pass to CMake. By default, empty. -
LIBFOO_CONF_OPTS
, to specify additional configure options to pass to CMake. By default, empty. A number of common CMake options are set by thecmake-package
infrastructure; so it is normally not necessary to set them in the package’s*.mk
file unless you want to override them:-
CMAKE_BUILD_TYPE
is driven byBR2_ENABLE_RUNTIME_DEBUG
; -
CMAKE_INSTALL_PREFIX
; -
BUILD_SHARED_LIBS
is driven byBR2_STATIC_LIBS
; -
BUILD_DOC
,BUILD_DOCS
are disabled; -
BUILD_EXAMPLE
,BUILD_EXAMPLES
are disabled; -
BUILD_TEST
,BUILD_TESTS
,BUILD_TESTING
are disabled.
-
-
LIBFOO_SUPPORTS_IN_SOURCE_BUILD = NO
should be set when the package cannot be built inside the source tree but needs a separate build directory. -
LIBFOO_MAKE
, to specify an alternatemake
command. This is typically useful when parallel make is enabled in the configuration (usingBR2_JLEVEL
) but that this feature should be disabled for the given package, for one reason or another. By default, set to$(MAKE)
. If parallel building is not supported by the package, then it should be set toLIBFOO_MAKE=$(MAKE1)
. -
LIBFOO_MAKE_ENV
, to specify additional environment variables to pass to make in the build step. These are passed before themake
command. By default, empty. -
LIBFOO_MAKE_OPTS
, to specify additional variables to pass to make in the build step. These are passed after themake
command. By default, empty. -
LIBFOO_INSTALL_OPTS
contains the make options used to install the package to the host directory. By default, the value isinstall
, which is correct for most CMake packages. It is still possible to override it. -
LIBFOO_INSTALL_STAGING_OPTS
contains the make options used to install the package to the staging directory. By default, the value isDESTDIR=$(STAGING_DIR) install/fast
, which is correct for most CMake packages. It is still possible to override it. -
LIBFOO_INSTALL_TARGET_OPTS
contains the make options used to install the package to the target directory. By default, the value isDESTDIR=$(TARGET_DIR) install/fast
. The default value is correct for most CMake packages, but it is still possible to override it if needed.
With the CMake infrastructure, all the steps required to build and install the packages are already defined, and they generally work well for most CMake-based packages. However, when required, it is still possible to customize what is done in any particular step:
-
By adding a post-operation hook (after extract, patch, configure, build or install). See [hooks] for details.
-
By overriding one of the steps. For example, even if the CMake infrastructure is used, if the package
.mk
file defines its ownLIBFOO_CONFIGURE_CMDS
variable, it will be used instead of the default CMake one. However, using this method should be restricted to very specific cases. Do not use it in the general case.
Infrastructure for Python packages
This infrastructure applies to Python packages that use the standard
Python setuptools or pep517 mechanisms as their build system, generally
recognizable by the usage of a setup.py
script or pyproject.toml
file.
python-package
tutorial
First, let’s see how to write a .mk
file for a Python package,
with an example :
01: ################################################################################ 02: # 03: # python-foo 04: # 05: ################################################################################ 06: 07: PYTHON_FOO_VERSION = 1.0 08: PYTHON_FOO_SOURCE = python-foo-$(PYTHON_FOO_VERSION).tar.xz 09: PYTHON_FOO_SITE = http://www.foosoftware.org/download 10: PYTHON_FOO_LICENSE = BSD-3-Clause 11: PYTHON_FOO_LICENSE_FILES = LICENSE 12: PYTHON_FOO_ENV = SOME_VAR=1 13: PYTHON_FOO_DEPENDENCIES = libmad 14: PYTHON_FOO_SETUP_TYPE = distutils 15: 16: $(eval $(python-package))
On line 7, we declare the version of the package.
On line 8 and 9, we declare the name of the tarball (xz-ed tarball recommended) and the location of the tarball on the Web. Buildroot will automatically download the tarball from this location.
On line 10 and 11, we give licensing details about the package (its license on line 10, and the file containing the license text on line 11).
On line 12, we tell Buildroot to pass custom options to the Python
setup.py
script when it is configuring the package.
On line 13, we declare our dependencies, so that they are built before the build process of our package starts.
On line 14, we declare the specific Python build system being used. In
this case the distutils
Python build system is used. The four
supported ones are distutils
, flit
, pep517
and setuptools
.
Finally, on line 16, we invoke the python-package
macro that
generates all the Makefile rules that actually allow the package to be
built.
python-package
reference
As a policy, packages that merely provide Python modules should all be
named python-<something>
in Buildroot. Other packages that use the
Python build system, but are not Python modules, can freely choose
their name (existing examples in Buildroot are scons
and
supervisor
).
The main macro of the Python package infrastructure is
python-package
. It is similar to the generic-package
macro. It is
also possible to create Python host packages with the
host-python-package
macro.
Just like the generic infrastructure, the Python infrastructure works
by defining a number of variables before calling the python-package
or host-python-package
macros.
All the package metadata information variables that exist in the
generic package infrastructure also
exist in the Python infrastructure: PYTHON_FOO_VERSION
,
PYTHON_FOO_SOURCE
, PYTHON_FOO_PATCH
, PYTHON_FOO_SITE
,
PYTHON_FOO_SUBDIR
, PYTHON_FOO_DEPENDENCIES
, PYTHON_FOO_LICENSE
,
PYTHON_FOO_LICENSE_FILES
, PYTHON_FOO_INSTALL_STAGING
, etc.
Note that:
-
It is not necessary to add
python
orhost-python
in thePYTHON_FOO_DEPENDENCIES
variable of a package, since these basic dependencies are automatically added as needed by the Python package infrastructure. -
Similarly, it is not needed to add
host-setuptools
toPYTHON_FOO_DEPENDENCIES
for setuptools-based packages, since it’s automatically added by the Python infrastructure as needed.
One variable specific to the Python infrastructure is mandatory:
-
PYTHON_FOO_SETUP_TYPE
, to define which Python build system is used by the package. The four supported values aredistutils
,flit
,pep517
andsetuptools
. If you don’t know which one is used in your package, look at thesetup.py
orpyproject.toml
file in your package source code, and see whether it imports things from thedistutils
,flit
module or thesetuptools
module. If the package is using apyproject.toml
file without any build-system requires and with a local in-tree backend-path one should usepep517
.
A few additional variables, specific to the Python infrastructure, can optionally be defined, depending on the package’s needs. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them, or none.
-
PYTHON_FOO_SUBDIR
may contain the name of a subdirectory inside the package that contains the mainsetup.py
orpyproject.toml
file. This is useful, if for example, the mainsetup.py
orpyproject.toml
file is not at the root of the tree extracted by the tarball. IfHOST_PYTHON_FOO_SUBDIR
is not specified, it defaults toPYTHON_FOO_SUBDIR
. -
PYTHON_FOO_ENV
, to specify additional environment variables to pass to the Pythonsetup.py
script (for distutils/setuptools packages) or thesupport/scripts/pyinstaller.py
script (for flit/pep517 packages) for both the build and install steps. Note that the infrastructure is automatically passing several standard variables, defined inPKG_PYTHON_DISTUTILS_ENV
(for distutils target packages),HOST_PKG_PYTHON_DISTUTILS_ENV
(for distutils host packages),PKG_PYTHON_SETUPTOOLS_ENV
(for setuptools target packages),HOST_PKG_PYTHON_SETUPTOOLS_ENV
(for setuptools host packages),PKG_PYTHON_PEP517_ENV
(for flit/pep517 target packages) andHOST_PKG_PYTHON_PEP517_ENV
(for flit/pep517 host packages). -
PYTHON_FOO_BUILD_OPTS
, to specify additional options to pass to the Pythonsetup.py
script during the build step, this generally only makes sense to use for distutils/setuptools based packages as flit/pep517 based packages do not pass these options to asetup.py
script but instead pass them tosupport/scripts/pyinstaller.py
. For target distutils packages, thePKG_PYTHON_DISTUTILS_BUILD_OPTS
options are already passed automatically by the infrastructure. -
PYTHON_FOO_INSTALL_TARGET_OPTS
,PYTHON_FOO_INSTALL_STAGING_OPTS
,HOST_PYTHON_FOO_INSTALL_OPTS
to specify additional options to pass to the Pythonsetup.py
script (for distutils/setuptools packages) orsupport/scripts/pyinstaller.py
(for flit/pep517 packages) during the target installation step, the staging installation step or the host installation, respectively. Note that the infrastructure is automatically passing some options, defined inPKG_PYTHON_DISTUTILS_INSTALL_TARGET_OPTS
orPKG_PYTHON_DISTUTILS_INSTALL_STAGING_OPTS
(for target distutils packages),HOST_PKG_PYTHON_DISTUTILS_INSTALL_OPTS
(for host distutils packages),PKG_PYTHON_SETUPTOOLS_INSTALL_TARGET_OPTS
orPKG_PYTHON_SETUPTOOLS_INSTALL_STAGING_OPTS
(for target setuptools packages),HOST_PKG_PYTHON_SETUPTOOLS_INSTALL_OPTS
(for host setuptools packages) andPKG_PYTHON_PEP517_INSTALL_TARGET_OPTS
orPKG_PYTHON_PEP517_INSTALL_STAGING_OPTS
(for target flit/pep517 packages).
With the Python infrastructure, all the steps required to build and install the packages are already defined, and they generally work well for most Python-based packages. However, when required, it is still possible to customize what is done in any particular step:
-
By adding a post-operation hook (after extract, patch, configure, build or install). See [hooks] for details.
-
By overriding one of the steps. For example, even if the Python infrastructure is used, if the package
.mk
file defines its ownPYTHON_FOO_BUILD_CMDS
variable, it will be used instead of the default Python one. However, using this method should be restricted to very specific cases. Do not use it in the general case.
Generating a python-package
from a PyPI repository
If the Python package for which you would like to create a Buildroot
package is available on PyPI, you may want to use the scanpypi
tool
located in utils/
to automate the process.
You can find the list of existing PyPI packages here.
scanpypi
requires Python’s setuptools
package to be installed on
your host.
When at the root of your buildroot directory just do :
utils/scanpypi foo bar -o package
This will generate packages python-foo
and python-bar
in the package
folder if they exist on https://pypi.python.org.
Find the external python modules
menu and insert your package inside.
Keep in mind that the items inside a menu should be in alphabetical order.
Please keep in mind that you’ll most likely have to manually check the
package for any mistakes as there are things that cannot be guessed by
the generator (e.g. dependencies on any of the python core modules
such as BR2_PACKAGE_PYTHON_ZLIB). Also, please take note that the
license and license files are guessed and must be checked. You also
need to manually add the package to the package/Config.in
file.
If your Buildroot package is not in the official Buildroot tree but in a br2-external tree, use the -o flag as follows:
utils/scanpypi foo bar -o other_package_dir
This will generate packages python-foo
and python-bar
in the
other_package_directory
instead of package
.
Option -h
will list the available options:
utils/scanpypi -h
python-package
CFFI backend
C Foreign Function Interface for Python (CFFI) provides a convenient
and reliable way to call compiled C code from Python using interface
declarations written in C. Python packages relying on this backend can
be identified by the appearance of a cffi
dependency in the
install_requires
field of their setup.py
file.
Such a package should:
-
add
python-cffi
as a runtime dependency in order to install the compiled C library wrapper on the target. This is achieved by addingselect BR2_PACKAGE_PYTHON_CFFI
to the packageConfig.in
.
config BR2_PACKAGE_PYTHON_FOO bool "python-foo" select BR2_PACKAGE_PYTHON_CFFI # runtime
-
add
host-python-cffi
as a build-time dependency in order to cross-compile the C wrapper. This is achieved by addinghost-python-cffi
to thePYTHON_FOO_DEPENDENCIES
variable.
################################################################################ # # python-foo # ################################################################################ ... PYTHON_FOO_DEPENDENCIES = host-python-cffi $(eval $(python-package))
Infrastructure for LuaRocks-based packages
luarocks-package
tutorial
First, let’s see how to write a .mk
file for a LuaRocks-based package,
with an example :
01: ################################################################################ 02: # 03: # lua-foo 04: # 05: ################################################################################ 06: 07: LUA_FOO_VERSION = 1.0.2-1 08: LUA_FOO_NAME_UPSTREAM = foo 09: LUA_FOO_DEPENDENCIES = bar 10: 11: LUA_FOO_BUILD_OPTS += BAR_INCDIR=$(STAGING_DIR)/usr/include 12: LUA_FOO_BUILD_OPTS += BAR_LIBDIR=$(STAGING_DIR)/usr/lib 13: LUA_FOO_LICENSE = luaFoo license 14: LUA_FOO_LICENSE_FILES = $(LUA_FOO_SUBDIR)/COPYING 15: 16: $(eval $(luarocks-package))
On line 7, we declare the version of the package (the same as in the rockspec, which is the concatenation of the upstream version and the rockspec revision, separated by a hyphen '-').
On line 8, we declare that the package is called "foo" on LuaRocks. In
Buildroot, we give Lua-related packages a name that starts with "lua", so the
Buildroot name is different from the upstream name. LUA_FOO_NAME_UPSTREAM
makes the link between the two names.
On line 9, we declare our dependencies against native libraries, so that they are built before the build process of our package starts.
On lines 11-12, we tell Buildroot to pass custom options to LuaRocks when it is building the package.
On lines 13-14, we specify the licensing terms for the package.
Finally, on line 16, we invoke the luarocks-package
macro that generates all the Makefile rules that actually allows the
package to be built.
Most of these details can be retrieved from the rock
and rockspec
.
So, this file and the Config.in file can be generated by running the
command luarocks buildroot foo lua-foo
in the Buildroot
directory. This command runs a specific Buildroot addon of luarocks
that will automatically generate a Buildroot package. The result must
still be manually inspected and possibly modified.
-
The
package/Config.in
file has to be updated manually to include the generated Config.in files.
luarocks-package
reference
LuaRocks is a deployment and management system for Lua modules, and supports
various build.type
: builtin
, make
and cmake
. In the context of
Buildroot, the luarocks-package
infrastructure only supports the builtin
mode. LuaRocks packages that use the make
or cmake
build mechanisms
should instead be packaged using the generic-package
and cmake-package
infrastructures in Buildroot, respectively.
The main macro of the LuaRocks package infrastructure is luarocks-package
:
like generic-package
it works by defining a number of variables providing
metadata information about the package, and then calling luarocks-package
.
Just like the generic infrastructure, the LuaRocks infrastructure works
by defining a number of variables before calling the luarocks-package
macro.
First, all the package metadata information variables that exist in
the generic infrastructure also exist in the LuaRocks infrastructure:
LUA_FOO_VERSION
, LUA_FOO_SOURCE
, LUA_FOO_SITE
,
LUA_FOO_DEPENDENCIES
, LUA_FOO_LICENSE
, LUA_FOO_LICENSE_FILES
.
Two of them are populated by the LuaRocks infrastructure (for the
download
step). If your package is not hosted on the LuaRocks mirror
$(BR2_LUAROCKS_MIRROR)
, you can override them:
-
LUA_FOO_SITE
, which defaults to$(BR2_LUAROCKS_MIRROR)
-
LUA_FOO_SOURCE
, which defaults to$(lowercase LUA_FOO_NAME_UPSTREAM)-$(LUA_FOO_VERSION).src.rock
A few additional variables, specific to the LuaRocks infrastructure, are also defined. They can be overridden in specific cases.
-
LUA_FOO_NAME_UPSTREAM
, which defaults tolua-foo
, i.e. the Buildroot package name -
LUA_FOO_ROCKSPEC
, which defaults to$(lowercase LUA_FOO_NAME_UPSTREAM)-$(LUA_FOO_VERSION).rockspec
-
LUA_FOO_SUBDIR
, which defaults to$(LUA_FOO_NAME_UPSTREAM)-$(LUA_FOO_VERSION_WITHOUT_ROCKSPEC_REVISION)
-
LUA_FOO_BUILD_OPTS
contains additional build options for theluarocks build
call.
Infrastructure for Perl/CPAN packages
perl-package
tutorial
First, let’s see how to write a .mk
file for a Perl/CPAN package,
with an example :
01: ################################################################################ 02: # 03: # perl-foo-bar 04: # 05: ################################################################################ 06: 07: PERL_FOO_BAR_VERSION = 0.02 08: PERL_FOO_BAR_SOURCE = Foo-Bar-$(PERL_FOO_BAR_VERSION).tar.gz 09: PERL_FOO_BAR_SITE = $(BR2_CPAN_MIRROR)/authors/id/M/MO/MONGER 10: PERL_FOO_BAR_DEPENDENCIES = perl-strictures 11: PERL_FOO_BAR_LICENSE = Artistic or GPL-1.0+ 12: PERL_FOO_BAR_LICENSE_FILES = LICENSE 13: PERL_FOO_BAR_DISTNAME = Foo-Bar 14: 15: $(eval $(perl-package))
On line 7, we declare the version of the package.
On line 8 and 9, we declare the name of the tarball and the location of the tarball on a CPAN server. Buildroot will automatically download the tarball from this location.
On line 10, we declare our dependencies, so that they are built before the build process of our package starts.
On line 11 and 12, we give licensing details about the package (its license on line 11, and the file containing the license text on line 12).
On line 13, the name of the distribution as needed by the script
utils/scancpan
(in order to regenerate/upgrade these package files).
Finally, on line 15, we invoke the perl-package
macro that
generates all the Makefile rules that actually allow the package to be
built.
Most of these data can be retrieved from https://metacpan.org/.
So, this file and the Config.in can be generated by running
the script utils/scancpan Foo-Bar
in the Buildroot directory
(or in a br2-external tree).
This script creates a Config.in file and foo-bar.mk file for the
requested package, and also recursively for all dependencies specified by
CPAN. You should still manually edit the result. In particular, the
following things should be checked.
-
If the perl module links with a shared library that is provided by another (non-perl) package, this dependency is not added automatically. It has to be added manually to
PERL_FOO_BAR_DEPENDENCIES
. -
The
package/Config.in
file has to be updated manually to include the generated Config.in files. As a hint, thescancpan
script prints out the requiredsource "…"
statements, sorted alphabetically.
perl-package
reference
As a policy, packages that provide Perl/CPAN modules should all be
named perl-<something>
in Buildroot.
This infrastructure handles various Perl build systems :
ExtUtils-MakeMaker
(EUMM), Module-Build
(MB) and Module-Build-Tiny
.
Build.PL
is preferred by default when a package provides a Makefile.PL
and a Build.PL
.
The main macro of the Perl/CPAN package infrastructure is
perl-package
. It is similar to the generic-package
macro. The ability to
have target and host packages is also available, with the
host-perl-package
macro.
Just like the generic infrastructure, the Perl/CPAN infrastructure
works by defining a number of variables before calling the
perl-package
macro.
First, all the package metadata information variables that exist in the
generic infrastructure also exist in the Perl/CPAN infrastructure:
PERL_FOO_VERSION
, PERL_FOO_SOURCE
,
PERL_FOO_PATCH
, PERL_FOO_SITE
,
PERL_FOO_SUBDIR
, PERL_FOO_DEPENDENCIES
,
PERL_FOO_INSTALL_TARGET
.
Note that setting PERL_FOO_INSTALL_STAGING
to YES
has no effect
unless a PERL_FOO_INSTALL_STAGING_CMDS
variable is defined. The perl
infrastructure doesn’t define these commands since Perl modules generally
don’t need to be installed to the staging
directory.
A few additional variables, specific to the Perl/CPAN infrastructure, can also be defined. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them.
-
PERL_FOO_PREFER_INSTALLER
/HOST_PERL_FOO_PREFER_INSTALLER
, specifies the preferred installation method. Possible values areEUMM
(forMakefile.PL
based installation usingExtUtils-MakeMaker
) andMB
(forBuild.PL
based installation usingModule-Build
). This variable is only used when the package provides both installation methods. -
PERL_FOO_CONF_ENV
/HOST_PERL_FOO_CONF_ENV
, to specify additional environment variables to pass to theperl Makefile.PL
orperl Build.PL
. By default, empty. -
PERL_FOO_CONF_OPTS
/HOST_PERL_FOO_CONF_OPTS
, to specify additional configure options to pass to theperl Makefile.PL
orperl Build.PL
. By default, empty. -
PERL_FOO_BUILD_OPTS
/HOST_PERL_FOO_BUILD_OPTS
, to specify additional options to pass tomake pure_all
orperl Build build
in the build step. By default, empty. -
PERL_FOO_INSTALL_TARGET_OPTS
, to specify additional options to pass tomake pure_install
orperl Build install
in the install step. By default, empty. -
HOST_PERL_FOO_INSTALL_OPTS
, to specify additional options to pass tomake pure_install
orperl Build install
in the install step. By default, empty.
Infrastructure for virtual packages
In Buildroot, a virtual package is a package whose functionalities are provided by one or more packages, referred to as 'providers'. The virtual package management is an extensible mechanism allowing the user to choose the provider used in the rootfs.
For example, 'OpenGL ES' is an API for 2D and 3D graphics on embedded systems.
The implementation of this API is different for the 'Allwinner Tech Sunxi' and
the 'Texas Instruments OMAP35xx' platforms. So libgles
will be a virtual
package and sunxi-mali-utgard
and ti-gfx
will be the providers.
virtual-package
tutorial
In the following example, we will explain how to add a new virtual package ('something-virtual') and a provider for it ('some-provider').
First, let’s create the virtual package.
Virtual package’s Config.in
file
The Config.in
file of virtual package 'something-virtual' should contain:
01: config BR2_PACKAGE_HAS_SOMETHING_VIRTUAL 02: bool 03: 04: config BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL 05: depends on BR2_PACKAGE_HAS_SOMETHING_VIRTUAL 06: string
In this file, we declare two options, BR2_PACKAGE_HAS_SOMETHING_VIRTUAL
and
BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL
, whose values will be used by the
providers.
Virtual package’s .mk
file
The .mk
for the virtual package should just evaluate the virtual-package
macro:
01: ################################################################################ 02: # 03: # something-virtual 04: # 05: ################################################################################ 06: 07: $(eval $(virtual-package))
The ability to have target and host packages is also available, with the
host-virtual-package
macro.
Provider’s Config.in
file
When adding a package as a provider, only the Config.in
file requires some
modifications.
The Config.in
file of the package 'some-provider', which provides the
functionalities of 'something-virtual', should contain:
01: config BR2_PACKAGE_SOME_PROVIDER 02: bool "some-provider" 03: select BR2_PACKAGE_HAS_SOMETHING_VIRTUAL 04: help 05: This is a comment that explains what some-provider is. 06: 07: http://foosoftware.org/some-provider/ 08: 09: if BR2_PACKAGE_SOME_PROVIDER 10: config BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL 11: default "some-provider" 12: endif
On line 3, we select BR2_PACKAGE_HAS_SOMETHING_VIRTUAL
, and on line 11, we
set the value of BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL
to the name of the
provider, but only if it is selected.
Provider’s .mk
file
The .mk
file should also declare an additional variable
SOME_PROVIDER_PROVIDES
to contain the names of all the virtual
packages it is an implementation of:
01: SOME_PROVIDER_PROVIDES = something-virtual
Of course, do not forget to add the proper build and runtime dependencies for this package!
Notes on depending on a virtual package
When adding a package that requires a certain FEATURE
provided by a virtual
package, you have to use depends on BR2_PACKAGE_HAS_FEATURE
, like so:
config BR2_PACKAGE_HAS_FEATURE bool config BR2_PACKAGE_FOO bool "foo" depends on BR2_PACKAGE_HAS_FEATURE
Notes on depending on a specific provider
If your package really requires a specific provider, then you’ll have to
make your package depends on
this provider; you can not select
a
provider.
Let’s take an example with two providers for a FEATURE
:
config BR2_PACKAGE_HAS_FEATURE bool config BR2_PACKAGE_FOO bool "foo" select BR2_PACKAGE_HAS_FEATURE config BR2_PACKAGE_BAR bool "bar" select BR2_PACKAGE_HAS_FEATURE
And you are adding a package that needs FEATURE
as provided by foo
,
but not as provided by bar
.
If you were to use select BR2_PACKAGE_FOO
, then the user would still
be able to select BR2_PACKAGE_BAR
in the menuconfig. This would create
a configuration inconsistency, whereby two providers of the same FEATURE
would be enabled at once, one explicitly set by the user, the other
implicitly by your select
.
Instead, you have to use depends on BR2_PACKAGE_FOO
, which avoids any
implicit configuration inconsistency.
Infrastructure for packages using kconfig for configuration files
A popular way for a software package to handle user-specified
configuration is kconfig
. Among others, it is used by the Linux
kernel, Busybox, and Buildroot itself. The presence of a .config file
and a menuconfig
target are two well-known symptoms of kconfig being
used.
Buildroot features an infrastructure for packages that use kconfig for
their configuration. This infrastructure provides the necessary logic to
expose the package’s menuconfig
target as foo-menuconfig
in
Buildroot, and to handle the copying back and forth of the configuration
file in a correct way.
The kconfig-package
infrastructure is based on the generic-package
infrastructure. All variables supported by generic-package
are
available in kconfig-package
as well. See
generic-package
reference for more details.
In order to use the kconfig-package
infrastructure for a Buildroot
package, the minimally required lines in the .mk
file, in addition to
the variables required by the generic-package
infrastructure, are:
FOO_KCONFIG_FILE = reference-to-source-configuration-file $(eval $(kconfig-package))
This snippet creates the following make targets:
-
foo-menuconfig
, which calls the package’smenuconfig
target -
foo-update-config
, which copies the configuration back to the source configuration file. It is not possible to use this target when fragment files are set. -
foo-update-defconfig
, which copies the configuration back to the source configuration file. The configuration file will only list the options that differ from the default values. It is not possible to use this target when fragment files are set. -
foo-diff-config
, which outputs the differences between the current configuration and the one defined in the Buildroot configuration for this kconfig package. The output is useful to identify the configuration changes that may have to be propagated to configuration fragments for example.
and ensures that the source configuration file is copied to the build directory at the right moment.
There are two options to specify a configuration file to use, either
FOO_KCONFIG_FILE
(as in the example, above) or FOO_KCONFIG_DEFCONFIG
.
It is mandatory to provide either, but not both:
-
FOO_KCONFIG_FILE
specifies the path to a defconfig or full-config file to be used to configure the package. -
FOO_KCONFIG_DEFCONFIG
specifies the defconfig 'make' rule to call to configure the package.
In addition to these minimally required lines, several optional variables can be set to suit the needs of the package under consideration:
-
FOO_KCONFIG_EDITORS
: a space-separated list of kconfig editors to support, for example 'menuconfig xconfig'. By default, 'menuconfig'. -
FOO_KCONFIG_FRAGMENT_FILES
: a space-separated list of configuration fragment files that are merged to the main configuration file. Fragment files are typically used when there is a desire to stay in sync with an upstream (def)config file, with some minor modifications. -
FOO_KCONFIG_OPTS
: extra options to pass when calling the kconfig editors. This may need to include '$(FOO_MAKE_OPTS)', for example. By default, empty. -
FOO_KCONFIG_FIXUP_CMDS
: a list of shell commands needed to fixup the configuration file after copying it or running a kconfig editor. Such commands may be needed to ensure a configuration consistent with other configuration of Buildroot, for example. By default, empty. -
FOO_KCONFIG_DOTCONFIG
: path (with filename) of the.config
file, relative to the package source tree. The default,.config
, should be well suited for all packages that use the standard kconfig infrastructure as inherited from the Linux kernel; some packages use a derivative of kconfig that use a different location. -
FOO_KCONFIG_DEPENDENCIES
: the list of packages (most probably, host packages) that need to be built before this package’s kconfig is interpreted. Seldom used. By default, empty. -
FOO_KCONFIG_SUPPORTS_DEFCONFIG
: whether the package’s kconfig system supports using defconfig files; few packages do not. By default, 'YES'.
Infrastructure for rebar-based packages
rebar-package
tutorial
First, let’s see how to write a .mk
file for a rebar-based package,
with an example :
01: ################################################################################ 02: # 03: # erlang-foobar 04: # 05: ################################################################################ 06: 07: ERLANG_FOOBAR_VERSION = 1.0 08: ERLANG_FOOBAR_SOURCE = erlang-foobar-$(ERLANG_FOOBAR_VERSION).tar.xz 09: ERLANG_FOOBAR_SITE = http://www.foosoftware.org/download 10: ERLANG_FOOBAR_DEPENDENCIES = host-libaaa libbbb 11: 12: $(eval $(rebar-package)) -------------------------------- On line 7, we declare the version of the package. On line 8 and 9, we declare the name of the tarball (xz-ed tarball recommended) and the location of the tarball on the Web. Buildroot will automatically download the tarball from this location. On line 10, we declare our dependencies, so that they are built before the build process of our package starts. Finally, on line 12, we invoke the `rebar-package` macro that generates all the Makefile rules that actually allows the package to be built. [[rebar-package-reference]] ==== `rebar-package` reference The main macro of the `rebar` package infrastructure is `rebar-package`. It is similar to the `generic-package` macro. The ability to have host packages is also available, with the `host-rebar-package` macro. Just like the generic infrastructure, the `rebar` infrastructure works by defining a number of variables before calling the `rebar-package` macro. First, all the package metadata information variables that exist in the generic infrastructure also exist in the `rebar` infrastructure: `ERLANG_FOOBAR_VERSION`, `ERLANG_FOOBAR_SOURCE`, `ERLANG_FOOBAR_PATCH`, `ERLANG_FOOBAR_SITE`, `ERLANG_FOOBAR_SUBDIR`, `ERLANG_FOOBAR_DEPENDENCIES`, `ERLANG_FOOBAR_INSTALL_STAGING`, `ERLANG_FOOBAR_INSTALL_TARGET`, `ERLANG_FOOBAR_LICENSE` and `ERLANG_FOOBAR_LICENSE_FILES`. A few additional variables, specific to the `rebar` infrastructure, can also be defined. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them. * `ERLANG_FOOBAR_USE_AUTOCONF`, to specify that the package uses _autoconf_ at the configuration step. When a package sets this variable to `YES`, the `autotools` infrastructure is used. + .Note You can also use some of the variables from the `autotools` infrastructure: `ERLANG_FOOBAR_CONF_ENV`, `ERLANG_FOOBAR_CONF_OPTS`, `ERLANG_FOOBAR_AUTORECONF`, `ERLANG_FOOBAR_AUTORECONF_ENV` and `ERLANG_FOOBAR_AUTORECONF_OPTS`. * `ERLANG_FOOBAR_USE_BUNDLED_REBAR`, to specify that the package has a bundled version of _rebar_ *and* that it shall be used. Valid values are `YES` or `NO` (the default). + .Note If the package bundles a _rebar_ utility, but can use the generic one that Buildroot provides, just say `NO` (i.e., do not specify this variable). Only set if it is mandatory to use the _rebar_ utility bundled in this package. * `ERLANG_FOOBAR_REBAR_ENV`, to specify additional environment variables to pass to the _rebar_ utility. * `ERLANG_FOOBAR_KEEP_DEPENDENCIES`, to keep the dependencies described in the rebar.config file. Valid values are `YES` or `NO` (the default). Unless this variable is set to `YES`, the _rebar_ infrastructure removes such dependencies in a post-patch hook to ensure rebar does not download nor compile them. With the rebar infrastructure, all the steps required to build and install the packages are already defined, and they generally work well for most rebar-based packages. However, when required, it is still possible to customize what is done in any particular step: * By adding a post-operation hook (after extract, patch, configure, build or install). See xref:hooks[] for details. * By overriding one of the steps. For example, even if the rebar infrastructure is used, if the package `.mk` file defines its own `ERLANG_FOOBAR_BUILD_CMDS` variable, it will be used instead of the default rebar one. However, using this method should be restricted to very specific cases. Do not use it in the general case. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Infrastructure for Waf-based packages [[waf-package-tutorial]] ==== `waf-package` tutorial First, let's see how to write a `.mk` file for a Waf-based package, with an example : ------------------------ 01: ################################################################################ 02: # 03: # libfoo 04: # 05: ################################################################################ 06: 07: LIBFOO_VERSION = 1.0 08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz 09: LIBFOO_SITE = http://www.foosoftware.org/download 10: LIBFOO_CONF_OPTS = --enable-bar --disable-baz 11: LIBFOO_DEPENDENCIES = bar 12: 13: $(eval $(waf-package)) ------------------------ On line 7, we declare the version of the package. On line 8 and 9, we declare the name of the tarball (xz-ed tarball recommended) and the location of the tarball on the Web. Buildroot will automatically download the tarball from this location. On line 10, we tell Buildroot what options to enable for libfoo. On line 11, we tell Buildroot the dependencies of libfoo. Finally, on line line 13, we invoke the `waf-package` macro that generates all the Makefile rules that actually allows the package to be built. [[waf-package-reference]] ==== `waf-package` reference The main macro of the Waf package infrastructure is `waf-package`. It is similar to the `generic-package` macro. Just like the generic infrastructure, the Waf infrastructure works by defining a number of variables before calling the `waf-package` macro. First, all the package metadata information variables that exist in the generic infrastructure also exist in the Waf infrastructure: `LIBFOO_VERSION`, `LIBFOO_SOURCE`, `LIBFOO_PATCH`, `LIBFOO_SITE`, `LIBFOO_SUBDIR`, `LIBFOO_DEPENDENCIES`, `LIBFOO_INSTALL_STAGING`, `LIBFOO_INSTALL_TARGET`. An additional variable, specific to the Waf infrastructure, can also be defined. * `LIBFOO_SUBDIR` may contain the name of a subdirectory inside the package that contains the main wscript file. This is useful, if for example, the main wscript file is not at the root of the tree extracted by the tarball. If `HOST_LIBFOO_SUBDIR` is not specified, it defaults to `LIBFOO_SUBDIR`. * `LIBFOO_NEEDS_EXTERNAL_WAF` can be set to `YES` or `NO` to tell Buildroot to use the bundled `waf` executable. If set to `NO`, the default, then Buildroot will use the waf executable provided in the package source tree; if set to `YES`, then Buildroot will download, install waf as a host tool and use it to build the package. * `LIBFOO_WAF_OPTS`, to specify additional options to pass to the `waf` script at every step of the package build process: configure, build and installation. By default, empty. * `LIBFOO_CONF_OPTS`, to specify additional options to pass to the `waf` script for the configuration step. By default, empty. * `LIBFOO_BUILD_OPTS`, to specify additional options to pass to the `waf` script during the build step. By default, empty. * `LIBFOO_INSTALL_STAGING_OPTS`, to specify additional options to pass to the `waf` script during the staging installation step. By default, empty. * `LIBFOO_INSTALL_TARGET_OPTS`, to specify additional options to pass to the `waf` script during the target installation step. By default, empty. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Infrastructure for Meson-based packages [[meson-package-tutorial]] ==== `meson-package` tutorial http://mesonbuild.com[Meson] is an open source build system meant to be both extremely fast, and, even more importantly, as user friendly as possible. It uses https://ninja-build.org[Ninja] as a companion tool to perform the actual build operations. Let's see how to write a `.mk` file for a Meson-based package, with an example:
01: 02: # 03: # foo 04: # 05: 06: 07: FOO_VERSION = 1.0 08: FOO_SOURCE = foo-$(FOO_VERSION).tar.gz 09: FOO_SITE = http://www.foosoftware.org/download 10: FOO_LICENSE = GPL-3.0+ 11: FOO_LICENSE_FILES = COPYING 12: FOO_INSTALL_STAGING = YES 13: 14: FOO_DEPENDENCIES = host-pkgconf bar 15: 16: ifeq ($(BR2_PACKAGE_BAZ),y) 17: FOO_CONF_OPTS += -Dbaz=true 18: FOO_DEPENDENCIES += baz 19: else 20: FOO_CONF_OPTS += -Dbaz=false 21: endif 22: 23: $(eval $(meson-package))
The Makefile starts with the definition of the standard variables for package declaration (lines 7 to 11). On line line 23, we invoke the `meson-package` macro that generates all the Makefile rules that actually allows the package to be built. In the example, `host-pkgconf` and `bar` are declared as dependencies in `FOO_DEPENDENCIES` at line 14 because the Meson build file of `foo` uses `pkg-config` to determine the compilation flags and libraries of package `bar`. Note that it is not necessary to add `host-meson` in the `FOO_DEPENDENCIES` variable of a package, since this basic dependency is automatically added as needed by the Meson package infrastructure. If the "baz" package is selected, then support for the "baz" feature in "foo" is activated by adding `-Dbaz=true` to `FOO_CONF_OPTS` at line 17, as specified in the `meson_options.adoc` file in "foo" source tree. The "baz" package is also added to `FOO_DEPENDENCIES`. Note that the support for `baz` is explicitly disabled at line 20, if the package is not selected. To sum it up, to add a new meson-based package, the Makefile example can be copied verbatim then edited to replace all occurences of `FOO` with the uppercase name of the new package and update the values of the standard variables. [[meson-package-reference]] ==== `meson-package` reference The main macro of the Meson package infrastructure is `meson-package`. It is similar to the `generic-package` macro. The ability to have target and host packages is also available, with the `host-meson-package` macro. Just like the generic infrastructure, the Meson infrastructure works by defining a number of variables before calling the `meson-package` macro. First, all the package metadata information variables that exist in the generic infrastructure also exist in the Meson infrastructure: `FOO_VERSION`, `FOO_SOURCE`, `FOO_PATCH`, `FOO_SITE`, `FOO_SUBDIR`, `FOO_DEPENDENCIES`, `FOO_INSTALL_STAGING`, `FOO_INSTALL_TARGET`. A few additional variables, specific to the Meson infrastructure, can also be defined. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them. * `FOO_SUBDIR` may contain the name of a subdirectory inside the package that contains the main meson.build file. This is useful, if for example, the main meson.build file is not at the root of the tree extracted by the tarball. If `HOST_FOO_SUBDIR` is not specified, it defaults to `FOO_SUBDIR`. * `FOO_CONF_ENV`, to specify additional environment variables to pass to `meson` for the configuration step. By default, empty. * `FOO_CONF_OPTS`, to specify additional options to pass to `meson` for the configuration step. By default, empty. * `FOO_CFLAGS`, to specify compiler arguments added to the package specific `cross-compile.conf` file `c_args` property. By default, the value of `TARGET_CFLAGS`. * `FOO_CXXFLAGS`, to specify compiler arguments added to the package specific `cross-compile.conf` file `cpp_args` property. By default, the value of `TARGET_CXXFLAGS`. * `FOO_LDFLAGS`, to specify compiler arguments added to the package specific `cross-compile.conf` file `c_link_args` and `cpp_link_args` properties. By default, the value of `TARGET_LDFLAGS`. * `FOO_MESON_EXTRA_BINARIES`, to specify a space-separated list of programs to add to the `[binaries]` section of the meson `cross-compilation.conf` configuration file. The format is `program-name='/path/to/program'`, with no space around the `=` sign, and with the path of the program between single quotes. By default, empty. Note that Buildroot already sets the correct values for `c`, `cpp`, `ar`, `strip`, and `pkgconfig`. * `FOO_MESON_EXTRA_PROPERTIES`, to specify a space-separated list of properties to add to the `[properties]` section of the meson `cross-compilation.conf` configuration file. The format is `property-name=<value>` with no space around the `=` sign, and with single quotes around string values. By default, empty. Note that Buildroot already sets values for `needs_exe_wrapper`, `c_args`, `c_link_args`, `cpp_args`, `cpp_link_args`, `sys_root`, and `pkg_config_libdir`. * `FOO_NINJA_ENV`, to specify additional environment variables to pass to `ninja`, meson companion tool in charge of the build operations. By default, empty. * `FOO_NINJA_OPTS`, to specify a space-separated list of targets to build. By default, empty, to build the default target(s). // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Infrastructure for Cargo-based packages Cargo is the package manager for the Rust programming language. It allows the user to build programs or libraries written in Rust, but it also downloads and manages their dependencies, to ensure repeatable builds. Cargo packages are called "crates". [[cargo-package-tutorial]] ==== `cargo-package` tutorial The `Config.in` file of Cargo-based package 'foo' should contain: --------------------------- 01: config BR2_PACKAGE_FOO 02: bool "foo" 03: depends on BR2_PACKAGE_HOST_RUSTC_TARGET_ARCH_SUPPORTS 04: select BR2_PACKAGE_HOST_RUSTC 05: help 06: This is a comment that explains what foo is. 07: 08: http://foosoftware.org/foo/ --------------------------- And the `.mk` file for this package should contain:
01: 02: # 03: # foo 04: # 05: 06: 07: FOO_VERSION = 1.0 08: FOO_SOURCE = foo-$(FOO_VERSION).tar.gz 09: FOO_SITE = http://www.foosoftware.org/download 10: FOO_LICENSE = GPL-3.0+ 11: FOO_LICENSE_FILES = COPYING 12: 13: $(eval $(cargo-package))
The Makefile starts with the definition of the standard variables for package declaration (lines 7 to 11). As seen in line 13, it is based on the `cargo-package` infrastructure. Cargo will be invoked automatically by this infrastructure to build and install the package. It is still possible to define custom build commands or install commands (i.e. with FOO_BUILD_CMDS and FOO_INSTALL_TARGET_CMDS). Those will then replace the commands from the cargo infrastructure. ==== `cargo-package` reference The main macros for the Cargo package infrastructure are `cargo-package` for target packages and `host-cargo-package` for host packages. Just like the generic infrastructure, the Cargo infrastructure works by defining a number of variables before calling the `cargo-package` or `host-cargo-package` macros. First, all the package metadata information variables that exist in the generic infrastructure also exist in the Cargo infrastructure: `FOO_VERSION`, `FOO_SOURCE`, `FOO_PATCH`, `FOO_SITE`, `FOO_DEPENDENCIES`, `FOO_LICENSE`, `FOO_LICENSE_FILES`, etc. A few additional variables, specific to the Cargo infrastructure, can also be defined. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them. * `FOO_SUBDIR` may contain the name of a subdirectory inside the package that contains the Cargo.toml file. This is useful, if for example, it is not at the root of the tree extracted by the tarball. If `HOST_FOO_SUBDIR` is not specified, it defaults to `FOO_SUBDIR`. * `FOO_CARGO_ENV` can be used to pass additional variables in the environment of `cargo` invocations. It used at both build and installation time * `FOO_CARGO_BUILD_OPTS` can be used to pass additional options to `cargo` at build time. * `FOO_CARGO_INSTALL_OPTS` can be used to pass additional options to `cargo` at install time. A crate can depend on other libraries from crates.io or git repositories, listed in its `Cargo.toml` file. Buildroot automatically takes care of downloading such dependencies as part of the download step of packages that use the `cargo-package` infrastructure. Such dependencies are then kept together with the package source code in the tarball cached in Buildroot's `DL_DIR`, and therefore the hash of the package's tarball includes such dependencies. This mechanism ensures that any change in the dependencies will be detected, and allows the build to be performed completely offline. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Infrastructure for Go packages This infrastructure applies to Go packages that use the standard build system and use bundled dependencies. [[golang-package-tutorial]] ==== `golang-package` tutorial First, let's see how to write a `.mk` file for a go package, with an example : ------------------------ 01: ################################################################################ 02: # 03: # foo 04: # 05: ################################################################################ 06: 07: FOO_VERSION = 1.0 08: FOO_SITE = $(call github,bar,foo,$(FOO_VERSION)) 09: FOO_LICENSE = BSD-3-Clause 10: FOO_LICENSE_FILES = LICENSE 11: 12: $(eval $(golang-package)) ------------------------ On line 7, we declare the version of the package. On line 8, we declare the upstream location of the package, here fetched from Github, since a large number of Go packages are hosted on Github. On line 9 and 10, we give licensing details about the package. Finally, on line 12, we invoke the `golang-package` macro that generates all the Makefile rules that actually allow the package to be built. [[golang-package-reference]] ==== `golang-package` reference In their `Config.in` file, packages using the `golang-package` infrastructure should depend on `BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS` because Buildroot will automatically add a dependency on `host-go` to such packages. If you need CGO support in your package, you must add a dependency on `BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS`. The main macro of the Go package infrastructure is `golang-package`. It is similar to the `generic-package` macro. The ability to build host packages is also available, with the `host-golang-package` macro. Host packages built by `host-golang-package` macro should depend on BR2_PACKAGE_HOST_GO_HOST_ARCH_SUPPORTS. Just like the generic infrastructure, the Go infrastructure works by defining a number of variables before calling the `golang-package`. All the package metadata information variables that exist in the xref:generic-package-reference[generic package infrastructure] also exist in the Go infrastructure: `FOO_VERSION`, `FOO_SOURCE`, `FOO_PATCH`, `FOO_SITE`, `FOO_SUBDIR`, `FOO_DEPENDENCIES`, `FOO_LICENSE`, `FOO_LICENSE_FILES`, `FOO_INSTALL_STAGING`, etc. Note that it is not necessary to add `host-go` in the `FOO_DEPENDENCIES` variable of a package, since this basic dependency is automatically added as needed by the Go package infrastructure. A few additional variables, specific to the Go infrastructure, can optionally be defined, depending on the package's needs. Many of them are only useful in very specific cases, typical packages will therefore only use a few of them, or none. * The package must specify its Go module name in the `FOO_GOMOD` variable. If not specified, it defaults to `URL-domain/1st-part-of-URL/2nd-part-of-URL`, e.g `FOO_GOMOD` will take the value `github.com/bar/foo` for a package that specifies `FOO_SITE = $(call github,bar,foo,$(FOO_VERSION))`. The Go package infrastructure will automatically generate a minimal `go.mod` file in the package source tree if it doesn't exist. * `FOO_LDFLAGS` and `FOO_TAGS` can be used to pass respectively the `LDFLAGS` or the `TAGS` to the `go` build command. * `FOO_BUILD_TARGETS` can be used to pass the list of targets that should be built. If `FOO_BUILD_TARGETS` is not specified, it defaults to `.`. We then have two cases: ** `FOO_BUILD_TARGETS` is `.`. In this case, we assume only one binary will be produced, and that by default we name it after the package name. If that is not appropriate, the name of the produced binary can be overridden using `FOO_BIN_NAME`. ** `FOO_BUILD_TARGETS` is not `.`. In this case, we iterate over the values to build each target, and for each produced a binary that is the non-directory component of the target. For example if `FOO_BUILD_TARGETS = cmd/docker cmd/dockerd` the binaries produced are `docker` and `dockerd`. * `FOO_INSTALL_BINS` can be used to pass the list of binaries that should be installed in `/usr/bin` on the target. If `FOO_INSTALL_BINS` is not specified, it defaults to the lower-case name of package. With the Go infrastructure, all the steps required to build and install the packages are already defined, and they generally work well for most Go-based packages. However, when required, it is still possible to customize what is done in any particular step: * By adding a post-operation hook (after extract, patch, configure, build or install). See xref:hooks[] for details. * By overriding one of the steps. For example, even if the Go infrastructure is used, if the package `.mk` file defines its own `FOO_BUILD_CMDS` variable, it will be used instead of the default Go one. However, using this method should be restricted to very specific cases. Do not use it in the general case. A Go package can depend on other Go modules, listed in its `go.mod` file. Buildroot automatically takes care of downloading such dependencies as part of the download step of packages that use the `golang-package` infrastructure. Such dependencies are then kept together with the package source code in the tarball cached in Buildroot's `DL_DIR`, and therefore the hash of the package's tarball includes such dependencies. This mechanism ensures that any change in the dependencies will be detected, and allows the build to be performed completely offline. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Infrastructure for QMake-based packages [[qmake-package-tutorial]] ==== `qmake-package` tutorial First, let's see how to write a `.mk` file for a QMake-based package, with an example : ------------------------ 01: ################################################################################ 02: # 03: # libfoo 04: # 05: ################################################################################ 06: 07: LIBFOO_VERSION = 1.0 08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz 09: LIBFOO_SITE = http://www.foosoftware.org/download 10: LIBFOO_CONF_OPTS = QT_CONFIG+=bar QT_CONFIG-=baz 11: LIBFOO_DEPENDENCIES = bar 12: 13: $(eval $(qmake-package)) ------------------------ On line 7, we declare the version of the package. On line 8 and 9, we declare the name of the tarball (xz-ed tarball recommended) and the location of the tarball on the Web. Buildroot will automatically download the tarball from this location. On line 10, we tell Buildroot what options to enable for libfoo. On line 11, we tell Buildroot the dependencies of libfoo. Finally, on line line 13, we invoke the `qmake-package` macro that generates all the Makefile rules that actually allows the package to be built. [[qmake-package-reference]] ==== `qmake-package` reference The main macro of the QMake package infrastructure is `qmake-package`. It is similar to the `generic-package` macro. Just like the generic infrastructure, the QMake infrastructure works by defining a number of variables before calling the `qmake-package` macro. First, all the package metadata information variables that exist in the generic infrastructure also exist in the QMake infrastructure: `LIBFOO_VERSION`, `LIBFOO_SOURCE`, `LIBFOO_PATCH`, `LIBFOO_SITE`, `LIBFOO_SUBDIR`, `LIBFOO_DEPENDENCIES`, `LIBFOO_INSTALL_STAGING`, `LIBFOO_INSTALL_TARGET`. An additional variable, specific to the QMake infrastructure, can also be defined. * `LIBFOO_CONF_ENV`, to specify additional environment variables to pass to the `qmake` script for the configuration step. By default, empty. * `LIBFOO_CONF_OPTS`, to specify additional options to pass to the `qmake` script for the configuration step. By default, empty. * `LIBFOO_MAKE_ENV`, to specify additional environment variables to the `make` command during the build and install steps. By default, empty. * `LIBFOO_MAKE_OPTS`, to specify additional targets to pass to the `make` command during the build step. By default, empty. * `LIBFOO_INSTALL_STAGING_OPTS`, to specify additional targets to pass to the `make` command during the staging installation step. By default, `install`. * `LIBFOO_INSTALL_TARGET_OPTS`, to specify additional targets to pass to the `make` command during the target installation step. By default, `install`. * `LIBFOO_SYNC_QT_HEADERS`, to run syncqt.pl before qmake. Some packages need this to have a properly populated include directory before running the build. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Infrastructure for packages building kernel modules Buildroot offers a helper infrastructure to make it easy to write packages that build and install Linux kernel modules. Some packages only contain a kernel module, other packages contain programs and libraries in addition to kernel modules. Buildroot's helper infrastructure supports either case. [[kernel-module-tutorial]] ==== `kernel-module` tutorial Let's start with an example on how to prepare a simple package that only builds a kernel module, and no other component: ---- 01: ################################################################################ 02: # 03: # foo 04: # 05: ################################################################################ 06: 07: FOO_VERSION = 1.2.3 08: FOO_SOURCE = foo-$(FOO_VERSION).tar.xz 09: FOO_SITE = http://www.foosoftware.org/download 10: FOO_LICENSE = GPL-2.0 11: FOO_LICENSE_FILES = COPYING 12: 13: $(eval $(kernel-module)) 14: $(eval $(generic-package)) ---- Lines 7-11 define the usual meta-data to specify the version, archive name, remote URI where to find the package source, licensing information. On line 13, we invoke the `kernel-module` helper infrastructure, that generates all the appropriate Makefile rules and variables to build that kernel module. Finally, on line 14, we invoke the xref:generic-package-tutorial[`generic-package` infrastructure]. The dependency on `linux` is automatically added, so it is not needed to specify it in `FOO_DEPENDENCIES`. What you may have noticed is that, unlike other package infrastructures, we explicitly invoke a second infrastructure. This allows a package to build a kernel module, but also, if needed, use any one of other package infrastructures to build normal userland components (libraries, executables...). Using the `kernel-module` infrastructure on its own is not sufficient; another package infrastructure *must* be used. Let's look at a more complex example: ---- 01: ################################################################################ 02: # 03: # foo 04: # 05: ################################################################################ 06: 07: FOO_VERSION = 1.2.3 08: FOO_SOURCE = foo-$(FOO_VERSION).tar.xz 09: FOO_SITE = http://www.foosoftware.org/download 10: FOO_LICENSE = GPL-2.0 11: FOO_LICENSE_FILES = COPYING 12: 13: FOO_MODULE_SUBDIRS = driver/base 14: FOO_MODULE_MAKE_OPTS = KVERSION=$(LINUX_VERSION_PROBED) 15: 16: ifeq ($(BR2_PACKAGE_LIBBAR),y) 17: FOO_DEPENDENCIES += libbar 18: FOO_CONF_OPTS += --enable-bar 19: FOO_MODULE_SUBDIRS += driver/bar 20: else 21: FOO_CONF_OPTS += --disable-bar 22: endif 23: 24: $(eval $(kernel-module)) 26: $(eval $(autotools-package)) ---- Here, we see that we have an autotools-based package, that also builds the kernel module located in sub-directory `driver/base` and, if libbar is enabled, the kernel module located in sub-directory `driver/bar`, and defines the variable `KVERSION` to be passed to the Linux buildsystem when building the module(s). [[kernel-module-reference]] ==== `kernel-module` reference The main macro for the kernel module infrastructure is `kernel-module`. Unlike other package infrastructures, it is not stand-alone, and requires any of the other `*-package` macros be called after it. The `kernel-module` macro defines post-build and post-target-install hooks to build the kernel modules. If the package's `.mk` needs access to the built kernel modules, it should do so in a post-build hook, *registered after* the call to `kernel-module`. Similarly, if the package's `.mk` needs access to the kernel module after it has been installed, it should do so in a post-install hook, *registered after* the call to `kernel-module`. Here's an example: ---- $(eval $(kernel-module)) define FOO_DO_STUFF_WITH_KERNEL_MODULE # Do something with it... endef FOO_POST_BUILD_HOOKS += FOO_DO_STUFF_WITH_KERNEL_MODULE $(eval $(generic-package)) ---- Finally, unlike the other package infrastructures, there is no `host-kernel-module` variant to build a host kernel module. The following additional variables can optionally be defined to further configure the build of the kernel module: * `FOO_MODULE_SUBDIRS` may be set to one or more sub-directories (relative to the package source top-directory) where the kernel module sources are. If empty or not set, the sources for the kernel module(s) are considered to be located at the top of the package source tree. * `FOO_MODULE_MAKE_OPTS` may be set to contain extra variable definitions to pass to the Linux buildsystem. [[kernel-variables]] You may also reference (but you may *not* set!) those variables: * `LINUX_DIR` contains the path to where the Linux kernel has been extracted and built. * `LINUX_VERSION` contains the version string as configured by the user. * `LINUX_VERSION_PROBED` contains the real version string of the kernel, retrieved with running `make -C $(LINUX_DIR) kernelrelease` * `KERNEL_ARCH` contains the name of the current architecture, like `arm`, `mips`... // -*- mode:doc; -*- // vim: syntax=asciidoc === Infrastructure for asciidoc documents [[asciidoc-documents-tutorial]] The Buildroot manual, which you are currently reading, is entirely written using the http://asciidoc.org/[AsciiDoc] mark-up syntax. The manual is then rendered to many formats: * html * split-html * pdf * epub * text Although Buildroot only contains one document written in AsciiDoc, there is, as for packages, an infrastructure for rendering documents using the AsciiDoc syntax. Also as for packages, the AsciiDoc infrastructure is available from a xref:outside-br-custom[br2-external tree]. This allows documentation for a br2-external tree to match the Buildroot documentation, as it will be rendered to the same formats and use the same layout and theme. ==== `asciidoc-document` tutorial Whereas package infrastructures are suffixed with `-package`, the document infrastructures are suffixed with `-document`. So, the AsciiDoc infrastructure is named `asciidoc-document`. Here is an example to render a simple AsciiDoc document. ---- 01: ################################################################################ 02: # 03: # foo-document 04: # 05: ################################################################################ 06: 07: FOO_SOURCES = $(sort $(wildcard $(FOO_DOCDIR)/*)) 08: $(eval $(call asciidoc-document)) ---- On line 7, the Makefile declares what the sources of the document are. Currently, it is expected that the document's sources are only local; Buildroot will not attempt to download anything to render a document. Thus, you must indicate where the sources are. Usually, the string above is sufficient for a document with no sub-directory structure. On line 8, we call the `asciidoc-document` function, which generates all the Makefile code necessary to render the document. ==== `asciidoc-document` reference The list of variables that can be set in a `.mk` file to give metadata information is (assuming the document name is `foo`) : * `FOO_SOURCES`, mandatory, defines the source files for the document. * `FOO_RESOURCES`, optional, may contain a space-separated list of paths to one or more directories containing so-called resources (like CSS or images). By default, empty. * `FOO_DEPENDENCIES`, optional, the list of packages (most probably, host-packages) that must be built before building this document. There are also additional hooks (see xref:hooks[] for general information on hooks), that a document may set to define extra actions to be done at various steps: * `FOO_POST_RSYNC_HOOKS` to run additional commands after the sources have been copied by Buildroot. This can for example be used to generate part of the manual with information extracted from the tree. As an example, Buildroot uses this hook to generate the tables in the appendices. * `FOO_CHECK_DEPENDENCIES_HOOKS` to run additional tests on required components to generate the document. In AsciiDoc, it is possible to call filters, that is, programs that will parse an AsciiDoc block and render it appropriately (e.g. http://ditaa.sourceforge.net/[ditaa] or https://pythonhosted.org/aafigure/[aafigure]). * `FOO_CHECK_DEPENDENCIES_<FMT>_HOOKS`, to run additional tests for the specified format `<FMT>` (see the list of rendered formats, above). Buildroot sets the following variable that can be used in the definitions above: * `$(FOO_DOCDIR)`, similar to `$(FOO_PKGDIR)`, contains the path to the directory containing `foo.mk`. It can be used to refer to the document sources, and can be used in the hooks, especially the post-rsync hook if parts of the documentation needs to be generated. * `$(@D)`, as for traditional packages, contains the path to the directory where the document will be copied and built. Here is a complete example that uses all variables and all hooks: ---- 01: ################################################################################ 02: # 03: # foo-document 04: # 05: ################################################################################ 06: 07: FOO_SOURCES = $(sort $(wildcard $(FOO_DOCDIR)/*)) 08: FOO_RESOURCES = $(sort $(wildcard $(FOO_DOCDIR)/ressources)) 09: 10: define FOO_GEN_EXTRA_DOC 11: /path/to/generate-script --outdir=$(@D) 12: endef 13: FOO_POST_RSYNC_HOOKS += FOO_GEN_EXTRA_DOC 14: 15: define FOO_CHECK_MY_PROG 16: if ! which my-prog >/dev/null 2>&1; then \ 17: echo "You need my-prog to generate the foo document"; \ 18: exit 1; \ 19: fi 20: endef 21: FOO_CHECK_DEPENDENCIES_HOOKS += FOO_CHECK_MY_PROG 22: 23: define FOO_CHECK_MY_OTHER_PROG 24: if ! which my-other-prog >/dev/null 2>&1; then \ 25: echo "You need my-other-prog to generate the foo document as PDF"; \ 26: exit 1; \ 27: fi 28: endef 29: FOO_CHECK_DEPENDENCIES_PDF_HOOKS += FOO_CHECK_MY_OTHER_PROG 30: 31: $(eval $(call asciidoc-document)) ---- // -*- mode:doc; -*- // vim: set syntax=asciidoc: [[linux-kernel-specific-infra]] === Infrastructure specific to the Linux kernel package The Linux kernel package can use some specific infrastructures based on package hooks for building Linux kernel tools or/and building Linux kernel extensions. [[linux-kernel-tools]] ==== linux-kernel-tools Buildroot offers a helper infrastructure to build some userspace tools for the target available within the Linux kernel sources. Since their source code is part of the kernel source code, a special package, `linux-tools`, exists and re-uses the sources of the Linux kernel that runs on the target. Let's look at an example of a Linux tool. For a new Linux tool named `foo`, create a new menu entry in the existing `package/linux-tools/Config.in`. This file will contain the option descriptions related to each kernel tool that will be used and displayed in the configuration tool. It would basically look like:
01: config BR2_PACKAGE_LINUX_TOOLS_FOO 02: bool "foo" 03: select BR2_PACKAGE_LINUX_TOOLS 04: help 05: This is a comment that explains what foo kernel tool is. 06: 07: http://foosoftware.org/foo/
The name of the option starts with the prefix `BR2_PACKAGE_LINUX_TOOLS_`, followed by the uppercase name of the tool (like is done for packages). .Note Unlike other packages, the `linux-tools` package options appear in the `linux` kernel menu, under the `Linux Kernel Tools` sub-menu, not under the `Target packages` main menu. Then for each linux tool, add a new `.mk.in` file named `package/linux-tools/linux-tool-foo.mk.in`. It would basically look like:
01: 02: # 03: # foo 04: # 05: 06: 07: LINUX_TOOLS += foo 08: 09: FOO_DEPENDENCIES = libbbb 10: 11: define FOO_BUILD_CMDS 12: $(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools foo 13: endef 14: 15: define FOO_INSTALL_STAGING_CMDS 16: $(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools \ 17: DESTDIR=$(STAGING_DIR) \ 18: foo_install 19: endef 20: 21: define FOO_INSTALL_TARGET_CMDS 22: $(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools \ 23: DESTDIR=$(TARGET_DIR) \ 24: foo_install 25: endef
On line 7, we register the Linux tool `foo` to the list of available Linux tools. On line 9, we specify the list of dependencies this tool relies on. These dependencies are added to the Linux package dependencies list only when the `foo` tool is selected. The rest of the Makefile, lines 11-25 defines what should be done at the different steps of the Linux tool build process like for a xref:generic-package-tutorial[`generic package`]. They will actually be used only when the `foo` tool is selected. The only supported commands are `_BUILD_CMDS`, `_INSTALL_STAGING_CMDS` and `_INSTALL_TARGET_CMDS`. .Note One *must not* call `$(eval $(generic-package))` or any other package infrastructure! Linux tools are not packages by themselves, they are part of the `linux-tools` package. [[linux-kernel-ext]] ==== linux-kernel-extensions Some packages provide new features that require the Linux kernel tree to be modified. This can be in the form of patches to be applied on the kernel tree, or in the form of new files to be added to the tree. The Buildroot's Linux kernel extensions infrastructure provides a simple solution to automatically do this, just after the kernel sources are extracted and before the kernel patches are applied. Examples of extensions packaged using this mechanism are the real-time extensions Xenomai and RTAI, as well as the set of out-of-tree LCD screens drivers `fbtft`. Let's look at an example on how to add a new Linux extension `foo`. First, create the package `foo` that provides the extension: this package is a standard package; see the previous chapters on how to create such a package. This package is in charge of downloading the sources archive, checking the hash, defining the licence informations and building user space tools if any. Then create the 'Linux extension' proper: create a new menu entry in the existing `linux/Config.ext.in`. This file contains the option descriptions related to each kernel extension that will be used and displayed in the configuration tool. It would basically look like:
01: config BR2_LINUX_KERNEL_EXT_FOO 02: bool "foo" 03: help 04: This is a comment that explains what foo kernel extension is. 05: 06: http://foosoftware.org/foo/
Then for each linux extension, add a new `.mk` file named `linux/linux-ext-foo.mk`. It should basically contain:
01: 02: # 03: # foo 04: # 05: 06: 07: LINUX_EXTENSIONS += foo 08: 09: define FOO_PREPARE_KERNEL 10: $(FOO_DIR)/prepare-kernel-tree.sh --linux-dir=$(@D) 11: endef
On line 7, we add the Linux extension `foo` to the list of available Linux extensions. On line 9-11, we define what should be done by the extension to modify the Linux kernel tree; this is specific to the linux extension and can use the variables defined by the `foo` package, like: `$(FOO_DIR)` or `$(FOO_VERSION)`... as well as all the Linux variables, like: `$(LINUX_VERSION)` or `$(LINUX_VERSION_PROBED)`, `$(KERNEL_ARCH)`... See the xref:kernel-variables[definition of those kernel variables]. // -*- mode:doc; -*- // vim: set syntax=asciidoc: [[hooks]] === Hooks available in the various build steps The generic infrastructure (and as a result also the derived autotools and cmake infrastructures) allow packages to specify hooks. These define further actions to perform after existing steps. Most hooks aren't really useful for generic packages, since the `.mk` file already has full control over the actions performed in each step of the package construction. The following hook points are available: * `LIBFOO_PRE_DOWNLOAD_HOOKS` * `LIBFOO_POST_DOWNLOAD_HOOKS` * `LIBFOO_PRE_EXTRACT_HOOKS` * `LIBFOO_POST_EXTRACT_HOOKS` * `LIBFOO_PRE_RSYNC_HOOKS` * `LIBFOO_POST_RSYNC_HOOKS` * `LIBFOO_PRE_PATCH_HOOKS` * `LIBFOO_POST_PATCH_HOOKS` * `LIBFOO_PRE_CONFIGURE_HOOKS` * `LIBFOO_POST_CONFIGURE_HOOKS` * `LIBFOO_PRE_BUILD_HOOKS` * `LIBFOO_POST_BUILD_HOOKS` * `LIBFOO_PRE_INSTALL_HOOKS` (for host packages only) * `LIBFOO_POST_INSTALL_HOOKS` (for host packages only) * `LIBFOO_PRE_INSTALL_STAGING_HOOKS` (for target packages only) * `LIBFOO_POST_INSTALL_STAGING_HOOKS` (for target packages only) * `LIBFOO_PRE_INSTALL_TARGET_HOOKS` (for target packages only) * `LIBFOO_POST_INSTALL_TARGET_HOOKS` (for target packages only) * `LIBFOO_PRE_INSTALL_IMAGES_HOOKS` * `LIBFOO_POST_INSTALL_IMAGES_HOOKS` * `LIBFOO_PRE_LEGAL_INFO_HOOKS` * `LIBFOO_POST_LEGAL_INFO_HOOKS` * `LIBFOO_TARGET_FINALIZE_HOOKS` These variables are 'lists' of variable names containing actions to be performed at this hook point. This allows several hooks to be registered at a given hook point. Here is an example: ---------------------- define LIBFOO_POST_PATCH_FIXUP action1 action2 endef LIBFOO_POST_PATCH_HOOKS += LIBFOO_POST_PATCH_FIXUP ---------------------- [[hooks-rsync]] ==== Using the `POST_RSYNC` hook The `POST_RSYNC` hook is run only for packages that use a local source, either through the `local` site method or the `OVERRIDE_SRCDIR` mechanism. In this case, package sources are copied using `rsync` from the local location into the buildroot build directory. The `rsync` command does not copy all files from the source directory, though. Files belonging to a version control system, like the directories `.git`, `.hg`, etc. are not copied. For most packages this is sufficient, but a given package can perform additional actions using the `POST_RSYNC` hook. In principle, the hook can contain any command you want. One specific use case, though, is the intentional copying of the version control directory using `rsync`. The `rsync` command you use in the hook can, among others, use the following variables: * `$(SRCDIR)`: the path to the overridden source directory * `$(@D)`: the path to the build directory ==== Target-finalize hook Packages may also register hooks in `LIBFOO_TARGET_FINALIZE_HOOKS`. These hooks are run after all packages are built, but before the filesystem images are generated. They are seldom used, and your package probably do not need them. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Gettext integration and interaction with packages Many packages that support internationalization use the gettext library. Dependencies for this library are fairly complicated and therefore, deserve some explanation. The 'glibc' C library integrates a full-blown implementation of 'gettext', supporting translation. Native Language Support is therefore built-in in 'glibc'. On the other hand, the 'uClibc' and 'musl' C libraries only provide a stub implementation of the gettext functionality, which allows to compile libraries and programs using gettext functions, but without providing the translation capabilities of a full-blown gettext implementation. With such C libraries, if real Native Language Support is necessary, it can be provided by the `libintl` library of the `gettext` package. Due to this, and in order to make sure that Native Language Support is properly handled, packages in Buildroot that can use NLS support should: . Ensure NLS support is enabled when `BR2_SYSTEM_ENABLE_NLS=y`. This is done automatically for 'autotools' packages and therefore should only be done for packages using other package infrastructures. . Add `$(TARGET_NLS_DEPENDENCIES)` to the package `<pkg>_DEPENDENCIES` variable. This addition should be done unconditionally: the value of this variable is automatically adjusted by the core infrastructure to contain the relevant list of packages. If NLS support is disabled, this variable is empty. If NLS support is enabled, this variable contains `host-gettext` so that tools needed to compile translation files are available on the host. In addition, if 'uClibc' or 'musl' are used, this variable also contains `gettext` in order to get the full-blown 'gettext' implementation. . If needed, add `$(TARGET_NLS_LIBS)` to the linker flags, so that the package gets linked with `libintl`. This is generally not needed with 'autotools' packages as they usually detect automatically that they should link with `libintl`. However, packages using other build systems, or problematic autotools-based packages may need this. `$(TARGET_NLS_LIBS)` should be added unconditionally to the linker flags, as the core automatically makes it empty or defined to `-lintl` depending on the configuration. No changes should be made to the `Config.in` file to support NLS. Finally, certain packages need some gettext utilities on the target, such as the `gettext` program itself, which allows to retrieve translated strings, from the command line. In such a case, the package should: * use `select BR2_PACKAGE_GETTEXT` in their `Config.in` file, indicating in a comment above that it's a runtime dependency only. * not add any `gettext` dependency in the `DEPENDENCIES` variable of their `.mk` file. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Tips and tricks [[package-name-variable-relation]] ==== Package name, config entry name and makefile variable relationship In Buildroot, there is some relationship between: * the _package name_, which is the package directory name (and the name of the `*.mk` file); * the config entry name that is declared in the `Config.in` file; * the makefile variable prefix. It is mandatory to maintain consistency between these elements, using the following rules: * the package directory and the `*.mk` name are the _package name_ itself (e.g.: `package/foo-bar_boo/foo-bar_boo.mk`); * the _make_ target name is the _package name_ itself (e.g.: `foo-bar_boo`); * the config entry is the upper case _package name_ with `.` and `-` characters substituted with `_`, prefixed with `BR2_PACKAGE_` (e.g.: `BR2_PACKAGE_FOO_BAR_BOO`); * the `*.mk` file variable prefix is the upper case _package name_ with `.` and `-` characters substituted with `_` (e.g.: `FOO_BAR_BOO_VERSION`). [[check-package]] ==== How to check the coding style Buildroot provides a script in `utils/check-package` that checks new or changed files for coding style. It is not a complete language validator, but it catches many common mistakes. It is meant to run in the actual files you created or modified, before creating the patch for submission. This script can be used for packages, filesystem makefiles, Config.in files, etc. It does not check the files defining the package infrastructures and some other files containing similar common code. To use it, run the `check-package` script, by telling which files you created or changed: ---- $ ./utils/check-package package/new-package/* ---- If you have the `utils` directory in your path you can also run: ---- $ cd package/new-package/ $ check-package * ---- The tool can also be used for packages in a br2-external: ---- $ check-package -b /path/to/br2-ext-tree/package/my-package/* ---- [[testing-package]] ==== How to test your package Once you have added your new package, it is important that you test it under various conditions: does it build for all architectures? Does it build with the different C libraries? Does it need threads, NPTL? And so on... Buildroot runs http://autobuild.buildroot.org/[autobuilders] which continuously test random configurations. However, these only build the `master` branch of the git tree, and your new fancy package is not yet there. Buildroot provides a script in `utils/test-pkg` that uses the same base configurations as used by the autobuilders so you can test your package in the same conditions. First, create a config snippet that contains all the necessary options needed to enable your package, but without any architecture or toolchain option. For example, let's create a config snippet that just enables `libcurl`, without any TLS backend: ---- $ cat libcurl.config BR2_PACKAGE_LIBCURL=y ---- If your package needs more configuration options, you can add them to the config snippet. For example, here's how you would test `libcurl` with `openssl` as a TLS backend and the `curl` program: ---- $ cat libcurl.config BR2_PACKAGE_LIBCURL=y BR2_PACKAGE_LIBCURL_CURL=y BR2_PACKAGE_OPENSSL=y ---- Then run the `test-pkg` script, by telling it what config snippet to use and what package to test: ---- $ ./utils/test-pkg -c libcurl.config -p libcurl ---- By default, `test-pkg` will build your package against a subset of the toolchains used by the autobuilders, which has been selected by the Buildroot developers as being the most useful and representative subset. If you want to test all toolchains, pass the `-a` option. Note that in any case, internal toolchains are excluded as they take too long to build. The output lists all toolchains that are tested and the corresponding result (excerpt, results are fake): ---- $ ./utils/test-pkg -c libcurl.config -p libcurl armv5-ctng-linux-gnueabi [ 1/11]: OK armv7-ctng-linux-gnueabihf [ 2/11]: OK br-aarch64-glibc [ 3/11]: SKIPPED br-arcle-hs38 [ 4/11]: SKIPPED br-arm-basic [ 5/11]: FAILED br-arm-cortex-a9-glibc [ 6/11]: OK br-arm-cortex-a9-musl [ 7/11]: FAILED br-arm-cortex-m4-full [ 8/11]: OK br-arm-full [ 9/11]: OK br-arm-full-nothread [10/11]: FAILED br-arm-full-static [11/11]: OK 11 builds, 2 skipped, 2 build failed, 1 legal-info failed ---- The results mean: * `OK`: the build was successful. * `SKIPPED`: one or more configuration options listed in the config snippet were not present in the final configuration. This is due to options having dependencies not satisfied by the toolchain, such as for example a package that `depends on BR2_USE_MMU` with a noMMU toolchain. The missing options are reported in `missing.config` in the output build directory (`~/br-test-pkg/TOOLCHAIN_NAME/` by default). * `FAILED`: the build failed. Inspect the `logfile` file in the output build directory to see what went wrong: ** the actual build failed, ** the legal-info failed, ** one of the preliminary steps (downloading the config file, applying the configuration, running `dirclean` for the package) failed. When there are failures, you can just re-run the script with the same options (after you fixed your package); the script will attempt to re-build the package specified with `-p` for all toolchains, without the need to re-build all the dependencies of that package. The `test-pkg` script accepts a few options, for which you can get some help by running: ---- $ ./utils/test-pkg -h ---- [[github-download-url]] ==== How to add a package from GitHub Packages on GitHub often don't have a download area with release tarballs. However, it is possible to download tarballs directly from the repository on GitHub. As GitHub is known to have changed download mechanisms in the past, the 'github' helper function should be used as shown below. ------------------------ # Use a tag or a full commit ID FOO_VERSION = 1.0 FOO_SITE = $(call github,<user>,<package>,v$(FOO_VERSION)) ------------------------ .Notes - The FOO_VERSION can either be a tag or a commit ID. - The tarball name generated by github matches the default one from Buildroot (e.g.: `foo-f6fb6654af62045239caed5950bc6c7971965e60.tar.gz`), so it is not necessary to specify it in the `.mk` file. - When using a commit ID as version, you should use the full 40 hex characters. - When the tag contains a prefix such as `v` in `v1.0`, then the `VERSION` variable should contain just `1.0`, and the `v` should be added directly in the `SITE` variable, as illustrated above. This ensures that the `VERSION` variable value can be used to match against http://www.release-monitoring.org/[release-monitoring.org] results. If the package you wish to add does have a release section on GitHub, the maintainer may have uploaded a release tarball, or the release may just point to the automatically generated tarball from the git tag. If there is a release tarball uploaded by the maintainer, we prefer to use that since it may be slightly different (e.g. it contains a configure script so we don't need to do AUTORECONF). You can see on the release page if it's an uploaded tarball or a git tag: image::github_hash_mongrel2.png[] - If it looks like the image above then it was uploaded by the maintainer and you should use that link (in that example: 'mongrel2-v1.9.2.tar.bz2') to specify `FOO_SITE`, and not use the 'github' helper. - On the other hand, if there's is *only* the "Source code" link, then it's an automatically generated tarball and you should use the 'github' helper function. [[gitlab-download-url]] ==== How to add a package from Gitlab In a similar way to the `github` macro described in xref:github-download-url[], Buildroot also provides the `gitlab` macro to download from Gitlab repositories. It can be used to download auto-generated tarballs produced by Gitlab, either for specific tags or commits: ------------------------ # Use a tag or a full commit ID FOO_VERSION = 1.0 FOO_SITE = $(call gitlab,<user>,<package>,v$(FOO_VERSION)) ------------------------ By default, it will use a `.tar.gz` tarball, but Gitlab also provides `.tar.bz2` tarballs, so by adding a `<pkg>_SOURCE` variable, this `.tar.bz2` tarball can be used: ------------------------ # Use a tag or a full commit ID FOO_VERSION = 1.0 FOO_SITE = $(call gitlab,<user>,<package>,v$(FOO_VERSION)) FOO_SOURCE = foo-$(FOO_VERSION).tar.bz2 ------------------------ If there is a specific tarball uploaded by the upstream developers in `https://gitlab.com/<project>/releases/`, do not use this macro, but rather use directly the link to the tarball. // -*- mode:doc; -*- // vim: set syntax=asciidoc: === Conclusion As you can see, adding a software package to Buildroot is simply a matter of writing a Makefile using an existing example and modifying it according to the compilation process required by the package. If you package software that might be useful for other people, don't forget to send a patch to the Buildroot mailing list (see xref:submitting-patches[])!