Cross compilation for PPC64 - camfort/camfort GitHub Wiki
PowerPC64 chips can run in big endian (ppc64) or little endian mode (ppc64). Use a suitable arch below for your cross tools.
PREFIX=/home/acr31/ppc64
You need to install a cross compiling gcc and binutils:
sudo apt-get install gcc-5-powerpc64-linux-gnu
There are good instructions for building a cross-compiling GHC here: https://ghc.haskell.org/trac/ghc/wiki/Building/CrossCompiling
GHC depends on a native version of ncurses. You need to compile --with-termlib because otherwise ncurses doesn't provide the library files the ghc wants. You also need -P on CPPFLAGS.
wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz
tar xf ncurses-6.0.tar.gz
cd ncurses-6.0
./configure --host=powerpc64-linux-gnu --prefix=$PREFIX --with-termlib CPPFLAGS=-P
make
make install
GHC on ppc64le wouldn't compile due to an error with the internal GMP. I fixed this by downloading and installing my own GMP. This wasn't necessary on ppc64.
wget https://gmplib.org/download/gmp/gmp-6.1.1.tar.xz
tar xf gmp-6.1.1.tar.xz
cd gmp-6.1.1.tar.xz
./configure --prefix=$PREFIX --host=powerpc64le-linux-gnu
make
make install
Download the ghc sources and configure for the target architecture. Create a build.mk from the sample and set HADDOCK_DOCS = NO and Stage1Only = YES. If you are using the built-in GMP you can omit the gmp parameters on configure.
wget http://downloads.haskell.org/~ghc/8.0.1/ghc-8.0.1-src.tar.xz
tar xf ghc-8.0.1-src.tar.xz
cd ghc-8.0.1
./configure --target=powerpc64le-linux-gnu --prefix=$PREFIX \
--with-gmp-includes=$PREFIX/include --with-gmp-libraries=$PREFIX/lib
make
The build will then fail when compiling terminfo because it can't find the ncurses library. I couldn't work out a way to get the build system to propagate the LDFLAGS and CFLAGS options into the terminfo build: I think the built-in cabal is swallowing them. Instead let the build fail and then copy and paste the cabal/configure command that failed and manually add -L$PREFIX/lib to LDFLAGS and --extra-lib-dirs and add -I$PREFIX/include to CFLAGS and --extra-include-dirs.
Let this run, ignore the warning about unrecognised --with-compiler flag, and then run make again.
On my machine the version of GHC I downloaded wouldn't play nice with cabal resulting in mysterious errors. Download the cabal library and the cabal install tool from https://www.haskell.org/cabal/download.html and install in $PREFIX
git clone https://github.com/xianyi/OpenBLAS.git
git checkout v0.2.19
cd OpenBLAS
make CC=/usr/bin/powerpc64-linux-gnu-gcc FC=/usr/bin/powerpc64-linux-gnu-gfortran LD=/usr/bin/powerpc64-linux-gnu-ld HOSTCC=gcc TARGET=POWER7 # or POWER8
make PREFIX=$PREFIX install
git clone https://github.com/camfort/camfort.git
git checkout v0.901
cd camfort
# Remove spurious reference to TemplateHaskell
sed -e "s/TemplateHaskell, //" -i src/Camfort/Specification/Units/Environment.hs
$PREFIX/bin/cabal sandbox init
cat <<EOF > cabal.config
compiler: ghc
with-compiler: $PREFIX/bin/powerpc64-unknown-linux-gnu-ghc
with-hc-pkg: $PREFIX/bin/powerpc64-unknown-linux-gnu-ghc-pkg
configure-option: --host=powerpc64-unknown-linux
program-locations
gcc-location: powerpc64-linux-gnu-gcc
ar-location: powerpc64-linux-gnu-ar
ld-location: powerpc64-linux-gnu-ld
strip-location: powerpc64-linux-gnu-strip
program-default-options
hsc2hs-options: -x
EOF
$PREFIX/bin/cabal install hmatrix-0.18.0.0 --flags=openblas \
--extra-include-dirs="$PREFIX/include" \
--extra-lib-dirs="$PREFIX/lib"
Check the version of libc installed on your target machine (use 'ldd --version'). If it is old (e.g. 2.12) you need to add a missing symbol to your binary to get it to link at runtime. There's actually only one function which is actually missing for our needs. (You can find this out by building camfort and doing 'ldd -v camfort' on the target machine). The function which is missing is __fdelt_chk. Create fake object file for this function:
cat <<EOF > fdelt_chk.c
#include <sys/select.h>
__asm__(".symver __fdelt_chk,__fdelt_chk@GLIBC_2.15");
long int __fdelt_chk (long int d) {
return d / __NFDBITS;
}
EOF
cat <<EOF > version-script.txt
GLIBC_2.15 {
global:
__fdelt_chk;
};
EOF
powerpc64-linux-gnu-gcc -o fdelt_chk.o fdelt_chk.c -Wl,--version-script -Wl,version-script.txt -c
$PREFIX/bin/cabal install --ghc-options="fdelt_chk.o"
mkdir camfort
cp --preserve=links $PREFIX/lib/libopenblas* camfort
cp .cabal-sandbox/bin/camfort camfort
tar zcf camfort.tar.gz camfort
tar xf camfort.tar.gz
cd camfort
LD_LIBRARY_PATH=. ./camfort