This document details extra that were needed to build the rpi cross-compiler on MSYS2. The original instructions are located on gurucodings.
This cross-compiler has been created targeting the Raspbian Wheezy OS which is based on Debian Wheezy with special support for the Raspberry PI architecture. The version that was installed on my rpi is 2014-06-20-wheezy-raspbian
.
Here the version of the various tools currently present in this version of Raspbian (Guest OS):
- gcc (Debian 4.6.3-14+rpi1) 4.6.3
- GNU ld (GNU Binutils for Debian) 2.22
- Binutils target target of
arm-linux-gnueabihf
- ldd (Debian EGLIBC 2.13-38+rpi2+deb7u1) 2.13
- Linux raspberrypi 3.12.22+ #691 PREEMPT Wed Jun 18 18:29:58 BST 2014 armv6l GNU/Linux
Here the relevant list of programs that were used (at time of writing) on MSYS2 to create the actual cross-compiler:
- GNU Make 4.0
- gcc version 4.8.2 (GCC)
- GNU ld (GNU Binutils) 2.24.51.20140326
- MSYS2 2.0.0(0.273/5/3) 2014-06-24 09:17 x86_64 Msys
- gmp 6.0.0-2 (
pacman -S msys/gmp msys/gmp-devel
) - mpfr 3.1.2.p8-1 (
pacman -S msys/mpfr msys/mpfr-devel
) - mpc 1.0.2-1 (
pacman -S msys/mpc msys/mpc-devel
) - gettext 0.18.3.2-2 (
pacman -S msys/gettext msys/gettext-devel
) - libexpat 2.1.0-1(
pacman -S msys/libexpat msys/libexpat-devel
)
Some utilities:
- gzip
pacman -S msys/gzip
- patch
pacman -S msys/patch
- svn
pacman -S msys/svn
- tar
pacman -S msys/tar
- wget
pacman -S msys/patch
And finally, here the list of programs that were downloaded from the interweb to compile the rpi cross-compiler:
binutils-2.22
eglibc-2.13
gcc-4.6.4
linux-3.12.22
gdb-7.7
- patches
If patches go missing from the link above, ping me, I will upload them somewhere.
Initial preperation simply involves creating a directory where you will put everything. In my case, I always work from my home directory work
folder, so I created:
mkdir -p ~/work/rpi-cross
This folder (i.e. ~/work/rpi-cross
) will be known in the instructions below as the $ROOT
variable. You can export it right now to make it easier to copy & paste below instructions:
export ROOT=~/work/rpi-cross
cd $ROOT && mkdir archives && mkdir src && mkdir patches
wget -d archives https://ftp.gnu.org/gnu/binutils/binutils-2.22.tar.gz
svn co svn://svn.eglibc.org/branches/eglibc-2_13 archives/eglibc-2.13
wget -d archives https://ftp.gnu.org/gnu/gcc/gcc-4.6.4/gcc-4.6.4.tar.gz
wget -d archives https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.12.22.tar.gz
wget -d archives https://ftp.gnu.org/gnu/gdb/gdb-7.7.tar.gz
wget -d archives http://www.gurucoding.com/en/rpi_cross_compiler/downloads/patches-for-raspberry-pi-toolchain.tar.gz
cd $ROOT/src
tar -xzvf ../archives/binutils-2.22.tar.gz
tar -xzvf ../archives/gcc-4.6.4.tar.gz
tar -xzvf ../archives/linux-3.12.22.tar.gz
tar -xzvf ../archives/gdb-7.7.tar.gz
cd $ROOT/patches
tar -xzvf ../archives/patches-for-raspberry-pi-toolchain.tar.gz
We are compiling a cross-compiler for MSYS2 system which is derived directly from Cygwin. However, the guess build system is not Cygwin at all but instead x86_64-pc-msys
. This can cause some of the programs above to not compile correctly because of a wrongly choose set of options.
To overcome this, add --build=x86_64-pc-cygwin
to all configure scripts that do not have already the --build
arguments specified. In fact, always use this value for --build
.
cd $ROOT/src/gcc-4.6.4
cat ../../patches/gcc--armhf-triplet.diff | patch -p2
cat ../../patches/gcc--arm-dynamic-linker.diff | patch -p2
cat ../../patches/gcc--arm-multilib-defaults.diff | patch -p2
cd $ROOT/src/eglibc-2.13
cat ../../patches/eglibc--remove-manual.diff | patch -p1
cat ../../patches/eglibc--cross-cygwin.diff | patch -p1
cat ../../patches/eglibc--armhf-triplet.diff | patch -p1
cat ../../patches/eglibc--armhf-linker.diff | patch -p1
cat ../../patches/eglibc--ldconfig-cache-abi.diff | patch -p1
cat ../../patches/eglibc--soname-hack.diff | patch -p1
find . -type f | xargs grep -l "\.oS" | xargs sed -i 's/\.oS/\.oZ/g'
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
Commands:
cd $ROOT/build/binutils
../../src/binutils-2.22/configure \
--build=x86_64-pc-cygwin --target=$TARGET --prefix=$PREFIX \
--with-sysroot=$TARGET --disable-nls --with-arch=armv6
make all
make install
Patch file gcc-4.6.4/gcc/doc/invoke.texi
by adding @comment
in front of line #1405:
-@include @value{srcdir}/../libiberty/at-file.texi
+@comment @include @value{srcdir}/../libiberty/at-file.texi
This remove libiberty
manual inclusion.
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
export PATH=$PATH:$PREFIX/bin
Commands:
cd $ROOT/build/gcc
../../src/gcc-4.6.4/configure \
--build=x86_64-pc-cygwin --target=$TARGET --prefix=$PREFIX \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--disable-sjlj-exceptions --enable-checking=release --enable-linker-build-id \
--enable-gnu-unique-object --disable-nls --enable-languages=c --without-headers \
--disable-shared --disable-threads --disable-multilib --disable-decimal-float \
--disable-libmudflap --disable-libssp --disable-libgomp --disable-lto \
--without-ppl --without-cloog
make all-gcc
make install-gcc
make all-target-libgcc
make install-target-libgcc
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
export PATH=$PATH:$PREFIX/bin
Commands:
make ARCH=arm CROSS_COMPILE=$TARGET- INSTALL_HDR_PATH=$PREFIX/usr headers_install
find $PREFIX/usr/include -name '..install.cmd' -delete
find $PREFIX/usr/include -name '.install' -delete
Patch file eglibc-2.13/configure
by accepting version 4.* of make. Apply the following change to line #5350:
- 3.79* | 3.[89]*)
+ 3.79* | 3.[89]* | 4.*)
Patch file eglibc-2.13/Makeconfig
by removing subdir manual. We don't really need the manual and the packaged eglibc I downloaded does not seem to have the required files to generate the manual. Apply the following change to line #971:
- gnulib iconv iconvdata wctype manual shadow gshadow po argp \
+ gnulib iconv iconvdata wctype shadow gshadow po argp \
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
export PATH=$PATH:$PREFIX/bin
Commands:
cd $ROOT/build/eglibc
CC=$PREFIX/bin/$TARGET-gcc \
CXX=$PREFIX/bin/$TARGET-g++ \
AR=$PREFIX/bin/$TARGET-ar \
RANLIB=$PREFIX/bin/$TARGET-ranlib \
MAKEINFO=: \
../../src/eglibc-2.13/configure \
--prefix=/usr --build=x86_64-pc-cygwin --host=$TARGET \
--with-headers=$PREFIX/usr/include --enable-kernel=3.0.0 \
--disable-profile --without-gd --without-cvs --enable-add-ons
make install_root=$PREFIX install-headers install-bootstrap-headers=yes
mkdir -p $PREFIX/usr/lib
make csu/subdir_lib
cp csu/crt1.o csu/crti.o csu/crtn.o $PREFIX/usr/lib
$PREFIX/bin/$TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $PREFIX/usr/lib/libc.so
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
export PATH=$PATH:$PREFIX/bin
Commands:
cd $ROOT/build/gcc
find . -delete
../../src/gcc-4.6.4/configure \
--build=x86_64-pc-cygwin --target=$TARGET --prefix=$PREFIX \
--with-sysroot=$PREFIX --disable-libquadmath \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--disable-sjlj-exceptions --enable-checking=release \
--enable-linker-build-id --enable-gnu-unique-object \
--disable-nls --enable-languages=c --with-headers \
--disable-multilib --disable-libmudflap --disable-libssp \
--disable-libgomp --disable-lto --without-ppl --without-cloog
make
make install
Patch file eglibc-2.13/Makerules
by changing how generated libraries source location is determined. Instead of using $(<F)
(which seems to return filename and not path, not sure about this), we will use $(<)
instead which returns a full path. Apply the following change to line #996:
-$(LN_S) $(<F) $@
+$(LN_S) $(<) $@
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
export PATH=$PATH:$PREFIX/bin
Commands:
cd $ROOT/build/eglibc
BUILD_CC=gcc \
CC=$PREFIX/bin/$TARGET-gcc \
CXX=$PREFIX/bin/$TARGET-g++ \
AR=$PREFIX/bin/$TARGET-ar \
RANLIB=$PREFIX/bin/$TARGET-ranlib \
MAKEINFO=: \
../../src/eglibc-2.13/configure \
--prefix=/usr --build=i686-pc-cygwin --host=$TARGET \
--with-headers=$PREFIX/usr/include --enable-kernel=3.0.0 \
--disable-profile --without-gd --without-cvs --enable-add-ons
make
make install_root=$PREFIX install
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
export PATH=$PATH:$PREFIX/bin
Commands:
cd $ROOT/build/gcc
find . -delete
../../src/gcc-4.6.4/configure \
--build=x86_64-pc-cygwin --target=$TARGET --prefix=$PREFIX \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--with-sysroot=$PREFIX \
--disable-sjlj-exceptions --enable-checking=release \
--enable-linker-build-id --enable-gnu-unique-object \
--disable-nls --enable-languages=c,c++ \
--with-headers --enable-shared --enable-threads=posix \
--disable-multilib -enable-__cxa_atexit \
--disable-libmudflap --disable-libssp \
--disable-libgomp --disable-lto --without-ppl --without-cloog
make
make install
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/gcc-4.6.4-rpi/$TARGET
Commands:
cd $ROOT/build/gdb
find . -delete
cp -R ../gdb-7.4.1/. .
./configure --build=x86_64-pc-cygwin --prefix=$PREFIX --target=$TARGET --with-expat
make
make install
cd $ROOT/build/gdb/gdb/gdbserver
CC=$PREFIX/bin/$TARGET-gcc LDFLAGS=-static ./configure --build=x86_64-pc-cygwin --host=$TARGET
CC=$PREFIX/bin/$TARGET-gcc LDFLAGS=-static make
cp ./gdbserver $PREFIX/usr/bin
cp ./gdbreplay $PREFIX/usr/bin
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/$TARGET
Commands:
cd /opt/crosstool/arm-linux-gnueabihf
mkdir pkg
cd pkg
wget http://zlib.net/zlib-1.2.8.tar.gz
cd ..
mkdir src
cd src
tar -xzvf ../pkg/zlib-1.2.8.tar.gz
cd zlib-1.2.8
CHOST="Linux" \
CC=$PREFIX/bin/$TARGET-gcc \
CXX=$PREFIX/bin/$TARGET-g++ \
AR=$PREFIX/bin/$TARGET-ar \
RANLIB=$PREFIX/bin/$TARGET-ranlib \
./configure --prefix=$PREFIX/usr
make
make install
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/$TARGET
Commands:
cd /opt/crosstool/arm-linux-gnueabihf
mkdir pkg
cd pkg
wget http://www.openssl.org/source/openssl-1.0.1h.tar.gz
cd ..
mkdir src
cd src
tar -xzvf ../pkg/openssl-1.0.1h.tar.gz
cd openssl-1.0.1h.tar.gz
CC=$PREFIX/bin/$TARGET-gcc \
CXX=$PREFIX/bin/$TARGET-g++ \
AR=$PREFIX/bin/$TARGET-ar \
RANLIB=$PREFIX/bin/$TARGET-ranlib \
./Configure dist threads -D_REENTRANT -O3 --prefix=$PREFIX/usr
make
make install
Environment:
export TARGET=arm-linux-gnueabihf
export PREFIX=/opt/crosstool/$TARGET
Commands:
cd /opt/crosstool/arm-linux-gnueabihf
mkdir src
cd src
git clone https://github.com/warmcat/libwebsockets.git
mkdir build
cd build
# Update ../cross-arm-linux-gnueabihf.cmake
# CROSS_PATH to `<Windows path to crosschain installation path`
# Add .exe to compiler executables
cmake .. -G "MSYS Makefiles" \
-DCMAKE_INSTALL_PREFIX:PATH=$PREFIX/usr \
-DCMAKE_TOOLCHAIN_FILE=../cross-arm-linux-gnueabihf.cmake \
-DLSW_IPV6=OFF
Proposed minor change:
to ...
Otherwise, you won't be forcing path resolution to prioritize your cross-compile toolchain over the default/native one already installed on the system, and the resulting binary will be for the current system rather than the cross-compile target.