126

I am attempting to get cross-compiling for Raspberry Pi working on my Ubuntu machine.

During my initial attempts I was using the arm-linux-gnueabi compiler, which is available in the Ubuntu repo. I got this working. I was able to build all my dependencies and use the cross-compiler in my cmake project.

However, I believe I should be using the hf version, so I switched to arm-linux-gnueabihf. Then I realized that this does not work with Raspberry Pi since it is armv6.

After some Googling, I then found the pre-built toolchain from GitHub.

I downloaded the toolchain, but I don't really understand how to "install" it. I extracted the files to my home directory. The directory structure looks like this:

/gcc-linearo-arm-linux-gnueabihf-raspbian
    /arm-linux-gnueabihf
        /bin
            (contains g++, gcc, etc)
        /lib
            (contains libstdc++ library)
    /bin
        (contains arm-linux-gnueabihf-g++, arm-linux-gnueabihf-...)
    /lib
        (gcc lib stuff)

If I change directory to the INNER bin folder I am able to compile a test program from the terminal without any problems.

~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/
arm-linux-gnueabihf/bin$ g++ test.cpp -o test

I then tried to compile a test program in the OUTER bin folder, which contains the prefixed versions of the tools.

 ~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin$ 
 arm-linux-gnueabihf-g++ test.cpp -o test

However, when I try to use the compiler now (from outside the inner bin directory), it is unable to find the libstdc++ shared library that comes with the toolchain:

arm-linux-gnueabihf-gcc: error while loading shared libraries: 
libstdc++.so.6: cannot open shared object file: No such file or directory.

Furthermore, I want to be able to use the compiler without having to navigate to the bin directory. So I tried adding the OUTER bin directory (since I want the prefixed versions) and both lib directories to my PATH:

export PATH=$PATH:~/tools/.../bin
export PATH=$PATH:~/tools/.../lib
export PATH=$PATH:~/tools/.../.../lib

However, this results in the same error. How should I "install" the toolchain so that I can use the toolchain from everywhere, just like I can when I use the cross-compilers from the Ubuntu repo?

koverman47
  • 111
  • 1
  • 5
pqvst
  • 4,344
  • 6
  • 33
  • 42
  • Try setting --sysroot via CMAKE_C{XX}_FLAGS to install dir. – auselen Oct 03 '13 at 15:27
  • I tried some different paths for --sysroot, but that did not help. I'm not really sure what path I should specify for the sysroot. See above regarding the directory structure of the toolchain. Also, some Googling seems to indicate that --sysroot does not help for libstdc++. – pqvst Oct 04 '13 at 08:17
  • I would try either /gcc-linearo-arm-linux-gnueabihf-raspbian or /gcc-linearo-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf – auselen Oct 04 '13 at 08:23
  • go here https://launchpad.net/gcc-arm-embedded and download the tarball and extract. Set your path to the bin dir...done. Or go to codesourcery.com (now mentor graphics) get the lite version, untar/bz, set your path to the bin dir...done. – old_timer Oct 08 '13 at 02:12
  • Related on RPI SE: https://raspberrypi.stackexchange.com/questions/64273/installing-raspberry-pi-cross-compiler/ – Ciro Santilli OurBigBook.com Jun 24 '18 at 07:23

9 Answers9

255

I'm gonna try to write this as a tutorial for you so it becomes easy to follow.

NOTE: This tutorial only works for older raspbian images. For the newer Raspbian based on Debian Buster see the following how-to in this thread: https://stackoverflow.com/a/58559140/869402

Pre-requirements

Before you start you need to make sure the following is installed:

apt-get install git rsync cmake libc6-i386 lib32z1 lib32stdc++6

Let's cross compile a Pie!

Start with making a folder in your home directory called raspberrypi.

Go in to this folder and pull down the ENTIRE tools folder you mentioned above:

git clone git://github.com/raspberrypi/tools.git

You wanted to use the following of the 3 ones, gcc-linaro-arm-linux-gnueabihf-raspbian, if I did not read wrong.

Go into your home directory and add:

export PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin

to the end of the file named ~/.bashrc

Now you can either log out and log back in (i.e. restart your terminal session), or run . ~/.bashrc in your terminal to pick up the PATH addition in your current terminal session.

Now, verify that you can access the compiler arm-linux-gnueabihf-gcc -v. You should get something like this:

Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/home/tudhalyas/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.b
 uild/src/gcc-linaro-4.7-2012.08/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-
 linux-gnu --target=arm-linux-gnueabihf --prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-l
 inux-gnueabihf-raspbian-linux/install --with-sysroot=/cbuild/slaves/oort61/crosstool-ng/builds/
 arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fo
 rtran --disable-multilib --with-arch=armv6 --with-tune=arm1176jz-s --with-fpu=vfp --with-float=
 hard --with-pkgversion='crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08' --with-bugurl=
 https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgom
 p --enable-libssp --with-gmp=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-rasp
 bian-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/cbuild/slaves/oort61/crosstool-
 ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpc
 =/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-
 gnueabihf/build/static --with-ppl=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf
 -raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/cbuild/slaves/oort61/cros
 stool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --wi
 th-libelf=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/a
 rm-linux-gnueabihf/build/static --with-host-libstdcxx='-L/cbuild/slaves/oort61/crosstool-ng/bui
 lds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static/lib -lpwl' --ena
 ble-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --enable-gol
 d --with-local-prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-li
 nux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08
 )

But hey! I did that and the libs still don't work!

We're not done yet! So far, we've only done the basics.

In your raspberrypi folder, make a folder called rootfs.

Now you need to copy the entire /liband /usr directory to this newly created folder. I usually bring the rpi image up and copy it via rsync:

rsync -rl --delete-after --safe-links pi@192.168.1.PI:/{lib,usr} $HOME/raspberrypi/rootfs

where 192.168.1.PI is replaced by the IP of your Raspberry Pi.

Now, we need to write a cmake config file. Open ~/home/raspberrypi/pi.cmake in your favorite editor and insert the following:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++)
SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/raspberrypi/rootfs)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Now you should be able to compile your cmake programs simply by adding this extra flag: -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake.

Using a cmake hello world example:

git clone https://github.com/jameskbride/cmake-hello-world.git 
cd cmake-hello-world
mkdir build
cd build
cmake -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake ../
make
scp CMakeHelloWorld pi@192.168.1.PI:/home/pi/
ssh pi@192.168.1.PI ./CMakeHelloWorld
Nate
  • 2,449
  • 3
  • 21
  • 29
Stenyg
  • 2,718
  • 1
  • 12
  • 4
  • 4
    I followed your tutorial step by step and now I am able to compile without any errors. Thanks! Extra thanks for including the cmake example. – pqvst Oct 10 '13 at 15:03
  • 1
    This works well for simple projects, but I can't cross-compile my CMAKE project that depends on opencv. I get following error "/opt/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: warning: libjpeg.so.8, needed by /opt/rpi-rootfs/usr/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)". Cmake also seems to pass "-Wl,-rpath,/opt/rpi-rootfs/usr/lib" flag to the linker – user389238 Nov 09 '13 at 23:00
  • How would this work with installing something like `omxplayer` or `mpich`? Would I just do `./configure -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake; make; sudo make install`, or `./configure; make -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake; sudo make install`, or `./configure; make; sudo make -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake install` – puk Nov 28 '13 at 00:58
  • 19
    The `ia32-libs` package isn't available on Ubuntu 13.10. I used `libc6-i386 lib32z1 lib32stdc++6` instead. – Ben T Dec 19 '13 at 12:24
  • I'm probably not doing it right... but I had to additionally add this line to `pi.cmake` on ubuntu with cmake 2.8.11.2 : `SET(CMAKE_CXX_FLAGS "-L$ENV{HOME}/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf $ENV{HOME}/raspberrypi/rootfs/lib/arm-linux-gnueabihf` – Ross Rogers Feb 13 '14 at 21:23
  • I just saw they have updated to gcc4.8.3 but there is no such compiler in the raspbian repositories. Can I safely use the new version? – Christian Rapp Apr 15 '14 at 14:45
  • 2
    Thank you for a thorough tutorial! Would you please explain why is it needed to copy /lib /usr folders from pi machine? – M.G. Jan 18 '15 at 05:23
  • Here is also a good article on how to set up Eclipse and set up toolchain: http://www.raspberrypi.org/forums/viewtopic.php?t=10739&p=119584 – M.G. Jan 19 '15 at 05:54
  • @Marcello Those directories store your OS's installed libraries and development headers. You need them for compiling (so the compiler can find those .h include files) and also for linking. Otherwise you would not be able to cross compile an application that uses OpenCV for example (which may be Ansis's problem). – Anthony Mar 14 '15 at 21:41
  • Superb tutorial! Did this on my Linux Mint installation and it worked flawlessly. Now, however, I am on Ubuntu 15.10 (64bit). This means that the "ia32-libs" are a (somewhat) unavailable. Is this going to be a problem? Can I still build raspberry pi software on my computer? – birgersp Jan 24 '16 at 17:56
  • It is essential to add CMAKE_SYSROOT as explained below. Otherwise the compiler will look in the wrong place (tools instead of rootfs) for system headers. – HappyCactus Jan 19 '17 at 17:58
  • I tried this on 32-bit Debain Jessie 8.7, and I got `E: Unable to locate package ia32-libs`. I looked it up, but all I could find was people running into this issue when trying to install ia32-libs on 64-bit Debian Wheezy, which is not my problem. – Sega dude Feb 02 '17 at 03:06
  • https://github.com/Kukkimonsuta/rpi-buildqt/blob/master/scripts/utils/sysroot-relativelinks.py – Albin Stigo Dec 16 '18 at 16:18
34

Building for newer Raspbian Debian Buster images and ARMv6

The answer by @Stenyg only works for older Raspbian images. The recently released Raspbian based on Debian Buster requires an updated toolchain:

In Debian Buster the gcc compiler and glibc was updated to version 8.3. The toolchain in git://github.com/raspberrypi/tools.git is still based on the older gcc 6 version. This means that using git://github.com/raspberrypi/tools.git will lead to many compile errors.

This tutorial is based on @Stenyg answer. In addition to many other solutions in the internet, this tutorial also supports older Rasperry Pi (A, B, B+, Zero) based on the ARMv6 CPU. See also: GCC 8 Cross Compiler outputs ARMv7 executable instead of ARMv6

Set up the toolchain

There is no official git repository containing an updated toolchain (See https://github.com/raspberrypi/tools/issues/102).

I created a new github repository which includes building and precompiled toolchains for ARMv6 based on GCC8 and newer:

https://github.com/Pro/raspi-toolchain

As mentioned in the project's readme, these are the steps to get the toolchain. You can also build it yourself (see the README for further details).

  1. Download the toolchain:
wget https://github.com/Pro/raspi-toolchain/releases/latest/download/raspi-toolchain.tar.gz
  1. Extract it. Note: The toolchain has to be in /opt/cross-pi-gcc since it's not location independent.
sudo tar xfz raspi-toolchain.tar.gz --strip-components=1 -C /opt
  1. You are done! The toolchain is now in /opt/cross-pi-gcc

  2. Optional, add the toolchain to your path, by adding:

export PATH=$PATH:/opt/cross-pi-gcc/bin

to the end of the file named ~/.bashrc

Now you can either log out and log back in (i.e. restart your terminal session), or run . ~/.bashrc in your terminal to pick up the PATH addition in your current terminal session.

Get the libraries from the Raspberry PI

To cross-compile for your own Raspberry Pi, which may have some custom libraries installed, you need to get these libraries onto your host.

Create a folder $HOME/raspberrypi. In your raspberrypi folder, make a folder called rootfs.

Now you need to copy the entire /liband /usr directory to this newly created folder. I usually bring the rpi image up and copy it via rsync:

rsync -vR --progress -rl --delete-after --safe-links pi@192.168.1.PI:/{lib,usr,opt/vc/lib} $HOME/raspberrypi/rootfs

where 192.168.1.PI is replaced by the IP of your Raspberry Pi.

Use CMake to compile your project

To tell CMake to take your own toolchain, you need to have a toolchain file which initializes the compiler settings.

Get this toolchain file from here: https://github.com/Pro/raspi-toolchain/blob/master/Toolchain-rpi.cmake

Now you should be able to compile your cmake programs simply by adding this extra flag: -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake and setting the correct environment variables:

export RASPBIAN_ROOTFS=$HOME/raspberry/rootfs
export PATH=/opt/cross-pi-gcc/bin:$PATH
export RASPBERRY_VERSION=1
cmake -DCMAKE_TOOLCHAIN_FILE=$HOME/raspberry/Toolchain-rpi.cmake ..

An example hello world is shown here: https://github.com/Pro/raspi-toolchain/blob/master/build_hello_world.sh

Stefan Profanter
  • 6,458
  • 6
  • 41
  • 73
  • I get "ignoring unsafe symlink" messages during rsync. Is it ok? – Alexandr Zarubkin Dec 03 '19 at 15:12
  • Should be fine. That's due to the `--safe-links` argument – Stefan Profanter Dec 03 '19 at 16:54
  • Unfortunately I can not test this for a raspi 4, but since executables from older Raspi can normally also executed on newer Raspi, this should work as well. If someone could test it, I'm happy to update the description – Stefan Profanter Feb 12 '20 at 16:01
  • Hi there @StefanProfanter, how would one go about making the toolchain path independent in order to place it in a path other than `/opt/cross-pi-gcc` ? – nass Apr 26 '20 at 08:37
  • @nass unfortunately no. I'm not an expert on cross compilers. If someone has more insight and infos on this, I would be happy to update my repo! Maybe you can create a new Stackoverflow Question. – Stefan Profanter Apr 27 '20 at 09:21
  • I have Mac M1 machine, this way I was able to compile my Rust project for Raspberry Pi Zero. And it works! – Alexander Korolev Jul 31 '21 at 18:03
  • Hi beginner question here; is there a reason we need to rsync the entire lib and usr directory? I am following a different QT cross compiler tutorial and it also says at some point to rsync usr/lib but this folder seems to have thousands of files and never finishes. Is there a way to selectively choose folders to rsync from here, or just choose the most common ones? For example there is a subfolder called chromium-browser here, which I don't see how is related to the programs I will be making on the pi zero. Is there a way to select only the libraries I want to use, .. – user13267 Oct 07 '21 at 06:22
  • .. or at least some how speed up the rsync process? – user13267 Oct 07 '21 at 06:22
6

I couldn't get the compiler (x64 version) to use the sysroot until I added SET(CMAKE_SYSROOT $ENV{HOME}/raspberrypi/rootfs) to pi.cmake.

NSNoob
  • 5,548
  • 6
  • 41
  • 54
Andreas
  • 61
  • 1
  • 1
  • I could run the Hello World example without CMAKE_SYSROOT set, but when trying the pi.cmake file with a project which uses a shared library I got the linker error libstdc++.so.6 not found. After I set CMAKE_SYSROOT everything worked flawless. – Michael Hilbert Nov 09 '16 at 20:49
6

You may use clang as well. It used to be faster than GCC, and now it is quite a stable thing. It is much easier to build clang from sources (you can really drink cup of coffee during build process).

In short:

  1. Get clang binaries (sudo apt-get install clang).. or download and build (read instructions here)
  2. Mount your raspberry rootfs (it may be the real rootfs mounted via sshfs, or an image).
  3. Compile your code:

    path/to/clang --target=arm-linux-gnueabihf --sysroot=/some/path/arm-linux-gnueabihf/sysroot my-happy-program.c -fuse-ld=lld
    

Optionally you may use legacy arm-linux-gnueabihf binutils. Then you may remove "-fuse-ld=lld" flag at the end.

Below is my cmake toolchain file.

toolchain.cmake

set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# Custom toolchain-specific definitions for your project
set(PLATFORM_ARM "1")
set(PLATFORM_COMPILE_DEFS "COMPILE_GLES")

# There we go!
# Below, we specify toolchain itself!

set(TARGET_TRIPLE arm-linux-gnueabihf)

# Specify your target rootfs mount point on your compiler host machine
set(TARGET_ROOTFS /Volumes/rootfs-${TARGET_TRIPLE})

# Specify clang paths
set(LLVM_DIR /Users/stepan/projects/shared/toolchains/llvm-7.0.darwin-release-x86_64/install)
set(CLANG ${LLVM_DIR}/bin/clang)
set(CLANGXX ${LLVM_DIR}/bin/clang++)

# Specify compiler (which is clang)
set(CMAKE_C_COMPILER   ${CLANG})
set(CMAKE_CXX_COMPILER ${CLANGXX})

# Specify binutils

set (CMAKE_AR      "${LLVM_DIR}/bin/llvm-ar" CACHE FILEPATH "Archiver")
set (CMAKE_LINKER  "${LLVM_DIR}/bin/llvm-ld" CACHE FILEPATH "Linker")
set (CMAKE_NM      "${LLVM_DIR}/bin/llvm-nm" CACHE FILEPATH "NM")
set (CMAKE_OBJDUMP "${LLVM_DIR}/bin/llvm-objdump" CACHE FILEPATH "Objdump")
set (CMAKE_RANLIB  "${LLVM_DIR}/bin/llvm-ranlib" CACHE FILEPATH "ranlib")

# You may use legacy binutils though.
#set(BINUTILS /usr/local/Cellar/arm-linux-gnueabihf-binutils/2.31.1)
#set (CMAKE_AR      "${BINUTILS}/bin/${TARGET_TRIPLE}-ar" CACHE FILEPATH "Archiver")
#set (CMAKE_LINKER  "${BINUTILS}/bin/${TARGET_TRIPLE}-ld" CACHE FILEPATH "Linker")
#set (CMAKE_NM      "${BINUTILS}/bin/${TARGET_TRIPLE}-nm" CACHE FILEPATH "NM")
#set (CMAKE_OBJDUMP "${BINUTILS}/bin/${TARGET_TRIPLE}-objdump" CACHE FILEPATH "Objdump")
#set (CMAKE_RANLIB  "${BINUTILS}/bin/${TARGET_TRIPLE}-ranlib" CACHE FILEPATH "ranlib")

# Specify sysroot (almost same as rootfs)
set(CMAKE_SYSROOT ${TARGET_ROOTFS})
set(CMAKE_FIND_ROOT_PATH ${TARGET_ROOTFS})

# Specify lookup methods for cmake
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# Sometimes you also need this:
# set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# Specify raspberry triple
set(CROSS_FLAGS "--target=${TARGET_TRIPLE}")

# Specify other raspberry related flags
set(RASP_FLAGS "-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS")

# Gather and distribute flags specified at prev steps.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")

# Use clang linker. Why?
# Well, you may install custom arm-linux-gnueabihf binutils,
# but then, you also need to recompile clang, with customized triple;
# otherwise clang will try to use host 'ld' for linking,
# so... use clang linker.
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld)
4

For Windows host, I want to highly recommend this tutorial::

  • Download and install the toolchain
  • Sync sysroot with your RPi include/lib directories
  • Compile your code
  • Drag and drop the executable to your RPi using SmarTTY
  • Run it!

Nothing more, nothing less!

Prebuilt GNU Toolchains available for Raspberry, Beaglebone, Cubieboard, AVR (Atmel) and more

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
SBF
  • 1,252
  • 3
  • 12
  • 21
  • Editing since the first line of the body of the question was "I am attempting to get cross-compiling for Raspberry Pi working on my Ubuntu machine." and I have clarified that on the title. This answer is still welcome, but you might also want to answer this at: https://raspberrypi.stackexchange.com/questions/27163/cross-compiling-with-windows-using-eclipse which is more specific. – Ciro Santilli OurBigBook.com Jun 24 '18 at 07:15
3

I could not compile QT5 with any of the (fairly outdated) toolchains from git://github.com/raspberrypi/tools.git. The configure script kept failing with an "could not determine architecture" error and with massive path problems for include directories. What worked for me was using the Linaro toolchain

http://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/arm-linux-gnueabihf/runtime-linaro-gcc4.9-2016.02-arm-linux-gnueabihf.tar.xz

in combination with

https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py

Failing to fix the symlinks of the sysroot leads to undefined symbol errors as described here: An error building Qt libraries for the raspberry pi This happened to me when I tried the fixQualifiedLibraryPaths script from tools.git. Everthing else is described in detail in http://wiki.qt.io/RaspberryPi2EGLFS . My configure settings were:

./configure -opengl es2 -device linux-rpi3-g++ -device-option CROSS_COMPILE=/usr/local/rasp/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- -sysroot /usr/local/rasp/sysroot -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -prefix /usr/local/qt5pi -hostprefix /usr/local/qt5pi

with /usr/local/rasp/sysroot being the path of my local Raspberry Pi 3 Raspbian (Jessie) system copy and /usr/local/qt5pi being the path of the cross compiled QT that also has to be copied to the device. Be aware that Jessie comes with GCC 4.9.2 when you choose your toolchain.

Community
  • 1
  • 1
cuffel
  • 499
  • 5
  • 7
3

The initial question has been posted quite some time ago and in the meantime Debian has made huge headway in the area of multiarch support.

Multiarch is a great achievement for cross compilation!

In a nutshell the following steps are required to leverage multiarch for Raspbian Jessie cross compilation:

  • On your Ubuntu host install Debian Jessie amd64 within a chroot or a LXC container.
  • Enable the foreign architecture armhf.
  • Install the cross compiler from the emdebian tools repository.
  • Tweak the cross compiler (it would generate code for ARMv7-A by default) by writing a custom gcc specs file.
  • Install armhf libraries (libstdc++ etc.) from the Raspbian repository.
  • Build your source code.

Since this is a lot of work I have automated the above setup. You can read about it here:

Cross Compiling for Raspbian

koverman47
  • 111
  • 1
  • 5
2

there is a CDP Studio IDE available that makes cross compile and deploy quite simple from both windows and linux and you can just check the raspberry toolchain checkbox during the installation. (PS. it has GPIO and I2C support so no code is needed to access those)

The IDE demo of raspberry use is up here: https://youtu.be/4SVZ68sQz5U

and you can download the IDE here: https://cdpstudio.com/home-edition

Jüri T
  • 56
  • 1
1

I have created an example repository which shows how to cross-compile for a Raspberry Pi 4 using CMake. It also includes the installation of the toolchain and some special steps necessary when cloning the root filesystem. It should in principle be possible to use it for older Pis as well, but the toolchain might be a different one: https://github.com/spacefisch/raspberrypi-crosscompiling

Spacefish
  • 305
  • 4
  • 11