Adept Software

Embedded Linux

Many embedded Linux projects use an existing Linux distribution as the starting point. This has many advantages, such as easier software package installation and better integration testing. What we are talking about here is a populated root file system and the means to add additional software. If you don't know where to start, have a read through the Embedded Linux Wiki page. The following build environments can save you a lot of hassle.


Scratchbox uses a QEMU emulator to run a virtual-target on your host. This means that you are actually using a native compiler, not a cross-compiler, and you will not have any problems with tools getting confused with host packages. Scratchbox is used by Nokia on Maemo.


OpenEmbedded is great for creating your own distribution and includes tools to build a cross-compiler, create the root file system, build the kernel and build your desired software packages (10000+ are supported out of the box). However it takes a large amount of disk space and a long time to build everything. OpenEmbedded is used on the MontaVista distribution.


emdebian is a version of the debian distribution for embedded targets and as such should offer the simplest solution. However, currently a lot of packages cannot be cross-compiled so emdebian uses a compiler running on the target to build packages; this is far from perfect for development.


BuildRoot is probably the easiest to get started with. You can use BuildRoot to create a root file system, build your kernel and all software packages, though only relatively few packages are supported out of the box.

If you use one of the above build environments, most of your problems will be solved. However, sometimes you might feel the need to cross-compile a individual package. The rest of this page provides some general information on cross-compiling Linux packages for an embedded target. It assumes you are using a Linux host for development with a directory used as your target's root file system. This directory is typically used with TFTP and NFS servers so that your target can get the kernel image and access the files respectively.

Cross-compiling packages

Most software packages come with scripts to configure it for a particular target and in general it is simple to cross-compile a package. Many installation instructions simply state that you perform three steps:
make install
This is true if you aren't cross-compiling, in our case you need to do a few more things.

Most packages use pkgconfig to determine what software is already installed (i.e. what the new package can use), where it resides, and what options are needed to include and link with other packages. Most configure scripts support the --host= and --prefix= options that are crucial for cross-compiling. You set the --host= option to the name of the gcc toolchain, i.e. the name of the executable excluding the "-gcc" ending. This name is used for a number of tools, hence you only specify part of the compiler name. The --prefix= option is used to specify where the built software will be installed to. Usually the output consists of files in the /bin and /lib directories under the path specified, along with man pages and various other files.

pkgconfig uses two environment variables to determine where it looks for installed software, these are PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR. Of course, by default these are set up for your host's installed software, not your target's! PKG_CONFIG_PATH specifies the default path that contains the pkgconfig files whereas PKG_CONFIG_LIBDIR specifies additional directories that pkgconfig should look at. You can change these (normally just within a build script so you don't mess up installation of host packages) or you can use a chroot jail to make the system use a particular directory look like a new host. Setting the PKG_CONFIG_* vars is easy but doesn't fix cross-compilation for all packages. Setting up a chroot jail is easy enough, and should fix most cross-compilation problems, though to be honest we haven't spent enough time looking at this! You are still using a host environment, but it's clearly defined.

Here's an example shell script for cross-compiling using the SH toolchain:

# Make pkg-config use the target packages, not the hosts
export PKG_CONFIG_LIBDIR=${INSTALL_DIR}/lib/pkgconfig

./configure \ --host=sh4-linux-gnu \ --prefix=${INSTALL_DIR} make sudo make install

Note that this assumes that everything is installed under /usr/local in your target's file systems. In reality, there may be multiple installation directories used if you are not building everything yourself from scratch.

Common problems

In an ideal world, everything should just work. In reality software packages are written by different people who have different agendas. Some do not have the time to update to the latest and greatest build system whilst others are not using Linux at all. Here are some common problems and some tricks that may get you going.
sudo env PATH=$PATH make install
export CPPFLAGS="-I${INSTALL_DIR}/include"
export LDFLAGS="-L${INSTALL_DIR}/lib"
make \
    CC=sh4-linux-gnu-gcc \
    LIBS="-lz -lpng -ljpeg"
sudo make \
    DESTDIR=${A_LOCAL_DIR} install

Qt 4.5.2 Touchscreen, mice & keyboards

Here's a little bit about Qt input devices. Normally, you have a system with or without a touchscreen and it's not going to change. However, for some systems you may want the same code/script to run no matter what. In order to get a touchscreen and USB mouse working at the same time you need to do a few things.