Вы находитесь на странице: 1из 62

Embedded Linux Conference Europe 2014

Buildroot: a deep dive


into the core

Thomas Petazzoni
Free Electrons
thomas.petazzoni@free-electrons.com

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 1/42
Thomas Petazzoni

I CTO and Embedded Linux engineer at Free Electrons


I Embedded Linux and Android development: kernel and driver
development, system integration, boot time and power
consumption optimization, consulting, etc.
I Embedded Linux, Linux driver development, Android system
and Yocto/OpenEmbedded training courses, with materials
freely available under a Creative Commons license.
I http://free-electrons.com
I Contributions
I Kernel support for the Marvell Armada ARM SoCs from
Marvell
I Major contributor to Buildroot, an open-source, simple and
fast embedded Linux build system
I Living in Toulouse, south west of France

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 2/42
Agenda

1. Quick introduction about Buildroot


2. Source tree and output tree
3. Configuration system
4. From make to the generic package infrastructure
5. Specialized package infrastructures
6. Toolchain support
7. Root filesystem image generation
8. Overall build logic

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 3/42
Buildroot at a glance

I An embedded Linux build system, builds from source:


I cross-compilation toolchain
I root filesystem with many libraries/applications, cross-built
I kernel and bootloader images
I Fast, simple root filesystem in minutes
I Easy to use and understand: kconfig and make
I Small root filesystem, default 2 MB
I More than 1200 packages available
I Generates filesystem images, not a distribution
I Vendor neutral
I Active community, regular releases
I Started in 2001, oldest still maintained build system
I http://buildroot.org

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 4/42
Demonstration

A demonstration is worth many


slides!

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 5/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I linux/ I top-level Makefile, handles the
I package/ configuration and general
I fs/ orchestration of the build
I boot/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I linux/ I top-level Config.in, main/general
I package/ options. Includes many other
I fs/ Config.in files
I boot/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/ I Config.in.* files defining the
I
architecture variants (processor
linux/
type, ABI, floating point, etc.)
I package/
I Config.in, Config.in.arm,
I fs/ Config.in.x86,
I boot/ Config.in.microblaze, etc.
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I
I packages for generating or using
arch/
toolchains
I toolchain/
I toolchain/ virtual package that
I system/ depends on either
I linux/ toolchain-buildroot or
I package/ toolchain-external
I fs/ I toolchain-buildroot/ virtual
I boot/ package to build the internal
toolchain
I configs/
I toolchain-external/ package to
I board/
handle external toolchains
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I
I skeleton/ the rootfs skeleton
linux/
I
I Config.in, options for
package/
system-wide features like init
I fs/ system, /dev handling, etc.
I boot/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I linux/
I linux.mk, the Linux kernel
I package/
package
I fs/
I boot/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/ I all the userspace packages (1200+)
I system/ I busybox/, gcc/, qt5/, etc.
I linux/ I pkg-generic.mk, core package
I
infrastructure
package/
I pkg-cmake.mk,
I fs/
pkg-autotools.mk,
I boot/ pkg-perl.mk, etc. Specialized
I configs/ package infrastructures
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/ I logic to generate filesystem images
I linux/ in various formats
I package/ I common.mk, common logic
I fs/ I cpio/, ext2/, squashfs/, tar/,
I boot/ ubifs/, etc.
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I linux/ I bootloader packages
I package/ I at91bootstrap3/, barebox/,
I fs/ grub/, syslinux/, uboot/, etc.
I boot/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I default configuration files for
various platforms
I linux/
I similar to kernel defconfigs
I package/
I atmel_xplained_defconfig,
I fs/
beaglebone_defconfig,
I boot/ raspberrypi_defconfig, etc.
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/ I board-specific files (kernel
I linux/ configuration files, kernel patches,
I package/ image flashing scripts, etc.)
I fs/ I typically go together with a
I boot/ defconfig in configs/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I linux/ I misc utilities (kconfig code, libtool
I package/ patches, download helpers, and
I fs/ more.)
I boot/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Source tree

I Makefile
I Config.in
I arch/
I toolchain/
I system/
I linux/
I Buildroot documentation
I package/
I 90 pages PDF document
I fs/
I boot/
I configs/
I board/
I support/
I docs/
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 6/42
Output tree

I output/
I build/
I host/
I staging/
I target/
I images/
I graphs/
I legal-info/

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I Global output directory


I output/
I Can be customized for
I build/
I host/ out-of-tree build by passing
I staging/ O=<dir>
I target/ I Variable: O (as passed on the
I images/ command line)
I graphs/
I legal-info/
I Variable: BASE_DIR (as an
absolute path)

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I output/
I build/ I Where all source tarballs are
I
I
buildroot-config/
busybox-1.22.1/
extracted
I host-pkgconf-0.8.9/
I kmod-1.18/ I Where the build of each
I build-time.log
package takes place
I host/
I staging/
I In addition to the package
I target/ sources and object files, stamp
I images/ files are created by Buildroot
I graphs/ I Variable: BUILD_DIR
I legal-info/

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I output/ I Contains both the tools built


I build/ for the host (cross-compiler,
I host/ etc.) and the sysroot of the
I usr/lib
I usr/bin toolchain
I usr/sbin

I usr/<tuple>/sysroot/bin
I Variable: HOST_DIR
I usr/<tuple>/sysroot/lib
I usr/<tuple>/sysroot/usr/lib I Host tools are directly in
I usr/<tuple>/sysroot/usr/bin
host/usr
I staging/
I target/
I The sysroot is in
I images/ host/<tuple>/sysroot/usr
I graphs/ I Variable for the sysroot:
I legal-info/ STAGING_DIR

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I output/
I build/
I host/ I Just a symbolic link to the
I staging/ sysroot, i.e to
I target/ host/<tuple>/sysroot/.
I images/ I Available for convenience
I graphs/
I legal-info/

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I output/ I The target root filesystem


I build/ I Usual Linux hierarchy
I host/
I Not completely ready for the
I staging/
I target/ target: permissions, device
I
I
bin/ files, etc.
etc/
I
I
lib/
usr/bin/
I Buildroot does not run as root:
I
I
usr/lib/
usr/share/
all files are owned by the user
I
I
usr/sbin/
THIS_IS_NOT_YOUR_ROOT_
running Buildroot, not setuid,
FILESYSTEM
I ...
etc.
I images/ I Used to generate the final root
I graphs/ filesystem images in images/
I legal-info/ I Variable: TARGET_DIR

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I output/
I build/
I host/
I staging/ I Contains the final images:
I target/
I images/ kernel image, bootloader
I zImage image, root filesystem image(s)
I armada-370-mirabox.dtb
I rootfs.tar
I Variable: BINARIES_DIR
I rootfs.ubi
I graphs/
I legal-info/

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I output/ I Visualization of Buildroot


I build/
operation: dependencies
I host/
I staging/ between packages, time to
I target/ build the different packages
I images/ I make graph-depends
I graphs/
I make graph-build
I legal-info/

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Output tree

I output/
I build/
I host/
I staging/
I Legal information: license of
I target/ all packages, and their source
I images/ code, plus a licensing manifest
I graphs/ I Useful for license compliance
I legal-info/
I manifest.csv I make legal-info
I host-manifest.csv
I licenses.txt
I Variable: LEGAL_INFO_DIR
I licenses/
I sources/
I ...

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 7/42
Configuration system
I Uses, almost unchanged, the kconfig code from the kernel, in
support/kconfig (variable CONFIG)
I kconfig tools are built in $(BUILD_DIR)/buildroot-config/
I The main Config.in file, passed to menuconfig/xconfig, is at
the top-level of the Buildroot source tree
I Config file saved as .config in the output directory (except for
in-tree builds)
I .config included in Makefile → config values readily available
as make variables.
CONFIG_CONFIG_IN = Config.in
CONFIG = support/kconfig
BR2_CONFIG = $(CONFIG_DIR)/.config

-include $(BR2_CONFIG)

$(BUILD_DIR)/buildroot-config/%onf:
mkdir -p $(@D)/lxdialog
$(MAKE) ... -C $(CONFIG) -f Makefile.br $(@F)

menuconfig: $(BUILD_DIR)/buildroot-config/mconf outputmakefile


@mkdir -p $(BUILD_DIR)/buildroot-config
@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 8/42
Configuration hierarchy

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 9/42
Example of package Config.in

I All packages have a


main option named
package/httping/Config.in
BR2_PACKAGE_<pkg>
comment "httping needs a toolchain w/ wchar"
depends on !BR2_USE_WCHAR I Sub-options are used for
config BR2_PACKAGE_HTTPING
bool "httping"
additional tuning of the
depends on BR2_USE_WCHAR
select BR2_PACKAGE_GETTEXT if BR2_NEEDS_GETTEXT
package
help
Httping is like 'ping' but for http-requests.
I depends on to depend
...
http://www.vanheusden.com/httping/ on toolchain features or
if BR2_PACKAGE_HTTPING
big features (e.g. X.org)
config BR2_PACKAGE_HTTPING_TFO I select used for most
bool "TCP Fast Open (TFO) support"
library dependencies, to
endif
make them transparent
to the user

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 10/42
When you run make...

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 11/42
Where is $(TARGETS) filled?

Part of package/pkg-generic.mk
# argument 1 is the lowercase package name
# argument 2 is the uppercase package name, including a HOST_ prefix
# for host packages

define inner-generic-package
...
$(2)_KCONFIG_VAR = BR2_PACKAGE_$(2)
...
ifeq ($$($$($(2)_KCONFIG_VAR)),y)
TARGETS += $(1)
endif # $(2)_KCONFIG_VAR

endef # inner-generic-package

I Adds the lowercase name of an enabled package as a make


target to the $(TARGETS) variable
I package/pkg-generic.mk is really the core of the package
infrastructure
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 12/42
Example of yavta.mk

YAVTA_VERSION = 82ff2efdb9787737b9f21b6f4759f077c827b238
YAVTA_SITE = git://git.ideasonboard.org/yavta.git
YAVTA_LICENSE = GPLv2+
YAVTA_LICENSE_FILES = COPYING.GPL

define YAVTA_BUILD_CMDS
$(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D)
endef

define YAVTA_INSTALL_TARGET_CMDS
$(INSTALL) -m 0755 -D $(@D)/yavta $(TARGET_DIR)/usr/bin/yavta
endef

$(eval $(generic-package))

I A package is just a definition of variables starting with the


package name
I Some variables are simple values: version, site, license, license
files
I Some variables contain commands: build and installation
commands

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 13/42
Example of zlib.mk (1/2)

ZLIB_VERSION = 1.2.8
ZLIB_SOURCE = zlib-$(ZLIB_VERSION).tar.xz
ZLIB_SITE = http://downloads.sourceforge.net/project/libpng/zlib/$(ZLIB_VERSION)
ZLIB_LICENSE = zlib license
ZLIB_LICENSE_FILES = README
ZLIB_INSTALL_STAGING = YES
...
define ZLIB_CONFIGURE_CMDS
(cd $(@D); rm -rf config.cache; \
$(TARGET_CONFIGURE_ARGS) \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS) $(ZLIB_PIC)" \
./configure \
$(ZLIB_SHARED) \
--prefix=/usr \
)
endef

define ZLIB_BUILD_CMDS
$(MAKE1) -C $(@D)
endef

define ZLIB_INSTALL_STAGING_CMDS
$(MAKE1) -C $(@D) DESTDIR=$(STAGING_DIR) LDCONFIG=true install
endef

define ZLIB_INSTALL_TARGET_CMDS
$(MAKE1) -C $(@D) DESTDIR=$(TARGET_DIR) LDCONFIG=true install
endef

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 14/42
Example of zlib.mk (2/2)

define HOST_ZLIB_CONFIGURE_CMDS
(cd $(@D); rm -rf config.cache; \
$(HOST_CONFIGURE_ARGS) \
$(HOST_CONFIGURE_OPTS) \
./configure \
--prefix="$(HOST_DIR)/usr" \
--sysconfdir="$(HOST_DIR)/etc" \
)
endef

define HOST_ZLIB_BUILD_CMDS
$(MAKE1) -C $(@D)
endef

define HOST_ZLIB_INSTALL_CMDS
$(MAKE1) -C $(@D) LDCONFIG=true install
endef

$(eval $(generic-package))
$(eval $(host-generic-package))

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 15/42
Diving into pkg-generic.mk

I The package/pkg-generic.mk file is divided in two main


parts:
I Definition of the actions done in each step of a package build
process. Done through stamp file targets.
I Definition of the inner-generic-package, generic-package
and host-generic-package macros, that define the sequence
of actions, as well as all the variables needed to handle the build
of a package.

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 16/42
Definition of the actions: code

$(BUILD_DIR)/%/.stamp_downloaded:
# Do some stuff here
$(Q)touch $@ $(BUILD_DIR)/%/.stamp_host_installed:
# Do some stuff here
$(BUILD_DIR)/%/.stamp_extracted: $(Q)touch $@
# Do some stuff here
$(Q)touch $@ $(BUILD_DIR)/%/.stamp_staging_installed:
# Do some stuff here
$(BUILD_DIR)/%/.stamp_patched: $(Q)touch $@
# Do some stuff here
$(Q)touch $@ $(BUILD_DIR)/%/.stamp_images_installed:
# Do some stuff here
$(BUILD_DIR)/%/.stamp_configured: $(Q)touch $@
# Do some stuff here
$(Q)touch $@ $(BUILD_DIR)/%/.stamp_target_installed:
# Do some stuff here
$(BUILD_DIR)/%/.stamp_built: $(Q)touch $@
# Do some stuff here
$(Q)touch $@

I $(BUILD DIR)/%/ → build directory of any package


I a make target depending on one stamp file will trigger the
corresponding action
I the stamp file prevents the action from being re-executed

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 17/42
Action example 1: download
# Retrieve the archive
$(BUILD_DIR)/%/.stamp_downloaded:
$(foreach hook,$($(PKG)_PRE_DOWNLOAD_HOOKS),$(call $(hook))$(sep))
[...]
$(if $($(PKG)_SOURCE),$(call DOWNLOAD,$($(PKG)_SITE:/=)/$($(PKG)_SOURCE)))
$(foreach p,$($(PKG)_EXTRA_DOWNLOADS),$(call DOWNLOAD,$($(PKG)_SITE:/=)/$(p))$(sep))
$(foreach p,$($(PKG)_PATCH),\
$(if $(findstring ://,$(p)),\
$(call DOWNLOAD,$(p)),\
$(call DOWNLOAD,$($(PKG)_SITE:/=)/$(p))\
)\
$(sep))
$(foreach hook,$($(PKG)_POST_DOWNLOAD_HOOKS),$(call $(hook))$(sep))
$(Q)mkdir -p $(@D)
$(Q)touch $@

I Step handled by the package infrastructure


I In all stamp file targets, PKG is the upper case name of the
package. So when used for Busybox, $($(PKG)_SOURCE) is the
value of BUSYBOX_SOURCE.
I Hooks: make macros called before and after each step.
I Downloads the files mentioned in <pkg>_SOURCE,
<pkg>_EXTRA_DOWNLOADS and <pkg>_PATCH.
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 18/42
Action example 2: build

# Build
$(BUILD_DIR)/%/.stamp_built::
@$(call step_start,build)
@$(call MESSAGE,"Building")
$(foreach hook,$($(PKG)_PRE_BUILD_HOOKS),$(call $(hook))$(sep))
+$($(PKG)_BUILD_CMDS)
$(foreach hook,$($(PKG)_POST_BUILD_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
@$(call step_end,build)

I Step handled by the package, by defining a value for


<pkg>_BUILD_CMDS.
I Same principle of hooks
I step_start and step_end are part of instrumentation to
measure the duration of each step (and other actions)

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 19/42
The generic-package macro

I Packages built for the target:


generic-package = $(call inner-generic-package,
$(pkgname),$(call UPPERCASE,$(pkgname)),
$(call UPPERCASE,$(pkgname)),target)

I Packages built for the host:


host-generic-package = $(call inner-generic-package,
host-$(pkgname),$(call UPPERCASE,host-$(pkgname)),
$(call UPPERCASE,$(pkgname)),host)

I In package/zlib/zlib.mk:
ZLIB_... = ...

$(eval $(generic-package))
$(eval $(host-generic-package))

I Leads to:
$(call inner-generic-package,zlib,ZLIB,ZLIB,target)
$(call inner-generic-package,host-zlib,HOST_ZLIB,ZLIB,host)

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 20/42
inner-generic-package: defining variables

Macro code Expanded for host-zlib


$(2)_TYPE = $(4) HOST_ZLIB_TYPE = host
$(2)_NAME = $(1) HOST_ZLIB_NAME = host-zlib
$(2)_RAWNAME = $$(patsubst host-%,%,$(1)) HOST_ZLIB_RAWNAME = zlib

$(2)_BASE_NAME = $(1)-$$($(2)_VERSION) HOST_ZLIB_BASE_NAME =


$(2)_DIR = $$(BUILD_DIR)/$$($(2)_BASE_NAME) host-zlib-$(HOST_ZLIB_VERSION)
HOST_ZLIB_DIR =
$(BUILD_DIR)/host-zlib-$(HOST_ZLIB_VERSION)

ifndef $(2)_SOURCE ifndef HOST_ZLIB_SOURCE


ifdef $(3)_SOURCE ifdef ZLIB_SOURCE
$(2)_SOURCE = $$($(3)_SOURCE) HOST_ZLIB_SOURCE = $(ZLIB_SOURCE)
else else
$(2)_SOURCE ?= HOST_ZLIB_SOURCE ?=
$$($(2)_RAWNAME)-$$($(2)_VERSION).tar.gz zlib-$(HOST_ZLIB_VERSION).tar.gz
endif endif
endif endif

ifndef $(2)_SITE ifndef HOST_ZLIB_SITE


ifdef $(3)_SITE ifdef ZLIB_SITE
$(2)_SITE = $$($(3)_SITE) HOST_ZLIB_SITE = $(ZLIB_SITE)
endif endif
endif endif

... ...

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 21/42
inner-generic-package: dependencies

ifeq ($(4),host)
$(2)_DEPENDENCIES ?= $$(filter-out host-toolchain $(1),\
$$(patsubst host-host-%,host-%,$$(addprefix host-,$$($(3)_DEPENDENCIES))))
endif

I Dependencies of host packages, if not explicitly specified, are derived


from the dependencies of the target package, by adding a host- prefix
to each dependency.
I If a package foo defines
FOO_DEPENDENCIES = bar baz host-buzz, then the
host-foo package will have host-bar, host-baz and
host-buzz in its dependencies.

ifeq ($(4),target)
ifeq ($$($(2)_ADD_TOOLCHAIN_DEPENDENCY),YES)
$(2)_DEPENDENCIES += toolchain
endif
endif

I Adding the toolchain dependency to target packages. Except for


some specific packages (e.g. C library).
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 22/42
inner-generic-package: stamp files

$(2)_TARGET_INSTALL_TARGET = $$($(2)_DIR)/.stamp_target_installed
$(2)_TARGET_INSTALL_STAGING = $$($(2)_DIR)/.stamp_staging_installed
$(2)_TARGET_INSTALL_IMAGES = $$($(2)_DIR)/.stamp_images_installed
$(2)_TARGET_INSTALL_HOST = $$($(2)_DIR)/.stamp_host_installed
$(2)_TARGET_BUILD = $$($(2)_DIR)/.stamp_built
$(2)_TARGET_CONFIGURE = $$($(2)_DIR)/.stamp_configured
$(2)_TARGET_RSYNC = $$($(2)_DIR)/.stamp_rsynced
$(2)_TARGET_RSYNC_SOURCE = $$($(2)_DIR)/.stamp_rsync_sourced
$(2)_TARGET_PATCH = $$($(2)_DIR)/.stamp_patched
$(2)_TARGET_EXTRACT = $$($(2)_DIR)/.stamp_extracted
$(2)_TARGET_SOURCE = $$($(2)_DIR)/.stamp_downloaded
$(2)_TARGET_DIRCLEAN = $$($(2)_DIR)/.stamp_dircleaned

I Defines shortcuts to reference the stamp files

$$($(2)_TARGET_INSTALL_TARGET): PKG=$(2)
$$($(2)_TARGET_INSTALL_STAGING): PKG=$(2)
$$($(2)_TARGET_INSTALL_IMAGES): PKG=$(2)
$$($(2)_TARGET_INSTALL_HOST): PKG=$(2)
[...]

I Pass variables to the stamp file targets, especially PKG

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 23/42
inner-generic-package: sequencing

Step sequencing for target packages


$(1): $(1)-install

$(1)-install: $(1)-install-staging $(1)-install-target $(1)-install-images

$(1)-install-target: $$($(2)_TARGET_INSTALL_TARGET)
$$($(2)_TARGET_INSTALL_TARGET): $$($(2)_TARGET_BUILD)

$(1)-build: $$($(2)_TARGET_BUILD)
$$($(2)_TARGET_BUILD): $$($(2)_TARGET_CONFIGURE)

$(1)-configure: $$($(2)_TARGET_CONFIGURE)
$$($(2)_TARGET_CONFIGURE): | $$($(2)_FINAL_DEPENDENCIES)
$$($(2)_TARGET_CONFIGURE): $$($(2)_TARGET_PATCH)

$(1)-patch: $$($(2)_TARGET_PATCH)
$$($(2)_TARGET_PATCH): $$($(2)_TARGET_EXTRACT)

$(1)-extract: $$($(2)_TARGET_EXTRACT)
$$($(2)_TARGET_EXTRACT): $$($(2)_TARGET_SOURCE)

$(1)-source: $$($(2)_TARGET_SOURCE)

$$($(2)_TARGET_SOURCE): | dirs prepare


$$($(2)_TARGET_SOURCE): | dependencies

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 24/42
inner-generic-package: sequencing diagram

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 25/42
Example of package build

>>> zlib 1.2.8 Downloading


... here it wgets the tarball ...

>>> zlib 1.2.8 Extracting


xzcat /home/thomas/dl/zlib-1.2.8.tar.xz | tar ...

>>> zlib 1.2.8 Patching

>>> zlib 1.2.8 Configuring


(cd /home/thomas/projets/buildroot/output/build/zlib-1.2.8;
...
./configure --shared --prefix=/usr)

>>> zlib 1.2.8 Building


/usr/bin/make -j1 -C /home/thomas/projets/buildroot/output/build/zlib-1.2.8

>>> zlib 1.2.8 Installing to staging directory


/usr/bin/make -j1 -C /home/thomas/projets/buildroot/output/build/zlib-1.2.8
DESTDIR=/home/thomas/projets/buildroot/output/host/usr/arm-buildroot-linux-uclibcgnueabi/sysroot
LDCONFIG=true install

>>> zlib 1.2.8 Installing to target


/usr/bin/make -j1 -C /home/thomas/projets/buildroot/output/build/zlib-1.2.8
DESTDIR=/home/thomas/projets/buildroot/output/target
LDCONFIG=true install

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 26/42
Preparation work: dirs, prepare, dependencies

pkg-generic.mk
$$($(2)_TARGET_SOURCE): | dirs prepare
$$($(2)_TARGET_SOURCE): | dependencies

I All package have in their dependencies three targets:


I dirs: creates the main directories (BUILD_DIR, TARGET_DIR,
HOST_DIR, etc.). As part of creating TARGET_DIR, the root
filesystem skeleton is copied into it
I prepare: generates a kconfig-related auto.conf file
I dependencies: triggers the check of Buildroot system
dependencies, i.e things that must be installed on the machine to
use Buildroot

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 27/42
Rebuilding packages?

I Once one step of a package build process has been done, it is


never done again due to the stamp file
I Even if the package configuration is changed, or the package is
disabled → Buildroot doesn’t try to be smart
I One can force rebuilding a package from its configure step or
build step using make <pkg>-reconfigure or
make <pkg>-rebuild

$(1)-clean-for-rebuild:
rm -f $$($(2)_TARGET_BUILD)
rm -f $$($(2)_TARGET_INSTALL_STAGING)
rm -f $$($(2)_TARGET_INSTALL_TARGET)
rm -f $$($(2)_TARGET_INSTALL_IMAGES)
rm -f $$($(2)_TARGET_INSTALL_HOST)

$(1)-rebuild: $(1)-clean-for-rebuild $(1)

$(1)-clean-for-reconfigure: $(1)-clean-for-rebuild
rm -f $$($(2)_TARGET_CONFIGURE)

$(1)-reconfigure: $(1)-clean-for-reconfigure $(1)

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 28/42
Specialized package infrastructures

I The generic-package infrastructure is fine for packages having


a custom build system
I For packages having well-known build system, we want to
factorize more logic
I Specialized package infrastructures were created to handle
these packages, and reduce the amount of duplication
I For autotools, CMake, Python, Perl, Lua and kconfig packages

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 29/42
Specialized package infrastructures

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 30/42
CMake package example: flann

package/flann/flann.mk
FLANN_VERSION = d0c04f4d290ebc3aa9411a3322992d298e51f5aa
FLANN_SITE = $(call github,mariusmuja,flann,$(FLANN_VERSION))
FLANN_INSTALL_STAGING = YES
FLANN_LICENSE = BSD-3c
FLANN_LICENSE_FILES = COPYING
FLANN_CONF_OPT = \
-DBUILD_C_BINDINGS=ON \
-DBUILD_PYTHON_BINDINGS=OFF \
-DBUILD_MATLAB_BINDINGS=OFF \
-DBUILD_EXAMPLES=$(if $(BR2_PACKAGE_FLANN_EXAMPLES),ON,OFF) \
-DBUILD_TESTS=OFF \
-DBUILD_DOC=OFF \
-DUSE_OPENMP=$(if $(BR2_GCC_ENABLE_OPENMP),ON,OFF) \
-DPYTHON_EXECUTABLE=OFF

$(eval $(cmake-package))

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 31/42
CMake package infrastructure (1/2)

define inner-cmake-package

$(2)_CONF_ENV ?=
$(2)_CONF_OPT ?=
...

$(2)_SRCDIR = $$($(2)_DIR)/$$($(2)_SUBDIR)
$(2)_BUILDDIR = $$($(2)_SRCDIR)

ifndef $(2)_CONFIGURE_CMDS
ifeq ($(4),target)
define $(2)_CONFIGURE_CMDS
(cd $$($$(PKG)_BUILDDIR) && \
$$($$(PKG)_CONF_ENV) $$(HOST_DIR)/usr/bin/cmake $$($$(PKG)_SRCDIR) \
-DCMAKE_TOOLCHAIN_FILE="$$(HOST_DIR)/usr/share/buildroot/toolchainfile.cmake" \
...
$$($$(PKG)_CONF_OPT) \
)
endef
else
define $(2)_CONFIGURE_CMDS
... host case ...
endef
endif
endif

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 32/42
CMake package infrastructure (2/2)

$(2)_DEPENDENCIES += host-cmake

ifndef $(2)_BUILD_CMDS
ifeq ($(4),target)
define $(2)_BUILD_CMDS
$$(TARGET_MAKE_ENV) $$($$(PKG)_MAKE_ENV) $$($$(PKG)_MAKE) $$($$(PKG)_MAKE_OPT)
-C $$($$(PKG)_BUILDDIR)
endef
else
... host case ...
endif
endif

... other commands ...

ifndef $(2)_INSTALL_TARGET_CMDS
define $(2)_INSTALL_TARGET_CMDS
$$(TARGET_MAKE_ENV) $$($$(PKG)_MAKE_ENV) $$($$(PKG)_MAKE) $$($$(PKG)_MAKE_OPT)
$$($$(PKG)_INSTALL_TARGET_OPT) -C $$($$(PKG)_BUILDDIR)
endef
endif

$(call inner-generic-package,$(1),$(2),$(3),$(4))

endef

cmake-package = $(call inner-cmake-package,$(pkgname),...,target)


host-cmake-package = $(call inner-cmake-package,host-$(pkgname),...,host)

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 33/42
Autoreconf in pkg-autotools.mk

I Package infrastructures can also add additional capabilities


controlled by variables in packages
I For example, with the autotools-package infra, one can do
FOOBAR_AUTORECONF = YES in a package to trigger an
autoreconf before the configure script is executed
I Implementation in pkg-autotools.mk
define AUTORECONF_HOOK
@$$(call MESSAGE,"Autoreconfiguring")
$$(Q)cd $$($$(PKG)_SRCDIR) && $$($$(PKG)_AUTORECONF_ENV) $$(AUTORECONF)
$$($$(PKG)_AUTORECONF_OPTS)
...
endef

ifeq ($$($(2)_AUTORECONF),YES)
...
$(2)_PRE_CONFIGURE_HOOKS += AUTORECONF_HOOK
$(2)_DEPENDENCIES += host-automake host-autoconf host-libtool
endif

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 34/42
Toolchain support

I One virtual package, toolchain, with two implementations in


the form of two packages: toolchain-buildroot and
toolchain-external
I toolchain-buildroot implements the internal toolchain
back-end, where Buildroot builds the cross-compilation
toolchain from scratch. This package simply depends on
host-gcc-final to trigger the entire build process
I toolchain-external implements the external toolchain
back-end, where Buildroot uses an existing pre-built toolchain

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 35/42
Internal toolchain back-end

ALL
I Build starts with utility host tools and
libraries needed for gcc (host-m4,
toolchain
host-mpc, host-mpfr, host-gmp). Installed
in $(HOST_DIR)/usr/{bin,include,lib}
toolchain-buildroot
I Build goes on with the cross binutils,
host-binutils, installed in host-gcc-final
$(HOST_DIR)/usr/bin
I Then the first stage compiler, uclibc

host-gcc-initial
I We need the linux-headers, installed in host-gcc-initial linux-headers

$(STAGING_DIR)/usr/include
I We build the C library, uclibc in this host-binutils host-mpc

example. Installed in $(STAGING_DIR)/lib,


host-mpfr
$(STAGING_DIR)/usr/include and of
course $(TARGET_DIR)/lib
host-gmp
I We build the final compiler
host-gcc-final, installed in
host-m4
$(HOST_DIR)/usr/bin
Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 36/42
External toolchain back-end

I Implemented as one package, toolchain-external


I Knows about well-known toolchains (CodeSourcery, Linaro, etc.)
or allows to use existing custom toolchains (built with Buildroot,
Crosstool-NG, etc.)
I Core logic:
1. Extract the toolchain to $(HOST_DIR)/opt/ext-toolchain
2. Run some checks on the toolchain
3. Copy the toolchain sysroot (C library and headers, kernel headers) to
$(STAGING_DIR)/usr/{include,lib}
4. Copy the toolchain libraries to $(TARGET_DIR)/usr/lib
5. Create symbolic links or wrappers for the compiler, linker, debugger, etc from
$(HOST_DIR)/usr/bin/<tuple>-<tool> to
$(HOST_DIR)/opt/ext-toolchain/bin/<tuple>-<tool>
6. A wrapper program is used for certain tools (gcc, ld, g++, etc.) in order to
ensure a certain number of compiler flags are used, especially
--sysroot=$(STAGING_DIR) and target-specific flags.

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 37/42
Root filesystem image generation

I Once all the targets in $(TARGETS) have been built, it’s time to
create the root filesystem images
I First, the target-finalize target does some cleanup of
$(TARGET_DIR) by removing documentation, headers, static
libraries, etc.
I Then the root filesystem image targets listed in
$(ROOTFS_TARGETS) are processed
I These targets are added by the common filesystem image
generation infrastructure, in fs/common.mk
I The purpose of this infrastructure is to factorize the preparation
logic, and then call fakeroot to create the filesystem image

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 38/42
fs/common.mk

define ROOTFS_TARGET_INTERNAL

ROOTFS_$(2)_DEPENDENCIES += host-fakeroot host-makedevs \


$$(if $$(PACKAGES_USERS),host-mkpasswd)

$$(BINARIES_DIR)/rootfs.$(1): target-finalize $$(ROOTFS_$(2)_DEPENDENCIES)


@$$(call MESSAGE,"Generating root filesystem image rootfs.$(1)")
$$(foreach hook,$$(ROOTFS_$(2)_PRE_GEN_HOOKS),$$(call $$(hook))$$(sep))
...
echo "chown -h -R 0:0 $$(TARGET_DIR)" >> $$(FAKEROOT_SCRIPT)
echo "$$(HOST_DIR)/usr/bin/makedevs -d $$(FULL_DEVICE_TABLE) $$(TARGET_DIR)" >> \
$$(FAKEROOT_SCRIPT)
echo "$$(ROOTFS_$(2)_CMD)" >> $$(FAKEROOT_SCRIPT)
chmod a+x $$(FAKEROOT_SCRIPT)
PATH=$$(BR_PATH) $$(HOST_DIR)/usr/bin/fakeroot -- $$(FAKEROOT_SCRIPT)
...

rootfs-$(1): $$(BINARIES_DIR)/rootfs.$(1) $$(ROOTFS_$(2)_POST_TARGETS)

ifeq ($$(BR2_TARGET_ROOTFS_$(2)),y)
TARGETS_ROOTFS += rootfs-$(1)
endif
endef

define ROOTFS_TARGET
$(call ROOTFS_TARGET_INTERNAL,$(1),$(call UPPERCASE,$(1)))
endef

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 39/42
fs/ubifs/ubifs.mk

UBIFS_OPTS := -e $(BR2_TARGET_ROOTFS_UBIFS_LEBSIZE) \
-c $(BR2_TARGET_ROOTFS_UBIFS_MAXLEBCNT) \
-m $(BR2_TARGET_ROOTFS_UBIFS_MINIOSIZE)

ifeq ($(BR2_TARGET_ROOTFS_UBIFS_RT_ZLIB),y)
UBIFS_OPTS += -x zlib
endif
...

UBIFS_OPTS += $(call qstrip,$(BR2_TARGET_ROOTFS_UBIFS_OPTS))

ROOTFS_UBIFS_DEPENDENCIES = host-mtd

define ROOTFS_UBIFS_CMD
$(HOST_DIR)/usr/sbin/mkfs.ubifs -d $(TARGET_DIR) $(UBIFS_OPTS) -o $@
endef

$(eval $(call ROOTFS_TARGET,ubifs))

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 40/42
Final example

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 41/42
http://buildroot.org
http://buildroot.org/downloads/manual/manual.html

Questions?
thomas.petazzoni@free-electrons.com
Slides under CC-BY-SA 3.0
http://free-electrons.com/pub/conferences/2014/elce/petazzoni-dive-
into-buildroot-core/

Free Electrons - Embedded Linux, kernel, drivers and Android - Development, consulting, training and support. http://free-electrons.com 42/42

Вам также может понравиться