How to cross compile for Raspberry Pi 3 ?

asked 2018-07-03 01:52:41 -0500

Delb gravatar image


Compiling my project directly on my raspberry has a high failure rate so I thought the cross compilation was a good option to avoid that. But it appears to be more difficult than I thought and there are not that much tutorials on the internet about this topic.

Can somebody help me figure it out by describing how to proceed step by step not to miss anything ?

Here's what I did : (this answer from stackoverflow helped me a lot)

1) Install the compiler for the raspberry on my computer (running Ubuntu 16.04) -> for my raspberry it's arm-linux-gnueabihf

2) Create a rostoolchain.cmake file :



set(CMAKE_LIBRARY_ARCHITECTURE arm-linux-gnueabihf)




# specify the cross compiler
SET(CMAKE_C_COMPILER   /usr/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++)

SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/raspberrypi/rootfs)



# Set compiler flag

3) Create a catkin profile to cross compile :

Profile:                     cross
Extending:        [explicit] /opt/ros/kinetic
Workspace:                   /home/robotics/raspberrypi
Source Space:       [exists] /home/robotics/raspberrypi/src
Log Space:          [exists] /home/robotics/raspberrypi/logs
Build Space:        [exists] /home/robotics/raspberrypi/build
Devel Space:        [exists] /home/robotics/raspberrypi/devel
Install Space:      [unused] /home/robotics/raspberrypi/install
DESTDIR:            [unused] None
Devel Space Layout:          linked
Install Space Layout:        None
Additional CMake Args:       -DBUILD_SHARED_LIBS=Off -DCMAKE_TOOLCHAIN_FILE=/home/robotics/raspberrypi/rostoolchain.cmake
Additional Make Args:        None
Additional catkin Make Args: None
Internal Make Job Server:    True
Cache Job Environments:      False
Whitelisted Packages:        None
Blacklisted Packages:        None

4) Finally, run catkin build but it generates this warning (I display for only one package) :

Warnings   << tile_manager:cmake /home/robotics/raspberrypi/logs/tile_manager/build.cmake.001.log                                                                                                          
CMake Warning at /home/robotics/raspberrypi/src/tile_manager/CMakeLists.txt:79 (add_executable):
  Cannot generate a safe linker search path for target tile_marker_node
  because there is a cycle in the constraint graph:

    dir 0 is [/home/robotics/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf]
      dir 1 must precede it due to link library []
    dir 1 is [/usr/lib/x86_64-linux-gnu]
      dir 0 must precede it due to link library []

  Some of these libraries may not be found correctly.

Leading to this error :

Errors     << tile_manager:make /home/robotics/raspberrypi/logs/tile_manager/build.make.002.log                                                                                                            
/opt/ros/kinetic/lib/ file not recognized: File format not recognized
collect2: error: ld returned 1 exit status

It seems that there is a conflict with the paths /usr/lib/x86_64-linux-gnu, /home/robotics/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf and I have other warnings with /opt/ros/kinetic/lib too but I can't find which variable is defining those paths (I think I should only have /home/robotics/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf )

Am I missing something here or ... (more)

edit retag flag offensive close merge delete


Extending:        [explicit] /opt/ros/kinetic

your Catkin workspace is extending the default amd64 ROS install location. That doesn't sound right to me.

gvdhoorn gravatar image gvdhoorn  ( 2018-07-03 02:11:33 -0500 )edit

What could it be instead ? Isn't it required to compile the non-custom packages ?

Delb gravatar image Delb  ( 2018-07-03 02:16:29 -0500 )edit

I'm not a cross-compilation expert, but how would you expect that to work? The files in /opt/ros are going to be all amd64: binaries, libraries, etc. The entire infrastructure in that directory is going to expect amd64. You cannot mix and match that.

gvdhoorn gravatar image gvdhoorn  ( 2018-07-03 02:45:09 -0500 )edit

See the source install instructions (amd64 though), they also don't do this.

If you have binary artefacts that you want to include in your build, they'll have to come from your RPi and be present in your rootfs dir.

gvdhoorn gravatar image gvdhoorn  ( 2018-07-03 02:47:07 -0500 )edit

I'm sorry but I don't quite understand your answer, I do have binary artifacts to include. Are you saying I should have my src/ dir inside the rootfs dir ?

Delb gravatar image Delb  ( 2018-07-03 03:46:30 -0500 )edit

No, I'm saying that you cannot reuse any binary artefacts from your host (amd64) when compiling for your RPi. By using /opt/ros/.. you're doing exactly that.

All libraries (and also headers) would have to come from your rootfs. So that includes any ROS binaries and libraries.

gvdhoorn gravatar image gvdhoorn  ( 2018-07-03 03:59:08 -0500 )edit

So you mean I shouldn't link the /opt/ros/.. libraries but instead copy the dir into rootfs ?

Delb gravatar image Delb  ( 2018-07-03 04:34:23 -0500 )edit

No: copying that directory in your rootfs dir would essentially copy amd64 libraries into your rootfs. That won't work.

You'll either need to install the arm binaries into your rootfs, or build them from source and then install them into your rootfs.

gvdhoorn gravatar image gvdhoorn  ( 2018-07-03 07:13:34 -0500 )edit