Cross-compilation error with freetype2


#1

Hi all, I am using a Mac and attempting to cross-compile projects for the Raspberry Pi 3. As I would rather not use Xcode, I am using a Vagrant VM running Ubuntu (Xenial) as my dev environment. I would like to cross-compile projects in the VM to save time, but I am running into a compilation error when trying to cross-compile from my Vagrant VM for the Pi (running Ubuntu Mate Xenial).

I have been able to successfully compile a Juce project on the Pi itself and also run on the Pi a “hello world” application cross-compiled in the Vagrant VM. However, I have been unable to successfully cross-compile a Juce project.

When I try to cross-compile the project (which does compile on the Pi itself), I get the following error:

/vagrant/juce_projects/level_control/Builds/Linux$ CXX=arm-linux-gnueabihf-g++ make
Compiling include_juce_graphics.cpp
In file included from /usr/include/freetype2/ft2build.h:37:0,
from …/…/…/…/JUCE/modules/juce_graphics/juce_graphics.cpp:95,
from …/…/JuceLibraryCode/include_juce_graphics.cpp:9:
/usr/include/freetype2/freetype/config/ftheader.h:13:70: fatal error: arm-linux-gnueabihf/freetype2/freetype/config/ftheader.h: No such file or directory
compilation terminated.
Makefile:152: recipe for target ‘build/intermediate/Debug/include_juce_graphics_f817e147.o’ failed

As you can see, I am using arm-linux-gnueabihf-g++ as the cross-compiler. The project does compile successfully when I use the normal g++, but obviously then it’s built for the VM’s architecture.

I have looked online for this error and it appears to be an issue with freetype2’s directory structure. I am pretty new to C++ development but from my reading of the Makefile it should have the correct include path:

JUCE_CPPFLAGS := (DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCE_USE_XSHM=0 -DJUCE_USE_XINERAMA=0 -DJUCER_LINUX_MAKE_7346DA2A=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 (shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk±x11-3.0) -pthread -I…/…/JuceLibraryCode -I…/…/…/…/JUCE/modules -I$(HOME)/JUCE/modules -I/usr/include/freetype2 $(CPPFLAGS)

The additional ‘-I/usr/include/freetype2’ I added in the Projucer, but I would have thought that the pkg-config bit above would have done the same thing. I have also followed suggestions to create symlinks between in the /usr/include directory for freetype and freetype2, but these have had no effect.

I’d be grateful for advice on why this is an issue when using arm-linux-gnueabihf-g++ but not g++ and also suggestions for how to solve this issue.

Here are the contents of my bootstrap.sh, showing the packages installed in the Vagrant VM. I think they have everything required?

apt-get update
apt-get install -y build-essential pkg-config
libasound2-dev libfreetype6-dev libcurl4-gnutls-dev
libx11-dev libxcomposite-dev libxcursor-dev libxext-dev
libxinerama-dev webkit2gtk-4.0 libgtk-3-dev x11proto-gl-dev
mesa-common-dev libjack-dev freeglut3-dev
g+±arm-linux-gnueabihf binutils-arm-linux-gnueabihf juce-tools


#2

To anyone coming along later with the same problem, here is what I found out.

To cross-compile successfully the compiler needs the same libraries etc as will be on the Pi. In the post above I was trying to use my dev machine’s libraries, which is what caused the problem.

So, copy the required directories from the Pi to a directory on your dev machine:

mkdir ~/rootfs
rsync -rl --delete-after --safe-links pi@<ip address of the pi>:/{lib,usr,opt,etc} ~/rootfs

In the Projucer, add the flag --with-sysroot=~/rootfs to both the compiler and linker flags fields.

I also had to change my dev machine image from 64bit to 32bit.

When running make be sure to prefix the command with CXX=arm-linux-gnueabihf-g++ so that it uses the cross-compiler and not the default.

With this I was able to cross-compile a basic hello world C++ program and run it on the Pi.

Unfortunately Juce projects failed at the linking stage. From memory, I think this was due to missing symbols in the prce library or something similar.

At this point I decided that any time saved from not having to compile on the Pi had been outweighed by the time wasted on trying to set up cross-compilation, so I gave up and just compiled on the Pi. Life is short.

edit: I have just found this article, which may also contain helpful pointers: https://solderspot.wordpress.com/2016/02/04/cross-compiling-for-raspberry-pi-part-ii/