Last Updated: February 25, 2017
·
7.506K
· sdressler

Build a ARM Linux Cross-Toolchain on OS X From Scratch

Recently I needed such a toolchain to test my RPi. However, crosstool-ng did not worked on OS X for me, so I had to figure it out myself and here is how I did it. Please perform these steps on a case-sensitive volume, otherwise it is not going to work.

Prerequisites

Alright then, open up Terminal.app and add your username to the wheel group

sudo dseditgroup -o edit -a MYUSERNAME -t user wheel

Restart Terminal.app and set up some variables (you may want to adapt them a bit to suit them your needs)

export TARGET=armv6l-unknown-linux-gnueabihf
export PREFIX=/Volumes/Toolchain/RPi
ulimit -n 1024

Then install the following with homebrew and use --default-names

grep
sed
gawk
wget
gettext

Now adapt your $PATH

export PATH=/usr/local/bin:$PREFIX/bin:$PATH

and re-link gettext

brew link gettext --force

Linux Kernel Source and Headers

Download Linux kernel sources (e.g. for RPi w. Arch Linux use 3.6.11), extract them, cd into the dir and

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- defconfig
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- headers_install

Yes, arm-none-linux-gnueabihf- is correct. Next: copy headers from usr/include to $PREFIX/include

Binutils

Download latest binutils package, extract and cd into its directory and install it:

mkdir build
cd build
../configure --disable-werror --target=$TARGET --prefix=$PREFIX --disable-nls
make
make install

GCC Stage 1

Again: download, extract and cd followed by:

./contrib/download_prerequisites
mkdir build
cd build
configure --target=$TARGET --prefix=$PREFIX --disable-threads --disable-shared --with-newlib --disable-multilib --with-local-prefix=$PREFIX --disable-nls --without-headers --enable-languages=c,c++
make all-gcc all-target-libgcc
make install-gcc install-target-libgcc

EGLIBC

Get EGLIBC

svn co svn://svn.eglibc.org/branches/eglibc-2_18 eglibc-2.18

Now we need some patches, i.e.

  • Patch sunrpc/rpc/types.h, add #define __u_char_defined, #define __daddr_t_defined prior line 74
  • Patch sunrpc/Makefile: replace $(BUILD_CC) $^ $(BUILD_LDFLAGS) -o $@ with $(BUILD_CC) $^ $(BUILD_LDFLAGS) -o $@ -L/usr/local/lib -lintl

Now build and install with

mkdir build
cd build
CC=$TARGET-gcc ../libc/configure --host=$TARGET --prefix=$PREFIX --with-headers=$PREFIX/include --enable-add-ons --disable-nls libc_cv_forced_unwind=yes
make
make install

GCC Stage 2

Go back to the GCC source directory from GCC Stage 1 and

mkdir build2
cd build2
../configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --with-headers=$PREFIX/include --with-libs=$PREFIX/lib
make
make install

This is it, you are done now and your shiny new cross-toolchain for ARM Linux resides in $PREFIX.


P.S.: Don't forget the mandatory beer/coffee/tea/cigarette between steps.

2 Responses
Add your response

Hello Sebastian!

Your work has helped me a lot doing the same on a Linux machine. There are so many howtos out there but many of them do not work (outdated, different target, etc).

First I started with http://www.gurucoding.com/en/rpi_cross_compiler/index.php (which still is a valuable source of information). Since its author targets an cross-compiler for Windows, some of his steps can be dropped on Linux. Here your work came in.

In order to share my results with the community I have put them on my local web server (http://fserver.alburg.selfhost.me/cross-gcc-arm/).
The small file contains the scripts, the huge file the sources (which could be found on their well known locations anyway, but I have packed them together with some patches for convenience).

Markus

over 1 year ago ·

Markus,

Great, that it helped you! This took me quite a while :)

Cheers,
Sebastian

over 1 year ago ·