ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I realize this answer is coming probably a month too late for you, but if you're still working on cross compiling ROS, here's a few tips:

Don't follow those instructions you found, because they are very old and outdated. I started with that document, but quickly found it wasn't relevant. Basically, you want to cross-compile a bare-bones ROS from source and then cross compile your own ROS packages. I have done this exact thing with ROS Hydro, targeting an Odroid U3 running Ubuntu 12.11. I can outline the steps for you here, but since you have a different system, details will change. The way I figured things out, you basically need to have cross-compiled versions of the dependencies for anything you want to cross-compile. At some basic level, you will install a toolchain, which should include cross-compiled standard libraries. Many dependencies you will need to build yourself, however.

Here's what you're going to need to do:

Step 1. Install your cross compiling toolchain. I don't know anything about the Wandboard, but it may use the same cross compiler toolchain that I used for the Odroid; I know the beaglebone uses the same one (g++-arm-linux-gnueabihf)

Step 2. Cross compile ROS dependencies. For bare-bones ROS Hydro, I needed the following dependencies: boost (1.56.0), Python (2.7.3), Bzip2, Poco, uuid, libtinyxml. Depending on what ROS packages you need, you might have different dependencies.

Step 3. After you cross compile all of those packages, you need to cross compile ROS. You basically just follow the building ROS from source instructions (http://wiki.ros.org/hydro/Installation/Source). The only major difference that you will have is when you build, you want to pass in a toolchain.cmake file, which will instruct cmake to use the cross compiling tools instead of your typical system tools. For a bare-bones ROS, use the following rosinstall_generator and wstool commands to get the necessary source code (modified for your needs, of course):

$ rosinstall_generator ros_comm <ros_pkg_1> <ros_pkg_2> ... <ros_pkg_n> --rosdistro hydro --deps --wet-only --tar > hydro-my_ros_config-wet.rosinstall

$ wstool init -j8 src hydro-my_ros_config-wet.rosinstall

Now, when you build ROS, you should use a rostoolchain.cmake file that looks something like this:

#File rostoolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH /path/to/cross/compile/build/environment)

# Have to set this one to BOTH, to allow CMake to find rospack
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

This file just tells cmake how to look for things it needs. Think about CMAKE_FIND_ROOT_PATH as the starting point for your system. Cmake won't search down any path that doesn't begin with CMAKE_FIND_ROOT_PATH. So if you have boost libraries installed on your system under /usr/lib and you also cross compiled boost to /home/user/crosscompile/boost/. If your CMAKE_FIND_ROOT_PATH is set to /home/user/crosscompile, then it can find the cross compiled boost, which is what you need if you want to cross compile ROS.

Unfortunately, getting everything to just work is not that simple, and cmake and make are still going to have a lot of trouble finding things properly, but I'll have to leave those details up to you. I recommend creating a directory at /path/to/cross/compile/build/environment/usr/ and to install all of your cross compiled dependencies there. It can be easier to have a unified install location. Also, if you need to set cmake variables like BOOST_INCLUDEDIR, you can do that in your rostoolchain.cmake file.

In order to actually build ros, you use catkin_make_isolated, and pass your toolchain file in as part of your build command:

$ ./src/catkin/bin/catkin_make_isolated -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake

Once you get ROS built fully, you should be able to take your devel_isolated folder, copy it to your device, then source devel_isolated/setup.bash and run a roscore.

Step 4. Cross compile your custom ROS packages. You need to first source ros/devel_isolated/setup.bash. This lets you use catkin_make and allows cmake to find all of the ros dependencies for your package. Then just navigate to your source code and build using the same toolchain file: catkin_make -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake

You should make sure you first delete any existing build/ and devel/ folders, otherwise cmake will get confused as it tries to build. It's just better to start clean. I would also recommend completely separating your local build from your cross compile build. If your code is under some type of version control, like git, then just do your development in your local build environment, push the changes, then pull the changes in your cross compile build environment, and build the cross compile version.

Step 5. Notes about installation, workspaces, and paths. - When you build and catkin creates the setup scripts, it uses paths based on where you built or installed ros or your custom packages. This is important if you're cross compiling, because it means things should have the same path on both systems (I haven't found a better way around this, but maybe a more seasoned catkin developer knows). So if your install location is under /home/user/ros_workspace/ then when you copy it to the device it should also be under /home/user/ros_workspace (and 'user' needs to be the same on both machines).

  • My recommendation is the following: Create an install location on your machine for the cross-compiled ROS software: e.g. /opt/ros-arm/. When you build, use a variation of the following build command to install there:

$ ./src/catkin/bin/catkin_make_isolated --install --install-space /opt/ros-arm/ -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake

When you build your own ros workspace:

$ source /opt/ros-arm/setup.bash

$ catkin_make install -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake -DCMAKE_INSTALL_PREFIX=/opt/ros-custom-arm

  • Just copy /opt/ros-arm and /opt/ros-custom-arm to your device, then source /opt/ros-custom-arm/setup.bash and you should be good to go (the information from /opt/ros-arm/setup.bash is included automatically because you sourced it before building your ros-custom workspace)

I realize this answer is coming probably a month too late for you, but if you're still working on cross compiling ROS, here's a few tips:

Don't follow those instructions you found, because they are very old and outdated. I started with that document, but quickly found it wasn't relevant. Basically, you want to cross-compile a bare-bones ROS from source and then cross compile your own ROS packages. I have done this exact thing with ROS Hydro, targeting an Odroid U3 running Ubuntu 12.11. I can outline the steps for you here, but since you have a different system, details will change. The way I figured things out, you basically need to have cross-compiled versions of the dependencies for anything you want to cross-compile. At some basic level, you will install a toolchain, which should include cross-compiled standard libraries. Many dependencies you will need to build yourself, however.

Here's what you're going to need to do:

Step 1. Install your cross compiling toolchain. I don't know anything about the Wandboard, but it may use the same cross compiler toolchain that I used for the Odroid; I know the beaglebone uses the same one (g++-arm-linux-gnueabihf)

Step 2. Cross compile ROS dependencies. For bare-bones ROS Hydro, I needed the following dependencies: boost (1.56.0), Python (2.7.3), Bzip2, Poco, uuid, libtinyxml. Depending on what ROS packages you need, you might have different dependencies.

Step 3. After you cross compile all of those packages, you need to cross compile ROS. You basically just follow the building ROS from source instructions (http://wiki.ros.org/hydro/Installation/Source). The only major difference that you will have is when you build, you want to pass in a toolchain.cmake file, which will instruct cmake to use the cross compiling tools instead of your typical system tools. For a bare-bones ROS, use the following rosinstall_generator and wstool commands to get the necessary source code (modified for your needs, of course):

$ rosinstall_generator ros_comm <ros_pkg_1> <ros_pkg_2> ... <ros_pkg_n> --rosdistro hydro --deps --wet-only --tar > hydro-my_ros_config-wet.rosinstall

$ wstool init -j8 src hydro-my_ros_config-wet.rosinstall

Now, when you build ROS, you should use a rostoolchain.cmake file that looks something like this:

#File rostoolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH /path/to/cross/compile/build/environment)

# Have to set this one to BOTH, to allow CMake to find rospack
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

This file just tells cmake how to look for things it needs. Think about CMAKE_FIND_ROOT_PATH as the starting point for your system. Cmake won't search down any path that doesn't begin with CMAKE_FIND_ROOT_PATH. So if you have boost libraries installed on your system under /usr/lib and you also cross compiled boost to /home/user/crosscompile/boost/. If your CMAKE_FIND_ROOT_PATH is set to /home/user/crosscompile, then it can find the cross compiled boost, which is what you need if you want to cross compile ROS.

Unfortunately, getting everything to just work is not that simple, and cmake and make are still going to have a lot of trouble finding things properly, but I'll have to leave those details up to you. I recommend creating a directory at /path/to/cross/compile/build/environment/usr/ and to install all of your cross compiled dependencies there. It can be easier to have a unified install location. Also, if you need to set cmake variables like BOOST_INCLUDEDIR, you can do that in your rostoolchain.cmake file.

In order to actually build ros, you use catkin_make_isolated, and pass your toolchain file in as part of your build command:

$ ./src/catkin/bin/catkin_make_isolated -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake

Once you get ROS built fully, you should be able to take your devel_isolated folder, copy it to your device, then source devel_isolated/setup.bash and run a roscore.

Step 4. Cross compile your custom ROS packages. You need to first source ros/devel_isolated/setup.bash. This lets you use catkin_make and allows cmake to find all of the ros dependencies for your package. Then just navigate to your source code and build using the same toolchain file: catkin_make -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake

You should make sure you first delete any existing build/ and devel/ folders, otherwise cmake will get confused as it tries to build. It's just better to start clean. I would also recommend completely separating your local build from your cross compile build. If your code is under some type of version control, like git, then just do your development in your local build environment, push the changes, then pull the changes in your cross compile build environment, and build the cross compile version.

Step 5. Notes about installation, workspaces, and paths. - When you build and catkin creates the setup scripts, it uses paths based on where you built or installed ros or your custom packages. This is important if you're cross compiling, because it means things should have the same path on both systems (I haven't found a better way around this, but maybe a more seasoned catkin developer knows). So if your install location is under /home/user/ros_workspace/ then when you copy it to the device it should also be under /home/user/ros_workspace (and 'user' needs to be the same on both machines).

  • My recommendation is the following: Create an install location on your machine for the cross-compiled ROS software: e.g. /opt/ros-arm/. When you build, use a variation of the following build command to install there:

$ ./src/catkin/bin/catkin_make_isolated --install --install-space /opt/ros-arm/ -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake

When you build your own ros workspace:

$ source /opt/ros-arm/setup.bash

$ catkin_make install -DCMAKE_TOOLCHAIN_FILE=/path/to/rostoolchain.cmake -DCMAKE_INSTALL_PREFIX=/opt/ros-custom-arm

  • Just copy /opt/ros-arm and /opt/ros-custom-arm to your device, then source /opt/ros-custom-arm/setup.bash and you should be good to go (the information from /opt/ros-arm/setup.bash is included automatically because you sourced it before building your ros-custom workspace)

EDIT: 10-07-2014

I just remembered another thing about copying libraries to the device. For whatever reason, when you try to run ROS on the device, it looks for some libraries (I specifically recall this with Boost) by their actual names, instead of their symlink names. As an example, the program might look for libboost_serialization.so.1.56.0 (if you had boost version 1.56.0) instead of libboost_serialization.so, which is just a symlink to libboost_serialization.so.1.56.0.

Perhaps this is a "hacky" way to do things, but I just took my entire collection of cross compiled libraries and copied it to the device. If you used a special /usr/ location when you cross compiled the ROS dependencies, then you can just take that entire /usr/lib folder, put it on your device, and copy all of its contents to the device's /usr/lib location. This is suitable if all you want to do is to run your software on the device. If you start getting into building things on the device, maybe you'll have issues, but that's why you're cross-compiling, right?