This document describes one method to cross-compile the orocos toolchain. Unlike my previous method, the method described in this document does not make it necessary to cross-compile any of the supporting software libraries needed by orocos, like boost, libxml2 etc.
The method has been tested on hosts running Debian 7.0 (Wheezy), both amd64 and i386. The target computer (armel) is running the same Debian version. It is unlikely that this method will work on other distributions, but feel free to try ;-)
As of now, you cannot cross-compile typelib, corba and mqueue transports of any typekit you make. This is due to a limitation of the typelib build system, which is in the process of getting fixed. See this discussion and the Tips section below.
Step 1: Add the emdebian repo
apt-get install emdebian-archive-keyring cat "deb http://www.emdebian.org/debian squeeze main" > /etc/apt/sources.list.d/emdebian.sources.list apt-get update
Step 2: Cross-compiler toolchain and libraries
apt-get install g++-4.4-arm-linux-gnueabi gcc-4.4-arm-linux-gnueabi apt-get install xapt xapt -a armel -m libboost1.49-dev libboost-thread1.49-dev libboost-program-options1.49-dev libboost-filesystem1.49-dev libboost-iostreams1.49-dev libboost-graph1.49-dev libboost-regex1.49-dev libboost-system1.49-dev libxml2-dev libreadline6-dev libncurses5-dev libomniorb4-dev
Now you may need to do the following tweaks
Fix broken package dependencies
This will probably tell you something like
The following packages have unmet dependencies: g++-4.4-arm-linux-gnueabi : Depends: libstdc++6-4.4-dev-armel-cross (= 4.4.5-8) but 4.4.7-2 is installed.
it will offer to remove that package, but do not choose that solution when it says, "Accept this solution?" (press n). Then it'll offer to remove g++-4.4-armel-cross and downgrade listdc++-6-4.4-dev-armel-cross to 4.4.5-8 (stable). Accept this solution. Verify that no packages are broken with
You may have to
cd /usr/arm-linux-gnueabi/lib; ln -s libstdc++.so.6.0.17 libstdc++.so
You may also have to set some symlinks in /usr/arm-linux-gnueabi/include/c++. For example, I had to
cd /usr/arm-linux-gnueabi/include/c++ ln -s 4.4 4.4.5;
- You may have to replace all occurrences of TIME_UTC with TIME_UTC_ in /usr/arm-linux-gnueabi/include/boost/thread/xtime.hpp but hold off this step until the subsequent orocos-toolchain compilation process stops with an error related to xtime.hpp
Optional Step: Cross-compile xenomai
Skip this step if you are not going to use xenomai
cd <xenomai source dir> ./configure --host=arm-linux-gnueabi --prefix=/path/to/orocos-armel/install; make && make install
NOTE: /path/to/orocos-armel is where you will install the cross-compiled version of the orocos-toolchain in a subsequent step.
Optional step: qemu user emulation
This enables your host computer to transparently execute arm binaries
apt-get install qemu binfmt-support qemu-user-static
(Verify successful registration of formats with:)
update-binfmts --display add the line
EXTRA_OPTS="-L /usr/arm-linux-gnueabi" to /etc/qemu-binfmt.conf (create it if necessary)
cd /etc/qemu-binfmt/ ln -s /usr/arm-linux-gnueabi arm;
Step 3: Create cmake toolchain file
Add the following to a file and save it in $HOME/Toolchain-arm-linux-gnueabi.cmake
# this one is important SET(CMAKE_SYSTEM_NAME Linux) #this one not so much SET(CMAKE_SYSTEM_VERSION 1) # specify the cross compiler SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabi-gcc) SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabi-g++) # where is the target environment SET(CMAKE_FIND_ROOT_PATH /path/to/orocos-armel/install /usr/arm-linux-gnueabi) # search for programs in the build host directories SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # for libraries and headers in the target directories SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Note especially the line
SET(CMAKE_FIND_ROOT_PATH /path/to/orocos-armel/install /usr/arm-linux-gnueabi)
Edit the /path/to/orocos-armel/install as appropriate. This line tells CMake where to look for the cross-compiled libraries and its includes, and these paths are prepended to the regular CMake search path. It is important that these paths come BEFORE the regular search paths, else there is a chance of CMake picking up and using the native system libraries. The risk of this happening can be further lowered by the lines
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
which tell CMake to not look anythere except the specified paths for its headers and libs.
Step 4: (Cross+)Compile orocos-toolchain
First, we do a native install of the orocos toolchain. This will give us the orogen/typegen tools which we cannot build during the cross-compile.
cd /path/to/orocos-native; wget http://gitorious.org/orocos-toolchain/build/blobs/raw/toolchain-2.6/bootstrap.sh sh bootstrap.sh source env.sh echo "source /path/to/orocos-native/env.sh" >> $HOME/.bashrc
Now we build the cross-compiled version.
cd /path/to/orocos-armel; wget http://gitorious.org/orocos-toolchain/build/blobs/raw/toolchain-2.6/bootstrap.sh
Now edit bootstrap.sh and comment out the lines at the end as follows (this is intended to interrupt the bootstrapping process, so we can tweak some parameters. If this is not done, then a native install will occur.)
#autoproj update || tellfailupdate #autoproj fast-build || tellfailbuild
Now do the bootstrap sh bootstrap.sh
Edit the /path/to/orocos-armel/autoproj/manifest file ad comment out the orogen under the layouts section. This disables compilation of orogen. The layout section should look like
layout: - typelib - utilrb - utilmm - log4cpp - rtt - rtt_typelib # - orogen - ocl
The various software packages in the toolchain are built using CMake and we need to tell CMake to use the cross-toolchain. This is done by passing the flag
to CMake. To pass this flag everytime a package is built with CMake, add the following lines to $HOME/orocos/autoproj/overrides.rb (This information comes thanks to Thomas Roehr)
Note: Edit the path to the cross-toolchain file according to your setup.
Autobuild::Package.each do |name, pkg| if pkg.kind_of?(Autobuild::CMake) pkg.define "CMAKE_TOOLCHAIN_FILE","/home/sagar/Toolchain-arm-linux-gnueabi.cmake" end end
That's all. Now build the cross-toolchain as usual with source /path/to/orocos-armel/env.sh autoproj update autoproj build echo "source /path/to/orocos-armel/env.sh" >> $HOME/.bashrc
- My $HOME/.bashrc has
the following lines
source /home/sagar/excludes/orocos-native/env.sh source /home/sagar/excludes/armel-orocos/env.sh
- If you create a typekit with
orocreate-pkg MyTypekit typekit
Then you should know that the corba transport will NOT compile. This is probably due to the hosts omniidl being used or some such issue. Also, the typelib thingys will compile, but will probably cause the deployer to segfault on the target. As recommended by this discussion on the mailing list you should disable compilation of corba, mqueue and typelib. You can do this by editing the top level CMakeLists.txt file in the generate typekit folder. Find the line that starts with "orocos_typegen_headers(src/..." and edit it as
orocos_typegen_headers(-n corba,typelib,mqueue src/...