Skip to content

Instantly share code, notes, and snippets.

@simark
Last active February 2, 2016 18:06
Show Gist options
  • Save simark/1167861bfabe21dd7658 to your computer and use it in GitHub Desktop.
Save simark/1167861bfabe21dd7658 to your computer and use it in GitHub Desktop.
OLA cross compile
# Terminology
Throughout this document, "host" refers to the build machine and "target"
refers to the machine where OLA will run. Note that this does not match
Autoconf's terminology, where "host" means the machine where things will run.
During the process, we will need to build some things that will run on the host
machine, and others that will run on the target machine. We will therefore
work with two separate terminals, one set up to build things for each. I'll
refer to those as "host terminal" and "target terminal".
# Scope
I am only building the strict minimum of OLA. If you want additional features
or plugins that requires other libraries (e.g. libmicrohttpd, libusb), you will
have to install or build those dependencies as well.
Every embedded platform is different and has its own particularities. You'll
likely have to adapt these instructions to your specific case. So please try
to understand what I am trying to do and ask yourself if that makes sense in
your environment or if there might be a better way. Do not just copy paste
commands.
I am using the Raspbian Jessie Lite image [1] and the provided toolchain [2] as
a starting point. To keep these instructions generic, I build the OLA
dependencies by hand instead of using the pre-built Debian package. However,
if your distribution does offer packages for those libraries, it would be a
good idea to use them instead.
# Prerequisites
It is expected that you already have a working cross-toolchain, including your
system's root filesystem (sysroot).
# Overview
The steps to cross-compile OLA are the following:
1. Compile protobuf for the host machine
2. Compile protobuf for the target machine
3. Compile libuuid for the target machine
3. Compile OLA's protoc plugin for the host machine
4. Compile OLA for the target machine
# Environment
In my working directory, I use the following layout:
- src: sources
- build: build
- host: install path for host tools
If the platform/SDK you use provides some kind of "environment-setup" script,
use that. It will set all the necessary flags and paths for cross-compilation
to work. Note that these scripts need to be "sourced" in your shell (using
"source <script name>" and not simply executed.
If there is no such script, you can make one yourself and use the provided
env-target.sh as an inspiration. Again, make sure that the values used make
sense in your environment. Throughout the document, I refer to some variables
defined at the top of these files, so take that into consideration when you
type commands.
I made one for the host as well (env-host.sh), even though it's much simpler.
# Compilation
## Compile protobuf for the host
We first need to build a copy of protobuf that will run on the host. The OLA
build needs to run the protoc tool to process some .pb files to C++ source code
(foo.pb generates foo.pb.h and foo.pb.cc). If you use a packaged version of
protobuf, you'll need to make sure that the protoc version on your host matches
the version of the library on your target.
So, in you host terminal:
workdir/src $ wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.bz2
workdir/src $ tar -xf protobuf-2.6.1.tar.bz2
workdir/src $ cd ../build
workdir/build $ mkdir protobuf-2.6.1-host && cd protobuf-2.6.1-host
workdir/build/protobuf-2.6.1-host $ ../../src/protobuf-2.6.1/configure --prefix=$WORKDIR/host
workdir/build/protobuf-2.6.1-host $ make
workdir/build/protobuf-2.6.1-host $ make install
## Compile protobuf for the target
We will now build the version of protobuf that will run on the target system.
In your target terminal:
workdir/build $ mkdir protobuf-2.6.1-target && cd protobuf-2.6.1-target
workdir/build/protobuf-2.6.1-target $ ../../src/protobuf-2.6.1/configure --host=$ARCH --with-protoc=$WORKDIR/host/bin/protoc
workdir/build/protobuf-2.6.1-target $ make
workdir/build/protobuf-2.6.1-target $ make install DESTDIR=$SYSROOT
Because of libtool limitations [3], we just need to adjust one thing. In each .la files in $SYSROOT/usr/local/lib, there is a line that says:
libdir='/usr/local/lib'
That would be good if we wanted to use that library to build some stuff
natively, directly on the target in the future. But that's not our case. If
we leave it like this, libtool will complain when we build OLA, and you might
get an error if you have the same lib in your host's /usr/local/lib. Change it
for {SYSROOT}/usr/local/lib, replacing {SYSROOT} with your actual sysroot.
This can be done with a sed command:
$ sed -i "s;libdir='/usr/local/lib';libdir='$SYSROOT/usr/local/lib';" $SYSROOT/usr/local/lib/*.la
## Compile libuuid for the target
libuuid is part of the util-linux package. It is a rather core lib, so if you
use a distribution, it is most likely available as a package. Otherwise, in
your terminal target:
workdir/src $ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.27/util-linux-2.27.1.tar.xz
workdir/src $ tar -xf util-linux-2.27.1.tar.xz
workdir/build $ mkdir util-linux-2.27.1-target && cd util-linux-2.27.1-target
workdir/build/util-linux-2.27.1-target $ ../../src/util-linux-2.27.1/configure --host=arm-linux-gnueabihf --disable-all-programs --enable-libuuid --without-python --prefix=/usr/local
...
workdir/build/util-linux-2.27.1-target $ make
...
workdir/build/util-linux-2.27.1-target $ make install DESTDIR=$SYSROOT
...
We have to do the same little hack as with protobuf, which is to edit the .la
file and change the libdir line. You can run the sed line again.
$ sed -i "s;libdir='/usr/local/lib';libdir='$SYSROOT/usr/local/lib';" $SYSROOT/usr/local/lib/*.la
## Compile OLA for the host
We now need to build the host part of OLA. We don't need to build the whole
thing, just the OLA protoc plugin. It is a small executable which protoc loads
in order to generate some OLA specific bits. In the host terminal:
workdir/src $ wget https://github.com/OpenLightingProject/ola/releases/download/0.10.0/ola-0.10.0.tar.gz
workdir/src $ tar -xf ola-0.10.0.tar.gz
workdir/src $ cd ../build
workdir/build $ mkdir ola-0.10.0-host && cd ola-0.10.0-host
workdir/build/ola-0.10.0-host $ ../../src/ola-0.10.0/configure --disable-all-plugins --with-protoc=$WORKDIR/host/bin/protoc
workdir/build/ola-0.10.0-host $ make protoc/ola_protoc_plugin
We are not going to use protoc itself for this step, so it's not really
necessary to specify --with-protoc, but configure still looks for it. So if
you don't have a protoc anywhere else on your system and you don't specify
--with-protoc, configure will complain.
## Compile OLA for the target
We are now getting to the real stuff. Here, I am just building the dummy
plugin, but you'll obviously want to enable other, more useful plugins. In the
target terminal:
workdir/build $ mkdir ola-0.10.0-target && cd ola-0.10.0-target
workdir/build/ola-0.10.0-target $ ../../src/ola-0.10.0/configure --host=arm-linux-gnueabihf --with-protoc=$WORKDIR/host/bin/protoc --with-ola-protoc-plugin=$WORKDIR/build/ola-0.10.0-host/protoc/ola_protoc_plugin --disable-all-plugins --disable-unittests --enable-dummy
workdir/build/ola-0.10.0-target $ make
workdir/build/ola-0.10.0-target $ make install DESTDIR=$SYSROOT
[1] https://www.raspberrypi.org/downloads/raspbian
[2] https://github.com/raspberrypi/tools
[3] http://www.metastatic.org/text/libtool.html
WORKDIR=/home/simark/ola-cross-compile
export PKG_CONFIG_PATH="$WORKDIR/host/lib/pkgconfig"
SYSROOT=/mnt/rpi
WORKDIR=/home/simark/ola-cross-compile
TOOLCHAIN=/home/simark/src/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64
ARCH=arm-linux-gnueabihf
export ac_cv_func_malloc_0_nonnull=yes
export ac_cv_func_realloc_0_nonnull=yes
export PATH=$TOOLCHAIN/bin:$PATH
export CFLAGS="--sysroot=$SYSROOT"
export CXXFLAGS="--sysroot=$SYSROOT"
export LDFLAGS="--sysroot=$SYSROOT"
export CONFIGURE_FLAGS="--host=$ARCH"
export PKG_CONFIG_LIBDIR="$SYSROOT/usr/lib/pkgconfig:$SYSROOT/usr/local/lib/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR="$SYSROOT"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment