../
Looking for a senior C++ dev? I'm looking for work. Hire me!

Summary

Setting up a BeagleBone Black (aka BBB) or BeagleBone Green (aka BBG) with ARM-7 Ubuntu is relatively easy. As I wrote in that document, compiling your software on those devices is then very simple...but it is slow.

What I really wanted to do is use a normal desktop (or a VM) to cross-compile for ARM-7.

What Not To Do

The biggest trap was trying to use the cross-compiler on my normal development VM to try and build for my ARM-7 BBB & BBG devices. While it first seemed to work, anything more complicated than a simple "hello world" application would result in a GLIBC error. Specifically, I was seeing this:

./test test: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by test)

Unfortunately, searching Google and StackOverflow didn't help much.

Setup

The solution is quite simple, and makes sense after I thought about it. The development VM where the cross-compiling takes place must be running the same version of Ubuntu (and glibc, etc...) as the target device. So if the ARM-7 BBB and BBG devices are running Ubuntu 14.04.3, make sure you're using Ubuntu 14.04.3 (or older) when doing the cross-compiling!

I don't know if 32-bit versus 64-bit is also important. Again, I suspect with trivial code it will work, as long as there aren't any 32-bit/64-bit differences in the header files or the layout of structures. Not wanting to take chances, when I setup my new development VM for the purpose of cross-compiling for BBB & BBG, I installed 32-bit Ubuntu 14.04-3, knowing I'd be compiling for a 32-bit ARM-7 target system.

Packages

I've previously written about how I turn a normal Ubuntu installation into a development environment. In short, it involves installing the following packages:

sudo apt-get install ssh dkms build-essential linux-headers-generic sudo apt-get install kdevelop cmake git subversion sudo apt-get install graphviz doxygen doxygen-gui sudo apt-get install manpages manpages-dev manpages-posix manpages-posix-dev sudo apt-get install libboost-all-dev libboost-dev libssl-dev sudo apt-get install rpm terminator fish

To cross compile for the ARM-7, the key is to also install the following two packages:

sudo apt-get install g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf

Building

Instead of using gcc and g++ to compile, you'll need to use arm-linux-gnueabihf-gcc and arm-linux-gnueabihf-g++. For example:

arm-linux-gnueabihf-g++ hello_world.cpp

If you're a CMake fan like myself, then the initial invocation of cmake will need to specify some overrides for gcc and g++. I do it like this:

mkdir build-arm7 cd build-arm7 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ ..

When you call make to build, it will now do a cross-compile for the ARM-7.

CMake Packaging

If you use CMake to create a .deb package with make package, you'll need one additional modification to your cmake files. By default, cmake (or cpack) will detect your build environment as x86, and your .deb files will be marked as such. When you try to install the .deb on your ARM-7 device, you'll get this error:

dpkg: error processing archive testing.deb (--install): package architecture (i386) does not match system (armhf) Errors were encountered while processing: testing.deb

The solution is to detect in the cmake file if a cross-compile is taking place, and manually set the architecture. For example, here is how I did it:

STRING (FIND "${CMAKE_CXX_COMPILER}" "arm-linux-gnueabihf-g++" pos) IF ( ${pos} EQUAL -1 ) MESSAGE ( "Normal compilation." ) ELSE () MESSAGE ( "Cross compiling for ARM-7." ) SET ( CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf" ) ENDIF ()

Once the architecture was manually set to armhf, my .deb package installed without problem on my BBB and BBG.

Last modified: 2015-12-31
Stéphane Charette, stephanecharette@gmail.com
../