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
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)
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)
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
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.
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 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.
2.3. Recommended packages
Shell: bash is recommended but not mandatory
3. Quick start guide
3.1. Download EmbToolkit
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
$ make xconfig or $ make menuconfig
|Qt based configuration GUI: see [prerequisites].|
|ncurses based configuration GUI: see [prerequisites].|
3.3. Start building your toolchain/root filesystem
This will start a long build process (so be patient) and will generate, depending on what was configured:
a root filesystem
3.4. Root filesystem rebuild after config change
$ make rootfs_build
4. EmbToolkit Toolchain
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
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 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.
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.
If you use EmbToolkit build system you can instrument your packages at build time as follow:
config EMBTK_EMBTK_FOO_USE_SCANBUILD bool "build with clang static analyzer" default y
$ make foo_install CONFIG_EMBTK_FOO_USE_SCANBUILD=y
Standard C libraries
EmbToolkit gives you the ability to generate toolchain based on one of the following standard C libraries:
Standard C++ libraries
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
|EmbToolkit does not support build of multilib toolchain.|
5. Generate a root filesystem
|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:
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 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
EmbToolkit build system also unconditionally includes, in the generated root filesystem, any binaries, sctipts and configuration files installed by packages in sysroot-<arch>/ hierarchy.
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.
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
#: indicates that you need to issue this command as root
yyy: depends on the architecture/cpu/variant used
|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.|
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
6. Expand EmbToolkit with a new package
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.
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.
Package sources can be:
tarball (with the ability to patch it)
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
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:
Add the following line in packages/net/net.kconfig
Add the following line in packages/net/net.mk, in case of target package
And in case of host package
|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 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" endchoice 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 config EMBTK_FOO_NEED_PATCH bool
|Allow user to enable or disable foo package in EmbToolkit configuration GUI.|
|Give user the ability to choose between two versions (0.16.4 and 0.14.2) of foo package|
|Make EmbToolkit build system aware of the version string selected.|
|Selected when a given version of the packahe needs to be patched.|
|Replace references to foo and FOO with the actual name of the package.|
All packages .kconfig should have at least these four configuration entries.
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.
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 select EMBTK_HAVE_BAR_OPTION1 help foo description.
|Instruct EmbToolkit to build bar as it is needed by foo|
|Instruct EmbToolkit to build bar with bar OPTION1 enabled as it is needed by foo|
The following kconfig entry is needed to configure a package named foo as waf based package.
config EMBTK_FOO_USE_WAF bool default y
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
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 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 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 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 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
|Create enrty in the configuration GUI giving ability to choose GIT|
|Create enrty in the configuration GUI giving ability to set GIT branch to use, instead of master|
|Create enrty in the configuration GUI giving ability to set GIT revision to checkout, instead of HEAD|
|Define the package class|
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 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 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 int "svn revision to checkout" depends on EMBTK_FOO_VERSION_SVN help Chechout specified svn revision config EMBTK_FOO_REFSPEC 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
|Create enrty in the configuration GUI giving ability to choose SVN|
|Create enrty in the configuration GUI giving ability to set SVN branch to use, instead of trunk|
|Create enrty in the configuration GUI giving ability to set SVN revision to checkout|
|Define the package class|
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 FOO_VERSION := $(call embtk_get_pkgversion,foo) FOO_SITE := http://www.foo.org/download FOO_PACKAGE := foo-$(FOO_VERSION).tar.gz FOO_SRC_DIR := $(embtk_pkgb)/foo-$(FOO_VERSION) FOO_BUILD_DIR := $(embtk_pkgb)/foo-$(FOO_VERSION)
|Set the package name. It is used internally in EmbToolkit build system|
|Set the package version. It is used internally in EmbToolkit build system (required for a tarball based package)|
|Set the package root URL. It is used to download the package tarball (if needed)|
|Set the package tarball file name (required for a tarball based package) to download from the root URL.|
|Set the package source directory name, after decompression of the package tarball (required for a tarball based package)|
|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.
|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
|Replace references to foo with the actual name of the package.|
Additional variables for other types of packages
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
|Replace references to foo with the actual name of 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.
You can make use of $(call embtk_decompress_pkg,foo) if the package sources are in a tarball.
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.).
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
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
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
|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
|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