How to cross-compile programs for the Raspberry Pi with gcc?

I am fond of using gcc to compile small little C and C++ programs on my main computer. However, I also have a Raspberry Pi, and, being a 700-MHz single-core computer, I would prefer to not have to do my development work on it every time I want to create a binary for it. How (for I know that there's a way) do I cross-compile my program for the Raspberry Pi using my x86 laptop? And is there a way that I may compile C(++) programs on the Pi but produce an x86 binary? If it's any help, "The SoC is a Broadcom BCM2835. This contains an ARM1176JZFS, with floating point..." (according to the official Raspberry Pi FAQ).


Solution 1:

Using a combination of poking around in the apt repositories and the extremely excellent Building Embedded Linux Systems (2nd edition, 2008, O'Reilly), I found this:

arm-linux-gnueabi-gcc

That is both the name of command and the package that you install to acquire it. Once invoked, it acts exactly as "vanilla" gcc, with the only exception that it builds packages for the ARM architecture (or a subset including the BCM2835, at least). Building Embedded Linux Systems (pg 93-94) explains that the names used for invoking the GNU tools in a cross-compilation manner follows this format:

cpu-kernel-manufactuer-os

The -gcc at the end of the topmost example is the component, used for specifing which part of binutils you want to use. It can be swapped out for another GNU toolchain component, such as ld (linker) or as (assembler). For arm-linux-gnueabi-gcc, arm is the architecture, linux is the kernel, gnueabi is the os, and gcc is the component. Where is the manufacturer? Apparently, the manufacturer can be specified as "unknown", as it rarely makes a difference, or left out alltogether (including it would make arm-linux-unknown-gnueabi-gcc).

Solution 2:

Officially documented method

https://www.raspberrypi.org/documentation/linux/kernel/building.md (GitHub)

git clone https://github.com/raspberrypi/tools
export PATH="$(pwd)/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:${PATH}"
printf '#include <stdio.h>\nint main() { puts("hello world"); }\n' > hello_world.c
printf '#include <iostream>\nint main() { std::cout << "hello world" << std::endl; }\n' > hello_world.cpp
arm-linux-gnueabihf-gcc -std=c99 -o hello_world_c hello_world.c
arm-linux-gnueabihf-g++ -std=c++11 -o hello_world_cpp hello_world.cpp

Tested in Ubuntu 17.10, tools repo at 5caa7046982f0539cf5380f94da04b31129ed521