\documentclass[obeyspaces,spaces,hyphens]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{minted}

\mode<presentation>
\usetheme{Bootlin}

\title{Buildroot: a nice, simple and efficient embedded Linux build
  system}
\authors{Thomas Petazzoni}
\institute{Bootlin}

\usepackage{hyperref}

\begin{document}

\begin{frame}{Embedded Linux Conference 2012}
  \begin{columns}[c]
   \column{0.6\textwidth}
     \huge
     Buildroot: a nice, simple and efficient embedded Linux build
     system\\
     \vspace{1cm}
     \normalsize
     Thomas Petazzoni\\
     {\bf Bootlin}\\
     {\em thomas.petazzoni@bootlin.com}
     \column{0.4\textwidth}
     \includegraphics[width=\textwidth]{logo.png}
   \end{columns}
\end{frame}

\begin{frame}{Thomas Petazzoni}
  \begin{itemize}
  \item Embedded Linux engineer and trainer at Bootlin since
    2008
    \begin{itemize}
    \item Embedded Linux development: kernel and driver
      development, system integration, boot time and power
      consumption optimization, consulting, etc.
    \item Embedded Linux training, Linux driver development training
      and Android system development training, with materials freely
      available under a Creative Commons license.
    \item \url{https://www.bootlin.com}
    \end{itemize}
  \item Major contributor to Buildroot, an open-source, simple and
    fast embedded Linux build system
  \item Living in Toulouse, south west of France
  \end{itemize}
\end{frame}

\begin{frame}{What is Buildroot?}
  \begin{center}
    \Large
    Buildroot is an {\bf embedded Linux build system}.\\
    \vspace{0.5cm}
    Its purpose is to {\bf simplify} and {\bf automate} the process of
    building an embedded Linux system.
  \end{center}
\end{frame}

\begin{frame}{Buildroot main characteristics}
  \begin{itemize}
  \item Based on {\bf well-known technologies}: {\em kconfig} for the
    configuration interface and language, {\em make} for the build
    logic. These technologies are familiar to all embedded Linux
    developers.
  \item Very {\bf simple to use}, and {\bf easily hackable} code
    base. The core infrastructure is a few hundred lines of {\em make}
    code.
  \item {\bf Fast}. It does really build only what's necessary. The base
    system, composed only of BusyBox, takes less than 3 minutes to
    build with an external toolchain.
  \item {\bf Designed for small to medium sized embedded
      systems}. There is no runtime package management system (dpkg,
    rpm). Complete rebuilds are often required. Well-suited for systems
    with a limited number of components.
  \end{itemize}
\end{frame}

\begin{frame}{Buildroot vs. OpenEmbedded/Yocto}
  \begin{center}
    \includegraphics[width=\textwidth]{buildroot-vs-openembedded.pdf}
  \end{center}
\end{frame}

\begin{frame}{Context: quick Buildroot history}
  \begin{center}
    {\bf December 2001}\\
    \vspace{0.5cm}
    Buildroot is created by {\em uClibc} developers as a way of
    building small embedded Linux systems to test {\em uClibc}
  \end{center}
\end{frame}

\begin{frame}{Context: quick Buildroot history}
  \begin{center}
    {\bf Starting around 2005}\\
    \vspace{0.5cm}
    Buildroot really starts to be used as an embedded Linux build
    system for production devices.\\
    \vspace{0.5cm}
    The number of developers increases with everybody having
    write-access to the repository, and the maintainer is no longer
    active. No stable releases, no design.\\
    \vspace{0.5cm}
    The code slowly gets crappier over the years.
  \end{center}
\end{frame}

\begin{frame}{Context: quick Buildroot history}
  \begin{center}
    {\bf January 2009}\\
    \vspace{0.5cm}
    Peter Korsgaard becomes the new maintainer. Start of a new period
    for the project:
    \begin{itemize}
    \item Stable releases every three months. First release 2009.02,
      2012.02 due at the end of the month.
    \item Huge cleanup effort: code base reduction from 5.2 MB to 2.2
      MB, while many packages are added, updated and many new features
      are added.
    \item Increase in the number of contributors and users. Regular
      {\em Buildroot Developer Days}.
    \item Linux model: only the maintainer has write-access. Allows to
      keep a very good consistency in the design decisions.
    \end{itemize}
  \end{center}
\end{frame}

\begin{frame}{Context: quick Buildroot history}
  \begin{center}
    \includegraphics[width=0.9\textwidth]{commit-activity.png}\\
    Number of commits per month\\
    \vspace{1cm}
    \includegraphics[width=0.9\textwidth]{mailing-list-activity.png}\\
    Number of e-mails per day\\
  \end{center}
\end{frame}

\begin{frame}{Three years of change}
  \begin{center}
    \Large After three years of major changes in {\em Buildroot}, it's
    a good time to have a fresh look at it.
  \end{center}
\end{frame}

\begin{frame}{Buildroot: general principle}
  \begin{center}
    \includegraphics[width=\textwidth]{buildroot-big-picture.pdf}
  \end{center}
\end{frame}

\begin{frame}[fragile]{Using Buildroot}
  \scriptsize
\begin{verbatim}
$ wget http://buildroot.org/downloads/buildroot-2011.11.tar.bz2
$ tar xjf buildroot-2011.11.tar.bz2
$ cd buildroot-2011.11

$ make [menu|x|n|g]config
\end{verbatim}
  \normalsize
  \begin{itemize}
  \item No need to run as root. Ever.
  \item No need to symlink \path{/bin/sh} to \path{bash}
  \item Very limited set of dependencies: a native compiler, and basic
    utilities like {\em awk}, {\em bison}, {\em patch}, {\em gzip},
    {\em tar}, {\em wget}, etc.
  \item Out-of-tree build is possible using \path{O=}, exactly like
    the Linux kernel.
  \end{itemize}
\end{frame}

\begin{frame}{Buildroot {\em menuconfig}}
  \begin{center}
    \includegraphics[width=\textwidth]{buildroot-menuconfig.png}
  \end{center}
\end{frame}

\begin{frame}{Target architecture}
  Allows you to define:
  \begin{itemize}
  \item The {\bf target architecture}, i.e ARM, x86, PowerPC,
    MIPS. Buildroot supports non-MMU architectures such as Blackfin or
    soon Microblaze, thanks to its uClibc support.
  \item The {\bf target architecture variant}, such as ARM926 or
    Cortex-A8 on ARM. Allows to automatically add the appropriate {\tt
      -mcpu}, {\tt -march}, {\tt -mtune} arguments to {\em gcc}.
  \item {\bf Target architecture ABI}
  \end{itemize}
\end{frame}

\begin{frame}{Build options}
  \begin{itemize}
  \item The {\bf download directory}, where tarballs are saved for
    future builds. Defaults to \path{$(TOPDIR)/dl}. Can also be
    overridden using the \path{BUILDROOT_DL_DIR} environment variable.
  \item The {\bf host directory}, where all host utilities are
    installed, including the {\em toolchain} and its {\em
      sysroot}. Defaults to \path{$(O)/host}, but can be changed to
    generate an SDK in a different directory.
  \item The {\bf number of jobs}. Buildroot runs the build of the
    different components sequentially, but uses {\tt make -j} for the
    compilation of the individual components.
  \item Use of {\bf ccache}
  \item Other build options: build with debugging symbols, install
    documentation on target, install development files on target, etc.
  \end{itemize}
\end{frame}

\begin{frame}{Toolchain}
  Buildroot provides three toolchain {\em back-ends}:
  \begin{itemize}
  \item An {\bf internal Buildroot toolchain back-end}, which has been
    available since Buildroot creation. Buildroot will directly build
    a {\em uClibc} toolchain and use it for cross-compiling all
    packages.
  \item An {\bf external toolchain back-end}, which allows use
    existing pre-built uClibc, glibc or eglibc toolchains, such as
    Sourcery CodeBench toolchains, Linaro toolchains, or toolchains
    that have previously been built using Crosstool-NG or
    Buildroot. Using an external toolchain removes the toolchain build
    time.
  \item A {\bf Crosstool-NG back-end}, which tells Buildroot to build a
    cross-compiling toolchain with Crosstool-NG. This allows to
    benefit from all Crosstool-NG advantages, such as the support for
    {\em glibc} or {\em eglibc}.
  \end{itemize}
  $\rightarrow$ Buildroot often had the reputation of being limited to
  uClibc, but it is no longer the case since several years.
\end{frame}

\begin{frame}{System configuration}
  Allows the definition of various system-wide parameters:
  \begin{itemize}
  \item The {\bf \path{/dev} management solution}:
    \begin{itemize}
    \item {\em static}, where device nodes are created statically at
      build time according to a device table
    \item {\em devtmpfs}
    \item {\em devtmpfs} + {\em BusyBox' mdev}
    \item {\em devtmpfs} + {\em udev}
    \end{itemize}
    \item The serial port for the console
    \item Location of a {\em post-build script} that gets run after
      all packages have been built, but before the filesystem images
      are created.
    \item Some misc. other parameters (hostname, etc.)
  \end{itemize}
\end{frame}

\begin{frame}{Packages}
  \begin{center}
    \includegraphics[width=\textwidth]{buildroot-menuconfig-packages.png}
  \end{center}
\end{frame}

\begin{frame}{Packages}
  A selection of more than 750 open-source components typically used
  in embedded systems:
  \begin{itemize}
  \item Audio and multimedia: gstreamer, mplayer, pulseaudio, many
    codec libraries, alsa, etc.
  \item Graphics: full X.org stack, Gtk, Qt, EFL, DirectFB, SDL, etc.
  \item System tools, filesystem utilities, hardware utilities and
    libraries
  \item Networking applications: dropbear, avahi, bluez, samba, pppd,
    connman, etc.
  \item Development, debugging: oprofile, lttng, etc.
  \item Interpreters: Python, PHP, Ruby, Perl
  \end{itemize}
\end{frame}

\begin{frame}{Filesystem images}
  Buildroot can generate filesystem images in multiple formats:
  \begin{itemize}
  \item tar
  \item cpio
  \item ext2
  \item jffs2
  \item ubi/ubifs
  \item cramfs
  \item cloop
  \item iso9660
  \item squashfs
  \item initramfs built into the kernel
  \end{itemize}
\end{frame}

\begin{frame}{Kernel and bootloader}
  \begin{itemize}
  \item Automates the {\bf Linux kernel build process}. Builds the
    kernel using a {\em defconfig} or a specified configuration
    file. Takes care of installing the kernel modules into the root
    filesystem. It is also capable of patching the kernel for
    real-time extensions like Xenomai or RTAI.
  \item Includes support for the {\bf most popular bootloaders}:
    U-Boot, Barebox, Grub, syslinux, but also architecture-specific
    bootloaders: AT91Bootstrap, X-Loader, lpc32xxcdl, etc.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Building}

  Once the configuration is defined and saved in \path{.config}, the
  compilation is triggered using:

\begin{verbatim}
$ make
...
$ ls output/images/
dataflash_at91sam9m10g45ek.bin  rootfs.tar
rootfs.ubi                      rootfs.ubifs
u-boot.bin                      u-boot-env.bin
uImage
\end{verbatim}

  Buildroot will automatically download, extract, patch, configure,
  compile and install the selected components, taking care of
  following the necessary dependencies.

\end{frame}

\begin{frame}{Build output (1/2)}

  In the output directory (by default, \path{output/}, but can be
  changed using out-of-tree build), Buildroot generates:

  \begin{itemize}
  \item {\bf build}, with one sub-directory per component built. This
    is where Buildroot extracts and builds the various components of
    the system.
  \item {\bf host}, with a typical Unix organization, in which
    Buildroot installs all utilities compiled for the host, including
    the cross-compiler. It also contains, in
    \path{host/usr/<tuple>/sysroot} the toolchain {\em sysroot}, with
    all the headers and libraries built for the target.
  \item {\bf images}, with the final images (root filesystem, kernel,
    bootloaders)
  \item ...
  \end{itemize}
\end{frame}

\begin{frame}{Build output (2/2)}
  \begin{itemize}
    \item ...
    \item {\bf stamps}, a few stamp files used internally by Buildroot
      to keep track of what has been built
  \item {\bf target}, the target root filesystem (but with an empty
    {\tt /dev} and invalid permissions, those are fixed using {\em
      fakeroot} in the final image)
  \item {\bf toolchain}, where the different toolchain components are
    built in the case of the internal back-end. Otherwise unused.
  \end{itemize}
\end{frame}

\begin{frame}{Build-time: basic examples}
  \begin{itemize}
  \item Building a simple ARM system with simply Busybox, using an
    already extracted CodeSourcery glibc toolchain, and generating a
    .tar filesystem image takes {\bf 39 seconds}. The target system
    size is {\bf 4.2 MB}.
  \item Building a simple ARM system with simply Busybox, using a
    tarball CodeSourcery glibc toolchain, and generating an UBIFS
    filesystem image takes {\bf 2 minutes 57 seconds}. Identical
    system size.
  \item Building the same simple ARM system, using an internal
    Buildroot toolchain (with largefile, locales, C++ support), takes
    {\bf 9 minutes 59 seconds}. The target system size is {\bf 2.2
      MB}.
  \end{itemize}

  \scriptsize

  Note: durations measured with the {\em real} output of the
  \path{time} command. Download times are excluded.
\end{frame}

\begin{frame}{Build time: real-world example 1}

\begin{itemize}

  \item The device is an ARM AT91-based platform with GPS, RFID
    readers, GSM modem, Ethernet and USB.
  \item The Buildroot configuration:
    \begin{itemize}
    \item CodeSourcery ARM glibc toolchain
    \item {\em Linux kernel}
    \item {\em BusyBox} for the basic system
    \item {\em Dropbear} for SSH access (debugging)
    \item {\em Qt} with only {\em QtCore}, {\em QtNetwork} and {\em QtXml}, no GUI
    \item {\em QExtSerialPort}
    \item {\em zlib}, {\em libxml2}, {\em logrotate}, {\em pppd}, {\em
      strace}, a special RFID library, {\em popt} library
    \item The {\em Qt} application
    \item JFFS2 root filesystem
    \end{itemize}
  \item Filesystem size: 11 MB. Could be reduced by using {\em uClibc}.
  \item Build time: 10 minutes on a fast build server (quad-core i7,
    12 GB of RAM)
\end{itemize}

\end{frame}

\begin{frame}{Build time: real-world example 2}

  \begin{itemize}
  \item An x86-based system, with an OpenGL application for vehicle
    navigation system.
    \begin{itemize}
    \item External {\em glibc} toolchain generated with {\em
      crosstool-NG}
    \item The Grub bootloader
    \item {\em Linux kernel}, of course
    \item {\em BusyBox}
    \item A large part of the {\em X.org} stack (the server, a few
      drivers, and some client libraries), including {\em libdrm},
      {\em Mesa}
    \item The {\em fglrx} ATI proprietary OpenGL driver
    \item {\em ALSA utils}, {\em ALSA library}, {\em V4L library},
      {\em Flashrom}, {\em LM Sensors}, {\em Lua}, {\em Dropbear},
      {\em Ethtool}
    \item The OpenGL application and its data
    \end{itemize}
  \item Filesystem size: 95 MB, with 10 MB of application (binary +
    data) and 45 MB (!) of {\em fglrx} driver.
  \item Build time: 27 minutes on a fast build server (quad-core i7,
    12 GB of RAM)
  \end{itemize}
\end{frame}

\begin{frame}{Overall logic: preparation}

  Buildroot starts by:

  \begin{itemize}
  \item Creating all output directories
  \item Copying the {\em target root filesystem skeleton}, located in
    \path{fs/skeleton} in the source tree, into the \path{target/}
    output directory. This {\em skeleton} contains the basic
    directories and configuration files for the target
    system.\\
    One can specify, through a configuration option, a different
    skeleton.
  \end{itemize}

\end{frame}

\begin{frame}{Overall logic: toolchain}
  Buildroot continues by building the toolchain:
  \begin{itemize}
  \item For {\bf internal} toolchains, it extracts and builds the
    different elements (binutils, gcc, uClibc, etc.) in the
    \path{toolchain} directory, with {\em stamp} files to keep track
    of what has already been done. It installs the results in the
    \path{host/usr/} directory (for binaries) and
    \path{host/usr/<tuple>/sysroot} directory (for libraries and
    headers)
  \item For {\bf external} toolchains, Buildroot copies the original
    toolchain sysroot to the \path{host/usr/<tuple>/sysroot} directory
    and creates wrappers for the toolchain binaries in
    \path{host/usr/bin}
  \item For {\bf Crosstool-NG toolchains}, Buildroot installs {\em
      Crosstool-NG} in \path{host/}, and then uses it to generate a
    toolchain with binaries in \path{host/usr/bin} and sysroot in
    \path{host/usr/<tuple>/sysroot}.
  \end{itemize}
\end{frame}

\begin{frame}{Overall logic: packages (1/2)}
  \begin{itemize}
  \item Buildroot continues by building the packages. Packages
    encapsulate the build procedure of userspace libraries and
    programs but also the Linux kernel or bootloaders build
    procedures.
  \item The build method of each package is described using an
    infrastructure: {\bf AUTOTARGETS} for autotools-based packages,
    {\bf CMAKETARGETS} for CMake-based packages and {\bf GENTARGETS}
    for other packages.
  \item Buildroot follows the dependencies expressed in the package
    recipes, and triggers the configuration, compilation and
    installation steps as described in the recipes.
  \item ...
  \end{itemize}
\end{frame}

\begin{frame}{Overall logic: packages (2/2)}
  \begin{itemize}
  \item ...
  \item The package source code is extracted in
    \path{build/<pkg>-<version>/}, and {\em stamp} files are created
    after each step to let Buildroot know of what has already been
    done. Commands like \path{make <foo>-reconfigure} and
    \path{make <foo>-rebuild} allow to restart the build of a package
    if needed.
  \item Host packages are installed in \path{host/}, while target
    packages are installed in \path{target/} (usually stripped, no
    headers). Target libraries are also installed in
    \path{host/usr/<tuple>/sysroot} so that they are found by the
    cross-compiler (unstripped, with headers and static libraries)
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Packages: an overview of the internals}
  \tiny
  \begin{block}{}
\begin{verbatim}
$(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_downloaded:
      # downloads the package
      touch $@

$(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_extracted:
      # extracts the package
      touch $@

$(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_built:
      # builds the package
      touch $@

$(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_installed:
      # installs the package
      touch $@

<pkgname>-download:
           $(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_downloaded

<pkgname>-extract: <pkgname>-download
           $(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_extracted

<pkgname>-build: <pkgname>-extract
           $(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_built

<pkgname>-install: <pkgname>-build
           $(BUILD_DIR)/<pkgname>-<pkgversion>/.stamp_installed

<pkgname>: <pkgname>-install

TARGETS += <pkgname>
\end{verbatim}
  \end{block}

\end{frame}

\begin{frame}{Overall logic: root filesystem image}
  Finally, Buildroot generates the {\em root filesystem image(s)}:
  \begin{itemize}
  \item It uses {\em fakeroot} to generate this root filesystem image
    without having to be root
  \item A {\em makedevs} utility is used to adjust the file
    permissions and ownership, and to create device files if a static
    {\tt /dev} was chosen.
  \end{itemize}
\end{frame}

\begin{frame}{Source code organization}
  \begin{columns}
    \column{0.5\textwidth}
    \begin{itemize}
    \item {\bf board}, board-specific patches and
      configuration files
    \item {\bf boot}, bootloaders recipes
    \item {\bf configs}, default configuration files for various
      platforms. Same concept as kernel {\em defconfigs}
    \item {\bf docs}
    \item {\bf fs}, recipes for generating root filesystem images in
      various formats, and also root filesystem skeleton in {\bf
        fs/skeleton}
    \end{itemize}
    \column{0.5\textwidth}
    \begin{itemize}
    \item {\bf package}, all user-space packages (for the host and the
      target)
    \item {\bf support}, misc scripts and tools
    \item {\bf target}, legacy, almost empty directory
    \item {\bf toolchain}, toolchain handling code (build recipes for
      internal and Crosstool-NG back-ends, integration recipes for
      external toolchains)
    \end{itemize}
  \end{columns}
\end{frame}

\begin{frame}{Important files}
  \begin{itemize}
  \item {\bf Makefile}, the entry point of the build system. Handles
    the {\em kconfig} part, and the overall build logic. About 700
    lines.
  \item {\bf package/Makefile.package.in}, the {\em GENTARGETS}
    infrastructure. The core logic for building packages. About 700
    lines as well.
  \item {\bf package/Makefile.autotools.in} and {\bf
      package/Makefile.cmake.in} for the {\em AUTOTARGETS} and {\em
      CMAKETARGETS} infrastructures. Both inherit from {\em
      GENTARGETS}. Respectively 300 and 200 lines.
  \item {\bf fs/common.mk}, the common logic for building the root
    filesystem images.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Adding packages: configuration}

  \begin{itemize}
  \item Each package has its own directory in \path{package/}. Let's
    say \path{package/foo} for our package.

  \item A \path{package/foo/Config.in} file needs to be created to
    declare at least one configuration option for the package. The
    syntax is identical to the {\em kconfig} syntax:
\footnotesize
\begin{block}{}
\begin{verbatim}
config BR2_PACKAGE_FOO
        bool "foo"
        select BR2_PACKAGE_ZLIB
        help
          This is package foo

          http://foo-project.org
\end{verbatim}
\end{block}
\normalsize

\item This \path{package/foo/Config.in} file must be included from
  \path{package/Config.in}:
\footnotesize
\begin{block}{}
\begin{verbatim}
source "package/foo/Config.in"
\end{verbatim}
\end{block}
\end{itemize}
\end{frame}

\begin{frame}{Adding packages: writing the recipe}
  \begin{itemize}
  \item The recipe must be written in the \path{package/foo/foo.mk}
    file
  \item It consists of
    \begin{itemize}
    \item Variable declarations to define the package location,
      version, and the steps to be done to build the package.
    \item A call to one of the \path{AUTOTARGETS}, \path{GENTARGETS}
      or \path{CMAKETARGETS} macro to expand the package recipe
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Adding packages: minimal recipe}

\small
\begin{block}{Basic recipe for {\em autotools} based package}
\begin{verbatim}
FOO_VERSION = 1.3
FOO_SOURCE = foo-$(FOO_VERSION).tar.bz2
FOO_SITE = http://foo-project.org/downloads
FOO_DEPENDENCIES = zlib host-pkg-config

$(eval $(call AUTOTARGETS))
\end{verbatim}
\end{block}

The {\bf AUTOTARGETS} infrastructure:
\begin{itemize}
\item knows how to configure, build and install the package
\item handles the common cross-compilation issues with {\em autotools}
  based packages (libtool problems, passing the right arguments and
  environment variables to \path{./configure}, etc.).
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Adding packages: various source methods}

\begin{block}{From Git}
\begin{verbatim}
FOO_VERSION = this-branch
FOO_SITE = git://git.foo-project.org/foo.git
\end{verbatim}
\end{block}

\begin{block}{From Subversion}
\begin{verbatim}
FOO_VERSION = 12345
FOO_SITE = http://foo-project.org/svn/foo/trunk/
FOO_SITE_METHOD = svn
\end{verbatim}
\end{block}

\begin{block}{From a local directory}
\begin{verbatim}
FOO_SITE = /home/thomas/projects/foo/
FOO_SITE_METHOD = local
\end{verbatim}
\end{block}

And also from Mercurial, from Bazaar, etc.
\end{frame}

\begin{frame}[fragile]{Packages: adding a sub-configuration option}

\begin{block}{In Config.in}
\tiny
\begin{verbatim}
config BR2_PACKAGE_FOO
...

config BR2_PACKAGE_FOO_BZIP2_SUPPORT
        bool "enable bzip2 support"
        depends on BR2_PACKAGE_FOO
        select BR2_PACKAGE_BZIP2
        help
          Adds support for bzip2
\end{verbatim}
\normalsize
\end{block}

\begin{block}{In {\tt foo.mk}}
\tiny
\begin{verbatim}
...
ifeq ($(BR2_PACKAGE_FOO_BZIP2_SUPPORT),y)
FOO_CONF_OPT     += --enable-bzip2
FOO_DEPENDENCIES += bzip2
else
FOO_CONF_OPT     += --disable-bzip2
endif
...
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Packages: GENTARGETS}

  For packages that use a special build system (not autotools, not
  CMake).

\tiny
  \begin{block}{}
\begin{verbatim}
FOO_VERSION = 1.3
FOO_SOURCE = foo-$(FOO_VERSION).tar.bz2
FOO_SITE = http://foo-project.org/downloads
FOO_DEPENDENCIES = zlib

define FOO_CONFIGURE_CMDS
        echo "HAS_ZLIB=YES" >> $(@D)/config
endef

define FOO_BUILD_CMDS
        $(MAKE) -C $(@D) \
                CC="$(TARGET_CC)" CFLAGS="$(TARGET_CFLAGS)" \
                all
endef

define FOO_INSTALL_TARGET_CMDS
        $(INSTALL) -D -m 0755 $(@D)/foo $(TARGET_DIR)/usr/bin
endef

$(eval $(call GENTARGETS))
\end{verbatim}
\end{block}
\end{frame}

\begin{frame}{Packages: other important mechanisms}
  \begin{itemize}
  \item {\bf Patches} in the \path{package/foo} directory are automatically
    applied if they are named \path{<number>-<something>.patch} or
    \path{<version>/<number>-<something>.patch}
  \item Need to set \path{FOO_INSTALL_STAGING = YES} for {\bf packages
      that install libraries}, so that headers and static library are
    installed in the toolchain {\em sysroot}
  \item Can add {\em hooks} to {\bf execute custom actions}
    before/after the different steps, especially for {\em AUTOTARGETS}
    packages
  \item Can set \path{FOO_AUTORECONF = YES} for autotools-based
    package to {\bf autoreconfigure} them, useful when the
    \path{configure.ac} or \path{Makefile.am} files are patched.
  \item The {\bf documentation} contains tutorials and a reference
    with all
    details about the package infrastructure\\
    \path{docs/manual/manual.pdf}
  \end{itemize}
\end{frame}

\begin{frame}{Buildroot simplicity}
  \begin{itemize}
  \item After a configuration modification, Buildroot {\bf does not
      even try to apply the configuration changes} during the next
    \path{make} invocation.
  \item Tracking the consequences of configuration modifications is
    very complicated (when a toolchain setting is changed everything
    need to be rebuilt; when a library is removed, all reverse
    dependencies needs to be rebuilt)
  \item Buildroot remains simple: it {\bf simply executes the build
      procedure of the selected packages, and does not try to track
      the files installed by each package}.
  \item Relies on the {\bf user's knowledge} about the configuration
    change to know what needs to be done. Since building is very fast,
    full rebuilds are not problematic.
  \item This focus on simplicity is a {\bf very strong design
      decision} of Buildroot. Some features, such as binary packages
    generation, are not implemented in order to keep the build system
    simple.
  \end{itemize}
\end{frame}

\begin{frame}{Customizing for a project}
  Buildroot offers multiple mechanisms to handle all the
  particularities of a given project:
  \begin{itemize}
  \item A \path{board/<company>/<project>} directory to store all {\bf
      project-specific files}: kernel and bootloaders patches, scripts
    and configuration files, etc.
  \item Storage of the {\bf project configuration} as a minimal {\em
      defconfig} file in the \path{configs/} directory.
  \item A {\bf hookable post-build} script that gets called after all
    packages are installed but before the root filesystem image is
    created.
  \item The possibility of {\bf easily adding packages for custom
      software}, including software coming from local repositories or
    directories.
  \end{itemize}

  See the slides of the {\em Using Buildroot for real projects} talk
  given at the Embedded Linux Conference Europe 2011.
\end{frame}

\begin{frame}{Testing effort}
  Buildroot provides more than 2000 config options, which creates a
  huge number of possible configurations.
  \begin{itemize}
  \item Peter Korsgaard the maintainer, has a random configuration
    builder running 24/24 since more than a year, with an ARM
    toolchain, and we have 100\% successful builds, except when
    regression are introduced.
  \item I run from time to time random configuration builds on a
    random set of 30 toolchains for various architectures (ARM, AVR32,
    PowerPC, x86, x86-64, MIPS, Blackfin). The results are not as
    good, but mostly due to architecture-specific issues.
  \end{itemize}
\end{frame}

\begin{frame}{Future directions}
  \begin{itemize}
  \item Implement a mechanism for automatic generation of a {\em
      licensing} report, detailing all components used in the system
    and their license
  \item Add more packages for {\em SoC}-specific software (hardware
    codecs, 3D acceleration, special bootloaders)
  \item Improve the documentation with more tutorials
  \item Finalize the cleanup effort in the remaining areas
  \item Further increase the testing effort, and make the testing
    results publicly available
  \end{itemize}
\end{frame}

\begin{frame}{References}
  \begin{itemize}
  \item Website: \url{http://buildroot.org}
  \item Mailing-list: \path{buildroot@uclibc.org}\\
    \url{http://buildroot.org/lists.html}
  \item IRC channel: {\tt \#buildroot} on Freenode
  \item Bug tracker: \url{https://bugs.uclibc.org}
  \end{itemize}
\end{frame}

\begin{frame}{Conclusion}
  \begin{itemize}
  \item {\bf Nice} : uses well-known technologies and languages, {\em
      kconfig} and {\em make}. Active community.
  \item {\bf Simple} : only a few hundreds lines of code to understand
    the core infrastructure. Easy to get started, and easy to fully
    understand the internal mechanisms.
  \item {\bf Efficient} : very reasonable build times, only what's
    necessary gets built.
  \end{itemize}

  Of course, Buildroot is not suitable for {\em all} embedded Linux
  projects, but it is well adapted to industrial-like projects which
  have a limited number of software components and fixed
  functionality.
\end{frame}

\begin{frame}
  \begin{center}
  \Huge
  Questions?\\
  \vspace{1.5cm}
  \huge
  Thomas Petazzoni\\
  \large
  \vspace{0.5cm}
  \code{thomas.petazzoni@bootlin.com}
  \vspace{1.5cm}\\
  Slides under CC-BY-SA 3.0.
  \end{center}
\end{frame}

\end{document}
