It is possible to compile x86_64 code on the Raspberry Pi, and i have just built a cross-compile toolchain on my Pi 2 (with more than 27 hrs of compilation and some hours of bug fixing).
You can directly download it from here: Link (Updated: 2022-Apr)
(GCC 4.9.3, built with GCC 4.9.2-10 on Raspbian JESSIE (2015-Nov-21) and crosstool-ng 1.22.0)
Here's how i built my toolchain
Getting required packages
sudo apt-get install gperf bison flex texinfo help2man gawk libtool libtool-bin autoconf libncurses5-dev python2.7-dev
Preparing crosstool-ng 1.22.0
# Getting crosstool-ng 1.22.0
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2
# Decompress it
tar -xvf crosstool-ng-1.22.0.tar.bz2
cd crosstool-ng
# Replace the value of prefix to the path you want crosstool-ng be installed in
./configure --prefix=/home/hopkins/ct-ng
make
make install
Tuning our RPi 2
I have found that we need to tune our RPi 2 before building our toolchain, as it may run out of RAM...
I have set the GPU/RAM split to the minimum (16MB for GPU) so i can have the maximum RAM available:
Modify/Add in /boot/config.txt:
gpu_mem=16
I have increased the default SWAP size, from 100MB to 1536MB. This maybe too much, you can fine tune by yourself, but i found no problem keeping my SWAP to 1536MB:
Modify /etc/dphys-swapfile, replace
CONF_SWAPSIZE=100
to
CONF_SWAPSIZE=1536
I recommend not running the Display Manager (lxpanel) while building the toolchain. I even just run "sudo raspi-config" and set "Boot Options" to "Console".
Reboot the Pi.
Start building our toolchain
# Update PATH, so we can use our newly built crosstool-ng
export PATH="${PATH}:/home/hopkins/ct-ng/bin"
cd ~/
mkdir x86_64-unknown-linux-gnu
cd x86_64-unknown-linux-gnu
ct-ng x86_64-unknown-linux-gnu
ct-ng menuconfig
In the configuration menu, i have did the following modifications:
- "Paths and misc options" ---> Enable "Debug crosstool-NG", "Save intermediate steps", "gzip saved states", "Interactive shell on failed commands"
- "Paths and misc options" ---> Under "Build behavior", set "Number of parallel jobs" to 1. You can try set it to 2 or 3 for faster build, but 1 should be the safest. My Pi 2 run out of RAM before by setting to 0 (auto, it eventually uses 5 threads) and i couldn't compile the toolchain (the kernel killed the compiler as it uses too much RAM).
- "C Compiler" ---> Set "gcc version" to 4.9.3. You can try other versions, but i just built 4.9.3 this time. (This version is the closest to the gcc compiler in my Raspbian, which is 4.9.2)
Now, we can build our toolchain:
ct-ng build
You can now let the Pi 2 do its job. The building process should take a quite long time (1640mins, 21.80secs for me, setting 1 parallel job in config).
Note: In case some step failed, you can restart the build from a specific step by setting the "RESTART" variable:
RESTART=step_name ct-ng build
Where step_name is the step name you failed. The step name will be displayed when starting a step, e.g.:
...
[INFO ] Installing final gcc compiler
[EXTRA] Configuring final gcc compiler
[EXTRA] Building final gcc compiler
[EXTRA] Installing final gcc compiler
[EXTRA] Housekeeping for final gcc compiler
[INFO ] Installing final gcc compiler: done in 8575.18s (at 600:54)
[INFO ] Saving state to restart at step 'libc_post_cc'...
[INFO ] Saving state to restart at step 'companion_libs_for_target'...
[INFO ] Saving state to restart at step 'binutils_for_target'...
[INFO ] Saving state to restart at step 'debug'...
[INFO ] =================================================================
[INFO ] Installing cross-gdb
[EXTRA] Configuring cross-gdb
[EXTRA] Building cross-gdb
[ERROR] configure: error: python is missing or unusable
[ERROR] make[5]: *** [configure-gdb] Error 1
[ERROR] make[4]: *** [all] Error 2
...
After fixing the problem, you can restart the build by issuing:
RESTART=debug ct-ng build
When you want restart the whole build (e.g. you have ran ct-ng clean), don't forgot the clear "RESTART" (RESTART= ct-ng build).
After a long time (or debug/error fixing if you are unfortunate), the build should be finished. The toolchain could be found in ~/x-tools/x86_64-unknown-linux-gnu (in my case: /home/hopkins/x-tools/x86_64-unknown-linux-gnu/).
Tests
On my RPi 2:
The compiled toolchain
hopkins@raspberrypi:~/x64_test$ cd ~/x-tools/x86_64-unknown-linux-gnu/bin
hopkins@raspberrypi:~/x-tools/x86_64-unknown-linux-gnu/bin$ ls
x86_64-unknown-linux-gnu-addr2line x86_64-unknown-linux-gnu-gcov
x86_64-unknown-linux-gnu-ar x86_64-unknown-linux-gnu-gdb
x86_64-unknown-linux-gnu-as x86_64-unknown-linux-gnu-gprof
x86_64-unknown-linux-gnu-c++ x86_64-unknown-linux-gnu-ld
x86_64-unknown-linux-gnu-c++filt x86_64-unknown-linux-gnu-ld.bfd
x86_64-unknown-linux-gnu-cc x86_64-unknown-linux-gnu-ld.gold
x86_64-unknown-linux-gnu-cpp x86_64-unknown-linux-gnu-ldd
x86_64-unknown-linux-gnu-ct-ng.config x86_64-unknown-linux-gnu-nm
x86_64-unknown-linux-gnu-dwp x86_64-unknown-linux-gnu-objcopy
x86_64-unknown-linux-gnu-elfedit x86_64-unknown-linux-gnu-objdump
x86_64-unknown-linux-gnu-g++ x86_64-unknown-linux-gnu-populate
x86_64-unknown-linux-gnu-gcc x86_64-unknown-linux-gnu-ranlib
x86_64-unknown-linux-gnu-gcc-4.9.3 x86_64-unknown-linux-gnu-readelf
x86_64-unknown-linux-gnu-gcc-ar x86_64-unknown-linux-gnu-size
x86_64-unknown-linux-gnu-gcc-nm x86_64-unknown-linux-gnu-strings
x86_64-unknown-linux-gnu-gcc-ranlib x86_64-unknown-linux-gnu-strip
hopkins@raspberrypi:~/x-tools/x86_64-unknown-linux-gnu/bin$ file x86_64-unknown-linux-gnu-gcc
x86_64-unknown-linux-gnu-gcc: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=9cf9ffdf29328cbb0e02ba01ed6d9ae6dc43c96b, stripped
hopkins@raspberrypi:~/x-tools/x86_64-unknown-linux-gnu/bin$ x86_64-unknown-linux-gnu-gcc --version
x86_64-unknown-linux-gnu-gcc (crosstool-NG crosstool-ng-1.22.0) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Some Hello World tests
hello_world.c:
#include <stdio.h>
int main() {
printf("Hello world");
return 0;
}
hello_world_c++.cpp:
#include <iostream>
using namespace std;
int main() {
cout << "Hello world";
return 0;
}
Compiling and file info:
hopkins@raspberrypi:~/x64_test$ x86_64-unknown-linux-gnu-gcc hello_world.c -o hello_world
hopkins@raspberrypi:~/x64_test$ file hello_world
hello_world: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped
hopkins@raspberrypi:~/x64_test$ x86_64-unknown-linux-gnu-g++ hello_world_c++.cpp -o hello_world_c++
hopkins@raspberrypi:~/x64_test$ file hello_world_c++
hello_world_c++: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped
On a 64-bit machine:
[hopkins@fkcp ~]$ uname -a
Linux fkcp 2.6.32-042stab112.15 #1 SMP Tue Oct 20 17:22:56 MSK 2015 x86_64 x86_64 x86_64 GNU/Linux
[hopkins@fkcp x64_test]$ ./hello_world
Hello world[hopkins@fkcp x64_test] ./hello_world_c++
Hello world