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.
Written by Sebastian Dreßler
Related protips
2 Responses
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
Markus,
Great, that it helped you! This took me quite a while :)
Cheers,
Sebastian