-
Notifications
You must be signed in to change notification settings - Fork 3
GHC Cross Compiler for Raspberry Pi
-
The following cross compilation was done on Linux Mint 17 64bit, although the instructions should work on any Debian/Ubuntu based distribution.
-
Install llvm:
sudo apt-get install llvm-3.5 llvm-3.5-tools
-
Install ghc from from distribution repository:
sudo apt-get install haskell-platform
-
Because ghci uses it (and even though the ghci you build will be kind of useless), you'll need to install ncurses:
sudo apt-get install ncurses-dev
-
Some notes:
-
Each version of GHC requires a specific version of llvm. For ghc-7.8 or ghc-7.10 you need to use llvm-3.5. llvm-3.5 has a bug regarding the ghc calling convention that was fixed in 3.5.2. Make sure you have installed llvm 3.5.2 or higher. In current Debian, this is in unstable.
-
There are settings for llvm versions in
/usr/lib/ghc/settings. You may need to set("LLVM llc command", "llc-3.5"), ("LLVM opt command", "opt-3.5")there.
-
ghc-7.6 and ghc-7.8 have bugs preventing building a cross-compiling ghc-7.10. Best results seem to be obtained by using 7.10 for both the host ghc and the compiler source.
-
(Gentoo specific) The Raspberry Pi tools that we will use are dynamically linked to 32-bit zlib, so if your host is 64-bit, you need
echo "sys-libs/zlib abi_x86_32" >> /etc/portage/package.use/ghc-crossdev-rpi
-
-
Create directory for cross compiler build and change into it:
mkdir ~/raspberrypi cd ~/raspberrypi
-
Install Raspberry Pi compilation tools into the working directory:
git clone https://github.com/raspberrypi/tools.git
-
Add the cross compiler directory to your shell path:
export PATH=$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH
-
Download GHC tarball (
ghc-7.10.2-src.tar.xz) into working directory and unpack:tar xJf ghc-7.10.2-src.tar.xz
-
Configure the GHC build using the following commands: (This will configure the build such that it uses the installed Raspberry Pi cross tools, and installs the GHC cross tools in
/usr/local/haskell/ghc-7.10.2-arm).cd ~/raspberrypi/ghc-7.10.2 ./configure --target=arm-linux-gnueabihf --with-gcc=arm-linux-gnueabihf-gcc \ --prefix=/usr/local/haskell/ghc-7.10.2-arm --with-llc=llc-3.5 --with-opt=opt-3.5 cp mk/build.mk.sample mk/build.mk
-
Edit
mk/build.mkand uncomment the line withBuildFlavour = perf-crossorBuildFlavour = quick-cross, as preferred.
-
The Raspberry Pi was setup with Raspbian version September 2014.
-
On the Raspberry Pi install ncurses-dev:
sudo apt-get install ncurses-dev
-
Copy the RootFS from the Raspberry Pi to the build machine for required libraries (where
$PI_ADDRin the rsync command is the IP address of your Pi):cd ~/raspberrypi mkdir rootfs rsync -rl --delete-after --safe-links pi@$PI_ADDR:/{lib,usr} $HOME/raspberrypi/rootfs
-
There are quite a few symlinks in the Pi file system’s
/usr/lib/arm-linux-gnueabihfdirectory that point to/lib/arm-linux-gnueabihfthat will not be copied properly by the above rsync. Therefore, change to the root file system copy’s/usr/lib/arm-linux-gnueabihfand create the following links:cd ~/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf ln -s ../../../lib/arm-linux-gnueabihf/libanl.so.1 libanl.so ln -s ../../../lib/arm-linux-gnueabihf/libBrokenLocale.so.1 libBrokenLocale.so ln -s ../../../lib/arm-linux-gnueabihf/libcidn.so.1 libcidn.so ln -s ../../../lib/arm-linux-gnueabihf/libcrypt.so.1 libcrypt.so ln -s ../../../lib/arm-linux-gnueabihf/libdl.so.2 libdl.so ln -s ../../../lib/arm-linux-gnueabihf/libm.so.6 libm.so ln -s ../../../lib/arm-linux-gnueabihf/libnsl.so.1 libnsl.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_compat.so.2 libnss_compat.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_dns.so.2 libnss_dns.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_files.so.2 libnss_files.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_hesiod.so.2 libnss_hesiod.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_nisplus.so.2 libnss_nisplus.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_nis.so.2 libnss_nis.so ln -s ../../../lib/arm-linux-gnueabihf/libresolv.so.2 libresolv.so ln -s ../../../lib/arm-linux-gnueabihf/librt.so.1 librt.so ln -s ../../../lib/arm-linux-gnueabihf/libthread_db.so.1 libthread_db.so ln -s ../../../lib/arm-linux-gnueabihf/libutil.so.1 libutil.so
-
Find the current ARM compiler root filesystem using the following command:
arm-linux-gnueabihf-gcc -print-sysroot
-
On the build system I was using this was:
~/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/../arm-linux-gnueabihf/libc -
Rename the original and link in the rootfs copied from the Pi:
cd ~/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/../arm-linux-gnueabihf mv libc libc.orig ln -s ~/raspberrypi/rootfs libc
-
Start the build with:
cd ~/raspberrypi/ghc-7.10.2 make
-
When the build finishes, the cross compiler will be available at:
~/raspberrypi/ghc-7.10.2/inplace/bin/ghc-stage1 -
Install the build cross compiler:
sudo make install
-
The install binary directory,
/usr/local/haskell/ghc-7.10.2-arm/binshould be added to your shell path so that the compiler and tools are available.
-
The following sequence of commands is an example of setting up the cabal sandbox and issuing the proper cabal command to build and install the package
randomwith the cross compiler. This should work for any pure-Haskell package withbuild-type: Simple.cabal sandbox init cabal --with-ghc=arm-unknown-linux-gnueabihf-ghc --with-ghc-pkg=arm-unknown-linux-gnueabihf-ghc-pkg --with-ld=arm-linux-gnueabihf-ld --with-strip=arm-linux-gnueabihf-strip install random
-
Packages that use
hsc2hsand/or configure scripts (such asdirectory) require some additional flags. You may want to use the below ascabal.configfile in the directory containing your sandbox:jobs: 1 compiler: ghc with-compiler: arm-unknown-linux-gnueabihf-ghc with-hc-pkg: arm-unknown-linux-gnueabihf-ghc-pkg configure-option: --host=arm-linux-gnueabihf program-locations gcc-location: arm-linux-gnueabihf-gcc ar-location: arm-linux-gnueabihf-ar ld-location: arm-linux-gnueabihf-ld strip-location: arm-linux-gnueabihf-strip program-default-options hsc2hs-options: -xThis should be equivalent to:
cabal --with-ghc=arm-unknown-linux-gnueabihf-ghc \ --with-ghc-pkg=arm-unknown-linux-gnueabihf-ghc-pkg \ --with-gcc=arm-linux-gnueabihf-gcc \ --with-ar=arm-linux-gnueabihf-ar \ --with-ld=arm-linux-gnueabihf-ld \ --with-strip=arm-linux-gnueabihf-strip \ --configure-option=--host=arm-linux-gnueabihf \ --hsc2hs-option=-x \ install $package_name