Cross compiling for ARM with Ubuntu 16.04 LTS

The goal of cross compiling is to compile for one architecture on machine running another one. In this post, I’ll try to explain the steps required to be able to compile software that is executable on ARM-based hardware using a “normal” x64-based PC or virtual machine. ARM-based devices are usually limited in processing power and are mostly running stripped-down, embedded versions of Linux. This makes it sometimes difficult to compile on the target device directly.

For this post, I was using Ubuntu 16.04 LTS (Xenial). I’m starting with a minimal install (Standard System Utilities + SSH server) as a starting point. This makes sure that the next steps should function on about any installation without missing dependencies or installation steps.

Terminology

In cross compiling, the following terminology is used:

  • Build platform: Architecture of the build machine
  • Host platform: The architecture you are building for
  • Target platform: The architecture that will run the binary output of the compilation

If the above three platforms are the same, which in mostly the case, then it’s called a “native” compilation. If build and host platform are the same, then we’re talking about a “cross” compilation, which this post is covering. When all three platforms are different, it’s called a “canadian”. This is used to build a cross compiler for another architecture.

Just to be clear, in this post, the build and host platform are x86_64 (standard PC) and the target is ARM.

Prerequisites

Before we can start compiling, we need to install the necessary packages and tools for cross compiling for ARM. These include the standard tools needed for compiling:

Compiling a simple C program from source

Once we have installed the prerequisites, we can try and compile a simple C program. Let’s first do a so-called native compile for the PC we’re compiling from just to make sure that our program does what we want.

Save the source as helloworld.c:

Compile the source “native” and write the binary as helloworld-x86_64

To see what type and for which platform the result of our compilation is, we can check the output with file:

We can execute the binary to check the result:

The next step is to compile the same source for ARM. We simply do this by using a different compiler (arm-linux-gnueabi-gcc instead of gcc). When compiling for a platform like ARM, it’s usually also a good thing to create a statically linked binary. This means that the binary will not depend on dynamically linked libraries (which can be missing/broken dependencies).

Now we can test the execution of our binary on an ARM-based machine:

As you see in the above output, our small program works fine on ARM after cross compiling it!

Cross compiling with configure and make

The above example was pretty simple but when compiling source from larger projects, it’s usually done by generating a makefile with configure and then running the compile and other necessary steps with make. To replace gcc with another, target platform specific compiler would be a lot of work. Fortunately most of the times you can just specify the platform which you are compiling for when running configure.

As an example, I’ll create a binary for ARM of strace. To avoid getting into problems with dependencies on my embedded ARM device, I’ll compile static as well.

First step is to get the source of strace from: https://sourceforge.net/projects/strace/files/strace/4.14/ and extract it:

The next step is to run configure. But here we need to specify that we want to end up with a binary (statically linked) for ARM:

At this point we’re ready to do the actual cross compile by running make:

As you can see in the output of the last command, the result is a statically linked binary for arm.

As with the small C-program, it’s time to test the compiled binary on ARM:

 

In most cases compiling for ARM (or another cross-platform) is not very difficult but it sometimes requires a little extra effort to find the correct options and flags for the configure script.

One thought on “Cross compiling for ARM with Ubuntu 16.04 LTS

Leave a Reply

Your email address will not be published. Required fields are marked *