How to cross compile C++ code ?

What is cross compilation ?

Unlike Java, the programming languages such as C/C++ are not platform independent. Your C++ code will only run on the machine it was compiled on i.e the code compiled on Windows machine isn't compatible to run on Linux machines :(

But no worries, this blog will help you compile your C++ code in a way to be compatible with multiple platforms depending on your requirements. This is known as cross compilation.

We'll be using a makefile to achieve this. If you don't know what a makefile is, in simple terms it is a file containing set of instructions so that you don't need to perform the repetitive tasks manually. Just run the makefile! it'll be more clear as we go ahead.

What are build and target machines ?

To keep it simple, build machine is where you'll install a cross-compiler and target machine is the one you want to compile for and run the generated executable file.

We'll perform cross-compilation of C++ code with the following system environment:

  1. Build Machine: Ubuntu 18.04 (x86)
  2. Target Machine: Raspberry Pi (arm64)
  3. Cross Compiler: aarch64-linux-gnu-g++

To determine OS architectures of both the machines run the below command:

 uname -a

To install the cross-compiler on build machine:

apt install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu

Note: The cross-compiler needs to be installed as per the OS architecture of target machine.

To install make utility on build machine:

apt install make

Sample program

Let's write a simple Hello World program in C++ and cross-compile it.

#include <iostream>

int main() {
    std::cout << "Hello World!";
    return 0;
}

Makefile

Makefile helps to organise compilation of your code. Create a file named as makefile (without any extension) and copy the below contents into it.

#Specify the cross-compiler 
CXX = aarch64-linux-gnu-g++

#Add path to lib dir and any other library your program will be using (e.g. -lcurl)
LIBS = -L/usr/lib/aarch64-linux-gnu -L/usr/lib/aarch64-linux-gnu/lib 

#Add path to include dir and header files belonging to your source code 
INC = -L/usr/include/aarch64-linux-gnu

myapp: main $(CXX) -o myapp main.o $(LIBS)

main: main.cpp
    $(CXX) -Wall $(INC) -c main.cpp

clean: 
        rm -rf main.o myapp

Note: Make correct use of tabs/spaces to avoid indentation errors. This Hello World example does not contain any header files or usage of external libraries. In case of larger C++ projects containing src and include folders, add paths to the same in the makefile as suggested in the comments.

To run the makefile simply run the make command or use the command below:

make -f makefile

To verify that the file has been cross compiled for target machine, use the below command. It should display arm64 in the description and that's just a confirmation.

file myapp

You can try running myapp on the build machine using ./myapp command and it won't run - WHY? Because we already discussed that it will run on the machine it was compiled for!

Voila!! Hope you found this blog helpful to get started with cross compiling your C++ code :)