EmbToolkit User Guide

EmbToolkit · Companion for your embedded system firmware

Download EmbToolkit v1.8.0

v1.8.0 Release note Older releases

EmbToolkit, here, means Embedded systems Toolkit.

EmbToolkit eases setup of necessary tools for embedded linux system development, including the root filesystem generation.
It generates toolchain/SDK based on traditional GNU tools (GCC, Binutils, etc.) and/or the newer clang/llvm compiler infrastructure.

Furthermore you have the choice to use one of supported C libraries:

EmbToolkit will be handy if you want to develop applications and generate firmware for a highly customized/specialized embedded linux product.
EmbToolkit is known to work and generate toolchain, build root filesystem under the following host development machines OS:

  • GNU/Linux based distributions

  • FreeBSD (other BSD may work, but not tested)

  • Mac OS X

Note

Most of prerequisites listed here are likely already installed in your distribution. This is a check list before reporting issue.

2.1. common prerequisites

In order to configure EmbToolkit and build your toolchain, you will need the following softwares (among others) installed on your host computer:

  • gcc or clang (or any other gcc compatible): C and C++ compilers

  • QT3 or QT4: development libraries and headers (if you want to use make xconfig for QT based configuration GUI)

  • ncurses: development libraries and headers (if you want to use make menuconfig for ncurses based configuration GUI)

  • gawk (not nawk: if you already have nawk installed, you must also install gawk)

  • bison

  • flex

  • texinfo

  • Subversion (if you want to build eglibc based toolchain)

  • git (if you want to build git version of some packages)

  • gnu make (GNU Make 3.81 or later)

  • patch

  • python

  • wget

And finally you must have enough free disk space in your host development machine (not the target).
At the moment of writing a full install of EmbToolkit (build of all packages, all supported programming
languages and eglibc used as C library) requires 5 GB of free disk space.

Please report any other prerequisites not listed here

2.2. Distributions specific prerequisites

Fedora

Beside the above prerequisites, under Fedora, you also need the following packages not installed by default:

  • libxi development package (library and headers).

  • XML::Parser perl module.

FreeBSD

Under FreeBSD make sure you have installed:

  • Gnu make and use gmake as command to build/rebuild etc…

Mac OS X

EmbToolkit can be used under Mac OS X with the following requirements:

  • EmbToolkit should be used in a case sensitive disk partition

Ubuntu

Ubuntu 12.04 LTS

Beside the above prerequisites, under Ubuntu as of 12.04 LTS, you also need the following packages not installed by default:

  • XML::Parser perl module.

  • Shell: bash is recommended but not mandatory

Warning
  • Do not run EmbToolkit as root on your host development machine.

  • Make sure you have all [prerequisites] installed prior trying to use EmbToolkit

3.1. Download EmbToolkit

To download EmbToolkit, you have two options:
  • Download the latest Embtoolkit stable version here.

  • Clone the git repository (you need to install git before of course):

$ git clone git://git.embtoolkit.org/embtoolkit.git embtoolkit.git
$ cd embtoolkit.git
$ git pull

3.2. Configure EmbToolkit

Two options to achieve the same goal
$ make xconfig     1
or
$ make menuconfig  2
1 Qt based configuration GUI: see [prerequisites].
2 ncurses based configuration GUI: see [prerequisites].

3.3. Start building your toolchain/root filesystem

$ make

This will start a long build process (so be patient) and will generate, depending on what was configured:

  • A toolchain/SDK

  • a root filesystem

3.4. Root filesystem rebuild after config change

$ make rootfs_build

EmbToolkit is versatile enough to allow generation of toolchain based on various components combination.
You can configure it, for example, to generate toolchain based on a one of supported C libraries associated
with one or both supported compiler infrastructures (clang/llvm and gcc).
The configuration of the toolchain takes place in Toolchain Configuration in the main GUI window.

4.1. How to use the toolchain

The toolchain generated by EmbToolkit is located in tools-<arch>/bin directory. Where <arch> depends on the architecture and the core CPU variant selected at EmbToolkit configuration time.

The toolchain is also packaged in a toolchain-xxx.tar.bz2 file located in generated/ directory, allowing its use outside of EmbToolkit. The packaged toolchain contains the following directories:

  • sysroot-<arch>: This directory contains SDK parts that will end up in your target root filesystem (C library, binaries, etc.) and development files (headers, static libraries, etc.)

  • tools-<arch>: This directory contains the toolchain components intended to run in your host development machine (compilers, static linker, etc.)

4.2. Components of the toolchain

Compiler infrastructures

EmbToolkit gives you the ability to choose to generate GCC or CLANG/LLVM based toolchain (cross compiler), or both.
This is a major change in cross compilation area and EmbToolkit is the first OpenSource build system allowing this.

GCC compiler infrastructure

gcc compiler infrastructure is the classical one supported by EmbToolkit.
Each version of gcc comes with patch set applied to the vanilla version, to ensure that the generated
toolchain has latest bug fixes available and that your are working with the best gcc toolchain available
for a given version.

CLANG/LLVM compiler infrastructure

The clang/llvm compiler infrastructure generated by EmbToolkit comes with some useful tools to help developers
to instrument the code they write, on ne example of such tools is the clang static analyzer.

Tip

If you use EmbToolkit build system you can instrument your packages at build time as follow:

  • In the package .kconfig file:

config EMBTK_EMBTK_FOO_USE_SCANBUILD                            1
        bool "build with clang static analyzer"
        default y
  • Or on command line while building the package:

$ make foo_install CONFIG_EMBTK_FOO_USE_SCANBUILD=y
1 replace FOO and foo with your package name

Standard C libraries

EmbToolkit gives you the ability to generate toolchain based on one of the following standard C libraries:

Standard C++ libraries

  • libstdc++

  • libc++ (only available for llvm/clang based toolchain)

Add debugging tools in the generated toolchain

  • GDB: The GNU Project Debugger

  • strace: trace system calls and signals

  • ltrace: library call tracer

Multilb toolchain

Note EmbToolkit does not support build of multilib toolchain.
Note EmbToolkit does not cover all types of root filesystem or partitioning on a flash device you may want.
Therefore the root filesystem generated must be considered to be there for testing purpose only.
However, nothing prevent you to customize how EmbToolkit generates root filesystem to fulfill your needs.
The whole root filesystem generation process is in core/mk/rootfs/rootfs.mk Makefile (see rootfs_build target).

Currently EmbToolkit supports build of the following root filesystem:

  • SquashFS

  • JFFS2

  • cpio: for initramfs

  • tar.bz2: for NFS root filesystem

5.1. Components of the root filesystem

The root filesystem generated by EmbToolkit mainly contains runtime libraries and other libraries and applications from packages.

Runtime libraries

Runtime libraries come from the toolchain C library and compiler runtime interface (libgcc, compiler-rt components, etc.). These libraries are needed for any binaries dynamically linked by the toolchain compiler from EmbToolkit. The build system will unconditionally include runtime libraries into the generated root filesystem. These files are mainly in sysroot-<arch>/lib/ and will be stored of course in /lib/ in the root filesystem

Libraries applications configuration file and scripts from packages

EmbToolkit build system also unconditionally includes, in the generated root filesystem, any binaries, sctipts and configuration files installed by packages in sysroot-<arch>/ hierarchy.

Root filesystem layout

EmbToolkit build system follows Filesystem Hierarchy Standard as much as possible.

5.2. NFS root filesystem

NFS root filesystem is extremely useful in application and library development phase. Indeed, no need to flash new firmware in the target device after only few changes on the code being developed. Just copy the new library/application in NFS server directory mounted and it is available in the target device.

Mount NFS root filesystem from EmbToolkit .tar.bz2 file

Assuming you have your NFS serveur top level directory in /nfsroot, you have board named wonderful-board and EmbToolkit located at /home/me/embtoolkit-xxx (where xxx is the version of EmbToolkit). Setting up NFS root filesystem can be done as follow:

$ cd /nfsroot
# mkdir wonderful-board
# cd wonderful-board
# tar xjvf /home/me/embtoolkit-xxx/generated/rootfs-yyy.tar.bz2

where:

  • #: indicates that you need to issue this command as root

  • yyy: depends on the architecture/cpu/variant used

Caution EmbToolkit .tar.bz2 contains exactly what need to be in / (the top level directory) of your target root filesystem. It contains /bin, /dev, /etc, /home, /lib, /mnt, /opt, /proc, /root, /sbin, /sys, /tmp, /usr, /var directories. DO NOT decompress it from your host development machine / (top level) directory.
Kernel command line example
root=/dev/nfs rw nfsroot=192.168.1.100:/nfsroot/wonderful-board ip=dhcp console=ttyS0 init=/sbin/init

Where 192.168.1.100 is the NFS server ip address

Tip
To quickly get started

You can take a look in EmbToolkit packages/ directory, to see the shape of packages already included and especially this template.

EmbToolkit package types

In EmbToolkit, there are two kinds of packages:

  • Packages intended to run on targeted embedded system: they will be named simply package in this documentation.

  • Packages intended to run on the host development machine: usually required to build the former or generate the root filesystem. They will be named host package in this documentation.

These two kinds of packages can be autotools, waf, or Makefile based or a custom package with special build steps requirements.

EmbToolkit package sources

Package sources can be:

  • tarball (with the ability to patch it)

  • GIT repository

  • SVN repository.

EmbToolkit package files

EmbToolkit build system is designed in a way that, for each built package, it needs two files.
Imagine we want to add a package named foo, we need to create two files:

  • foo.kconfig: a configuration file which uses the simple linux kernel kconfig language

  • foo.mk: a Makefile which will be included in the EmbToolkit build system

All packages in EmbToolkit are based on this scheme, from the toolchain components (GCC, Binutils, eglibc, uClibc etc.),
to busybox and other highly configurable packages (such as Gtk+ and xorg-server).
This shows the robustness and versatility of EmbToolkit build system, without a high level of complexity (the goal being to be as simple as possible).

6.1. First step for new package inclusion

Determinate your package category/class

The first step before starting to write .mk and .kconfig files for a new package is to determinate your package class/category.
Each subdirectory in EmbToolkit packages/ corresponds to a so called package class (for example net, database, etc.).

For example if you want to add a new package named foo among net packages, you must:

Create the two needed files
packages/net/foo/foo.mk
packages/net/foo/foo.kconfig
Include these two in EmbToolkit build system

Add the following line in packages/net/net.kconfig

source packages/net/foo/foo.kconfig

Add the following line in packages/net/net.mk, in case of target package

$(call embtk_include_pkg,foo)

And in case of host package

$(call embtk_include_hostpkg,foo)
Note Replace references to foo with the actual name of the package and net with the actual package class.

6.2. Writing a .kconfig config file

The .kconfig file is a configuration file, It gives details about the package displayed in EmbToolkit confuguration GUI.
This file syntax is the same as linux kconfig, see here for more details.
It is also used to enable, disable or set default options for a given package.

Here is an example of .kconfig file for a package named foo (foo.kconfig):

config EMBTK_HAVE_FOO           1
        bool "Have foo"
        help
         foo description.

choice                          2
        prompt "foo version you wish"
        depends on EMBTK_HAVE_FOO
        help
         Here you can choose which version of foo you want to use.

        config  EMBTK_FOO_VERSION_0_16_4
                bool "foo-0.16.4"
        config  EMBTK_FOO_VERSION_0_14_2
                bool "foo-0.14.2"
endchoice

config EMBTK_FOO_VERSION_STRING 3
        string
        default "0.16.4"        if EMBTK_FOO_VERSION_0_16_4
        default "0.14.2"        if EMBTK_FOO_VERSION_0_14_2

config EMBTK_FOO_NEED_PATCH     4
        bool
1 Allow user to enable or disable foo package in EmbToolkit configuration GUI.
2 Give user the ability to choose between two versions (0.16.4 and 0.14.2) of foo package
3 Make EmbToolkit build system aware of the version string selected.
4 Selected when a given version of the packahe needs to be patched.
Note Replace references to foo and FOO with the actual name of the package.

All packages .kconfig should have at least these four configuration entries.

Add configuration options in a package

A configuration option may be used to enable or disable a feature in a package.
This is achieved usually by adding bool kconfig entry.

For example a foo package may implement option1, disabled by default. To add a configuration entry allowing to enable it,
you could add (just under EMBTK_HAVE_FOO bool entry):

config EMBTK_HAVE_FOO_OPTION1
        bool "Enable option1"
        help
         If you say Y here you will have option1 enabled in foo.
Configure package dependencies

When a package has a strong dependency on some other packages (already included in EmbToolkit), these other packages
must be selected.

For example if package foo depends on package bar, with package bar OPTION1 enabled, you could insert the following outlined kconfig entries in foo.kconfig:

config EMBTK_HAVE_FOO
        bool "Have foo"
        select EMBTK_HAVE_BAR         1
        select EMBTK_HAVE_BAR_OPTION1 2
        help
         foo description.
1 Instruct EmbToolkit to build bar as it is needed by foo
2 Instruct EmbToolkit to build bar with bar OPTION1 enabled as it is needed by foo
Configure a waf based package

The following kconfig entry is needed to configure a package named foo as waf based package.

config EMBTK_FOO_USE_WAF
        bool
        default y
Configure a package needing a patch

If package foo needs to be patched, just enable the bool kconfig indicating it needs it as follow
in the version kconfig entry:

        ....
        ....
        config  EMBTK_FOO_VERSION_0_14_2
                bool "foo-0.14.2"
                select EMBTK_FOO_NEED_PATCH
Configure autotools based package needing configure script (re)generation

Explain how….

Add ability to use GIT repository

Here is the same example as the previous foo package, with this time GIT configuration options added:

config EMBTK_HAVE_FOO
        bool "Have foo"
        help
         foo description.

choice
        prompt "foo version you wish"
        depends on EMBTK_HAVE_FOO
        help
         Here you can choose which version of foo you want to use.

        config  EMBTK_FOO_VERSION_0_16_4
                bool "foo-0.16.4"
        config  EMBTK_FOO_VERSION_0_14_2
                bool "foo-0.14.2"
        config EMBTK_FOO_VERSION_GIT                           1
                bool "Use foo git repository"
                help
                 Say Y here to use foo development version from its git repository.
endchoice

#
# FOO repository options
#
config EMBTK_FOO_GIT_BRANCH                                    2
        string "Branch to use"
        default "master"
        depends on EMBTK_FOO_VERSION_GIT
        help
         The branch of the git repository to use, the default is master.

config EMBTK_FOO_GIT_REVISION                                  3
        string "Checkout a specific revision instead of the latest"
        depends on EMBTK_FOO_VERSION_GIT
        help
         Chechout a specific revision instead of the latest.

config EMBTK_FOO_REFSPEC                                       4
        string
        default "net"

config EMBTK_FOO_VERSION_STRING
        string
        default "0.16.4"        if EMBTK_FOO_VERSION_0_16_4
        default "0.14.2"        if EMBTK_FOO_VERSION_0_14_2
        default "git"           if EMBTK_FOO_VERSION_GIT       5
1 Create enrty in the configuration GUI giving ability to choose GIT
2 Create enrty in the configuration GUI giving ability to set GIT branch to use, instead of master
3 Create enrty in the configuration GUI giving ability to set GIT revision to checkout, instead of HEAD
4 Define the package class
5 Optional

Add ability to use SVN repository

Here is the same example as the previous foo package, with this time SVN configuration options added:

config EMBTK_HAVE_FOO
        bool "Have foo"
        help
         foo description.

choice
        prompt "foo version you wish"
        depends on EMBTK_HAVE_FOO
        help
         Here you can choose which version of foo you want to use.

        config  EMBTK_FOO_VERSION_0_16_4
                bool "foo-0.16.4"
        config  EMBTK_FOO_VERSION_0_14_2
                bool "foo-0.14.2"
        config EMBTK_FOO_VERSION_SVN                           1
                bool "Use foo svn repository"
                help
                 Say Y here to use foo development version from its svn repository.
endchoice

#
# FOO repository options
#
config EMBTK_FOO_SVN_BRANCH                                    2
        string "Branch to use"
        default "trunk"
        depends on EMBTK_FOO_VERSION_SVN
        help
         The branch of the svn repository to use, the default is trunk.

config EMBTK_FOO_SVN_REVISION                                  3
        int "svn revision to checkout"
        depends on EMBTK_FOO_VERSION_SVN
        help
         Chechout specified svn revision

config EMBTK_FOO_REFSPEC                                       4
        string
        default "net"

config EMBTK_FOO_VERSION_STRING
        string
        default "0.16.4"        if EMBTK_FOO_VERSION_0_16_4
        default "0.14.2"        if EMBTK_FOO_VERSION_0_14_2
        default "svn"           if EMBTK_FOO_VERSION_SVN       5
1 Create enrty in the configuration GUI giving ability to choose SVN
2 Create enrty in the configuration GUI giving ability to set SVN branch to use, instead of trunk
3 Create enrty in the configuration GUI giving ability to set SVN revision to checkout
4 Define the package class
5 Optional

6.3. Writing a .mk Makefile

The .mk file is a regular GNU Makefile, it is used to instruct EmbToolkit build system how to
download, build, install and clean a package.

EmbToolkit build system defines some useful variables/macros that may/must be used in a package .mk file, espacially in case of
Makefile based packages or custom packages.

Here is some of them outlined:

  • $(embtk_pkgb)/ : working directory where EmbToolkit decompresses packages intended to run on the target

  • $(embtk_toolsb) : working directory where EmbToolkit decompresses host development packages

  • $(embtk_sysroot)/ : directory where EmbToolkit installs target libraries, binaries, development files etc

  • $(embtk_tools)/ : directory where EmbToolkit installs the toolchain (compilers, static linker etc.).

  • $(embtk_htools)/ : directory where EmbToolkit installs host development packages.

  • $(embtk_generated)/ : directory where EmbToolkit places useful outputs (root filesystem, packaged toolchain, etc.)

  • $(embtk_dldir)/ : directory where EmbToolkit places downloaded files (patch, tarball, etc.)

  • $(call embtk_get_pkgversion,xxx) : retrieve version string of package xxx, defined in its .kconfig file

Here is an example of .mk file for a package named foo (foo.mk):

FOO_NAME        := foo                               1
FOO_VERSION     := $(call embtk_get_pkgversion,foo)  2
FOO_SITE        := http://www.foo.org/download       3
FOO_PACKAGE     := foo-$(FOO_VERSION).tar.gz         4
FOO_SRC_DIR     := $(embtk_pkgb)/foo-$(FOO_VERSION)  5
FOO_BUILD_DIR   := $(embtk_pkgb)/foo-$(FOO_VERSION)  6
1 Set the package name. It is used internally in EmbToolkit build system
2 Set the package version. It is used internally in EmbToolkit build system (required for a tarball based package)
3 Set the package root URL. It is used to download the package tarball (if needed)
4 Set the package tarball file name (required for a tarball based package) to download from the root URL.
5 Set the package source directory name, after decompression of the package tarball (required for a tarball based package)
6 Set the build directory of the package (optional)

The above variables are all you need, in a .mk file, to make EmbToolkit build system download compile and install
an autotools based package using a tarball as source. In the following sections we will see what may/should be
added to build for example from GIT repository and more.

Note Replace references to foo and FOO with the actual name of the package.

Additional variables for Makefile based package

EmbToolit supports build of external Makefile based package that has an install target.
To build a such package, named foo for example, you need to define the following variable (in foo.mk):

define embtk_install_foo
        $(call embtk_makeinstall_pkg,foo)
endef
Note Replace references to foo with the actual name of the package.

Additional variables for other types of packages

Custom packages build

EmbToolkit supports build of packages that are neither autotools based nor Makefile based, nor waf based
as long as you define steps to download, build and install them.

To build a such package, named foo for example, you need to define the embtk_install_foo macro and add all needed steps within.
EmbToolkit .mk files are GNU Makefile, you can do the same things you would do in a regular GNU Makefile.

define embtk_install_foo
        $(call embtk_download_pkg,foo)
        $(call embtk_decompress_pkg,foo)
        ...
        ...
        ...
endef
Note Replace references to foo with the actual name of the package.
To download the package

You can make use of $(call embtk_download_pkg,foo) if the package sources are in a tarball, GIT repository, or SVN repository.

To decompress the package

You can make use of $(call embtk_decompress_pkg,foo) if the package sources are in a tarball.

To compile/build the package

As said earlier, .mk files are regular GNU Makefile so you can use any shell command and variables already defined by EmbToolkit build system (such as $(embtk_pkgb), $(embtk_toolsb), etc.).

To install the package

You can use any shell command (usually install or cp) with EmbToolkit build system defined variables:

  • $(embtk_sysroot)/: for a target package, postfix usr/bin or usr/lib, etc… to this variable to install its components.

  • $(embtk_htools)/ : for a host package, postfix usr/bin or usr/lib, etc… to this variable to install its components.

Variables you may/should define in .mk file

Installed libraries, binaries and other files linsting:

In the following variables you should list file names (name only, not absolute path name) installed by a package
in various $(embtk_sysroot)/ subdirectories.

  • FOO_BINS : list of files installed in $(embtk_sysroot)/usr/bin by foo package

  • FOO_SBINS : list of files installed in $(embtk_sysroot)/usr/sbin by foo package

  • FOO_ETC : list of files installed in $(embtk_sysroot)/etc by foo package

  • FOO_INCLUDES : list of files installed in $(embtk_sysroot)/usr/include by foo package

  • FOO_LIBS : list of files installed in $(embtk_sysroot)/usr/lib by foo package

  • FOO_LIBEXECS : list of files installed in $(embtk_sysroot)/usr/libexec by foo package

  • FOO_PKGCONFIGS : list of files installed in $(embtk_sysroot)/usr/lib/pkconfig and $(embtk_sysroot)/usr/share/pkconfig by foo package

  • FOO_SHARES : list of files installed in $(embtk_sysroot)/usr/share by foo package

Package build options variables:

The following variables instruct EmbToolkit build system how to configure, compile, install a package.

  • FOO_CFLAGS : additional C compiler flags for foo package

  • FOO_CXXFLAGS : additional C++ compiler flags for foo package

  • FOO_CPPFLAGS : additional C preprocessor flags for foo package

  • FOO_LDFLAGS : additional linker flags for foo package

  • FOO_SET_RPATH : set this variable to y if you want rpath set in a foo host package binaries

  • FOO_CONFIGURE_DIR : name of the directory where to find autotools or waf configure script (when not in standard location)

  • FOO_CONFIGURE_ENV : additional autotools or waf configure script env for foo package

  • FOO_CONFIGURE_OPTS : autotools or waf configure script options for foo package (ie. --enable-xxx --disable-yyy --with-zzz)

  • FOO_MAKE_ENV : additional env to set while invoking make for foo package

  • FOO_MAKE_OPTS : additional command line variables to set while invoking make for foo package

  • FOO_MAKE_DIRS : directories, within foo package, where EmbToolkit build system should invoke make (seldom needed)

  • FOO_DEPS : list here foo package dependencies. if foo depends on bar, you should set here bar_install

Note Replace references to FOO with the actual name of the external package.

6.4. Host packages special case

In EmbToolkit there is a convention, with some exceptions, where all host packages are named
PACKAGENAME_HOST and packagename_host, in .kconfig and .mk files.

So in the above examples, in case of host package, replace all references to FOO with FOO_HOST, and While invoking
EmbToolkit build system macros, such as $(call embtk_download_pkg,foo), $(call embtk_get_pkgversion,foo) replace references to foo with foo_host

Note Replace references to FOO and foo with the actual name of the package.

6.5. Build the package just added

Each package in EmbToolkit can be built separately from other build processes.

For example to build the new package named foo, issue the following command in EmbToolkit root directory:

$ make foo_install