6

I'm doing experiments regarding compilation of the Linux kernel on various platforms, but mainly on the RPi and on x86-64 machines. There's no shortage to the links on Google describing how to compile Raspbian on an x86-64 machine to ARM for either the Raspberry Pi or Raspberry Pi 2, but I have a different idea: is it possible to use Raspberry Pi 2s as a compile farm for x64-86 code? I've been looking around and haven't found anything.

Seems like if it could, it would be a nice way to accelerate the compilation of my Ubuntu kernels on my laptop using something like distcc.

  • 3
    That should work. It will be very slow though. The slowness of the Pi is the main reason people cross-compile code for the Pi on their laptop/desktop. – joan Sep 2 '15 at 18:53
  • @joan, which arguments would need to be specified? ultimately, the idea wouldn't be to compile on the RPi2 alone, but to have it be an extra node for my laptop to send work to. It'd probably shave some time off of the compiles, perhaps enough to be worth it. – nerdenator Sep 2 '15 at 20:37
  • I can't help there. I'm very much a dumb user of cross-compilers, I just do what I'm told. – joan Sep 2 '15 at 20:42
  • 3
    If you have only one Pi chances are it's not worth the hassle. Your laptop must be fairly old if it should be beaten by a Raspberry Pi, even a 2. Intuitively I'd say it's worthwhile with 4 Pi's as a minimum. First because compile must be prepared for distcc, which implies some non-negligible overhead on the host. Even with 1 x86 distcc node you won't see a noticeable difference when both nodes hardware are similar in performance. Otherwise it's a nice case study. More to come if you want. – user29510 Sep 2 '15 at 21:42
5

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 (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...

  1. 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
    
  2. 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
    
  3. 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".

  4. 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:

  1. "Paths and misc options" ---> Enable "Debug crosstool-NG", "Save intermediate steps", "gzip saved states", "Interactive shell on failed commands"
  2. "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).
  3. "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
  • Thanks for download link! You basically saved 27 hours of my life :') – Jacajack Jul 7 '16 at 7:50
  • 1
    No problem, glad that you found it useful :) – Kong Chun Ho Jul 8 '16 at 7:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.