Note: This tutorial is outdated, for the current version see nao/Tutorials/Cross-Compiling.
(!) Please ask about problems and questions regarding this tutorial on Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Cross-Compiling ROS for the Nao (cturtle on NaoQI 1.6)

Description: This tutorial covers the steps necessary for cross-compiling ROS cturtle for the Nao's AMD Geode platform (NaoQI 1.6).

Keywords: Nao, Cross-compile

Tutorial Level: INTERMEDIATE


This page explains how to setup ROS to run on the humanoid robot Nao. Note that the steps here haven't been tested on many machines yet. If you try this out for yourself, be kind and take notes of any flaws in this guide and update this page accordingly. This tutorial follows mostly the GumROS tutorial for the compilation of the non-ROS packages.

We are going to cross-compile ROS for the nao platform with a geode CPU. As the geode is x86 CPU this is not definitly necessary for getting ROS running on the Nao - you can just copy binaries from another x86 machine if the dynamically linked libraries are of the same versions. As this is not always the case, cross-compiling is the preferred way. Nao's operating system is stored on a removable USB-stick. We are going to install ROS to the same stick at the path


Make sure that you have enough space left on the stick. In our lab, we replaced the original 2GB USB stick with an 8 GB USB stick by Transcend. I will only explain how to compile the ROS base system, which should also fit onto the original stick. If you want to store ROS to a different path, make appropriate adjustments to the instructions below. Make sure that this path exists on your build machine and that you own the appropriate directory with all its subdirectories, otherwise you could encounter errors during installation. Once ROS is installed, you cannot move it unless you recompile it, because the paths to libraries are stored in the binaries.


You need Aldebaran's Nao SDK (SDK), at least version 1.6.0 and Aldebaran's Cross-Compile-Toolkit (CTC), at least version 1.6.0. Aldebaran provides a toolchain for cross-compiling cmake based projects for the Nao platform. This comes very handy when cross-compiling ROS, as it is also cmake-based. However, ROS depends on a few libraries which we need to build before we can start with the actual cross-compilation of ROS. These libraries however use automake, hence the cmake toolchain provided by Aldebaran is not applicable. Instead, we need to set some environment variables used by automake. You can save the following commands to a shell script, adjust it according to your setup and execute it.

# some basic settings
export TARGETDIR=/media/external #this is where ROS will be installed to, see below
export ROS_ROOT=$TARGETDIR/ros/ros # ROS_ROOT, as usual
export ROS_PACKAGE_PATH=$ROS_ROOT/../stacks # ROS_PACKAGE_PATH, as usual
export CTC_DIR=/path/to/ctc-academics-1.6.13 # path to Aldebaran's cross-compilation toolchain
export ROS_DEPS=$ROS_ROOT/../ros-deps/
export CTC_USR_DIR=$CTC_DIR/staging/geode-linux/usr/
export CTC_BIN_DIR=$CTC_DIR/cross/geode/bin
export PYTHONPATH=$ROS_ROOT/core/roslib/src
export CPATH=$ROS_ROOT/../ros-deps/include/
export GEODE_CXX=$CTC_DIR/cross/geode/bin/i586-linux-g++
export GEODE_CC=$CTC_DIR/cross/geode/bin/i586-linux-gcc
export PATH=$CTC_BIN_DIR:$ROS_ROOT/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# automake compiler/linker flags
export LDFLAGS="-Wl,--sysroot,$CTC_DIR/staging/geode-linux/ -lgcc -L$CTC_DIR/cross/geode/i586-linux/lib/ -L$CTC_DIR/staging/geode-linux/usr/lib  -lc -lstdc++ -ldl"
export CPPFLAGS="--sysroot /$CTC_DIR/staging/geode-linux/ -I/$CTC_DIR/staging/geode-linux/usr/include/ -I/$CTC_DIR/cross/geode/lib/gcc/i586-linux/4.3.3/include/ -I/$CTC_DIR/staging/geode-linux/usr/include/c++/ -I/$CTC_DIR/staging/geode-linux/usr/include/c++/i586-linux/ -I/$CTC_DIR/cross/geode/i586-linux/include/c++/ -I/$CTC_DIR/cross/geode/i586-linux/include/c++/backward/ -I/$CTC_DIR/cross/geode/i586-linux/include/c++/i586-linux -I/$CTC_DIR/cross/geode/i586-linux/include/ -I/$CTC_DIR/staging/geode-linux/usr/lib"
export CFLAGS="-march=geode"
export CXXFLAGS="-march=geode"

Cross-Compiling of non-ROS modules

Download them to whatever location you want but you need to use the environment setup from above and sepcify the right prefix path. This is where the packages will end up.

First, we build apr.

extract the package and cd into the new directory
./configure --prefix=$ROS_DEPS --disable-shared --enable-static CC=$GEODE_CC --host=i586-linux
make && make install
cd ..

Next we compile apr-utils

extract the package and cd into the new directory
./configure --prefix=$ROS_DEPS  --with-apr=$ROS_DEPS/apr-1.4.2 --with-expat=builtin CC=$GEODE_CC --host=i586-linux --without-pgsql --without-sqlite2 --without-sqlite3 \
ac_cv_file__dev_zero=yes \
ac_cv_func_setpgrp_void=yes \
apr_cv_tcp_nodelay_with_cork=no \
apr_cv_process_shared_works=no \
apr_cv_mutex_robust_shared=no \
make && make install
cd ..

If you experience errors like

ctc-academics-1.6.13/cross/geode/bin/../lib/gcc/i586-linux/4.3.3/../../../../i586-linux/bin/ld: crti.o: No such file: No such file or directory

during compilation of expat (part of apr-util) you are probably best off creating the directory


and copy all files from the ctc directory into that directory, i.e.,

cp -r $CTC_DIR/* /home/opennao/opennao-1-4-x/build/tmp/

I know this is ugly, but I could not find a proper solution. If you know one, give me a hint!

Finally, we can compile log4cxx

extract the package and cd into the new directory
./configure --prefix=$ROS_DEPS  --with-apr=$ROS_DEPS --with-apr-util=$ROS_DEPS CC=$GEODE_CC CXX=$GEODE_CXX LDFLAGS="$LDFLAGS" --host=i586-linux \
ac_cv_file__dev_zero=yes \
ac_cv_func_setpgrp_void=yes \
apr_cv_tcp_nodelay_with_cork=no \
apr_cv_process_shared_works=no \
apr_cv_mutex_robust_shared=no \
make && make install

If you experience the error message

/bin/sed: can't read /usr/lib/ No such file or directory

it might be necessary to edit


and look for and change the path from

/usr/bin/  to  $CTC_USR_DIR/lib/

If you experience the error message

i586-linux-g++: crti.o: No such file or directory
i586-linux-g++: crtn.o: No such file or directory

edit the file


and search for crti.o and crtn.o and append the full path to those files, i.e. point it to $CTC_USR_DIR/lib/ .

If you experience errors like

undefined reference to `cerr'

while building the examples, you might need to

edit src/examples/cpp/console.cpp to include <stdio.h>

In $TARGETIDR/ros-deps/lib, you should now have libapr-1.*, libaprutil-1.* libexpat.*, and liblog4cxx.*

Cross-Compiling ROS

Once all this is complete, we can start to build ROS.

First, get rosinstall and the appropriate .rosinstall file


Then start to download packages using rosinstall

chmod +x rosinstall
./rosinstall -n ros cturtle_base.rosinstall

Now setup the toolchain to include Aldebaran's cmake toolchain file

echo "include(\"$CTC_DIR/toolchain-geode.cmake\")" >> ros/ros/rostoolchain.cmake
echo "include_directories(\"$TARGETDIR/ros/ros-deps/include\")" >> ros/ros/rostoolchain.cmake
echo "link_directories(\"$TARGETDIR/ros/ros-deps/lib\")" >> ros/ros/rostoolchain.cmake

rxtools needs wxwidgets which is not available for the Nao so we do not build it

touch ros/ros/tools/rxtools/ROS_NOBUILD

Afterwards, get rid of all the automake flags, otherwise cmake gets all crazy

export CFLAGS=
export CXXFLAGS=
export CPPFLAGS=
export LDFLAGS=
export CPATH=
export PATH=$TARGETDIR/ros/ros/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

We can then start to build a base system of ros

cd ros/ros && make
cd ..
rosmake ros # just to be sure...

Installing TF

TF does not cross-compile out of the box, I needed to patch the CMakeList.txt and Makefile for bullet and TF.

Download tf_patches.tgz and point a variable to the directory containing the extracted files

export PATCHESDIR= #path to extracted tf_patches.tgz

Then we need to apply the patches and call rosmake to compile TF

roscd bullet && patch < $PATCHESDIR/Makefile.bullet.patch
roscd tf && patch < $PATCHESDIR/tf.CMakeLists.txt.patch && cd $TARGETDIR
rosmake tf

Also, we need to copy some boost libraries from the CTC directory which are missing on the Nao's USB stick

mkdir libs
cp -r $CTC_USR_DIR/lib/libboost* $TARGETDIR/libs/

Finally, we need to copy the python yaml and xmlrpc packages from the host system (need to be installed on the host system first of course)

mkdir python
cp -r /usr/lib/python2.6/dist-packages/yaml $TARGETDIR/python/
cp /usr/lib/python2.6/SimpleXMLRPCServer* $TARGETDIR/python/
cp /usr/lib/python2.6/xmlrpclib* $TARGETDIR/python/

Again, if you know a better way to do this, let me know!

Further Packages

So far, the following packages should compile and run on the Nao:

rosmake hokuyo_node
rosmake common
rosmake geometry
rosmake driver_common

Currently, the following packages are not compiling:

rosmake camera_drivers
rosmake navigation

These packages probably either have faulty CMakeList.txt files or depend on a some other package with broken CMakeFiles. I never needed those packages, so I did not look into it.


Just copy the directory


to the same path on the Nao's USB stick. Log onto the robot, bring up a bash and call


and ROS should be running (until you log out).

Final Remark

If you know how to fix one or more of the issues I came across, please let me (Daniel Maier) know so I can update this page. Your contribution will be mentioned of course :)

Wiki: nao/Installation/Cross-Compiling/cturtle on NaoQI 1.6 (last edited 2014-10-03 09:40:09 by VincentRabaud)