Cross compilation

From flashrom
Revision as of 06:19, 7 May 2013 by Hailfinger (talk | contribs) (FreeBSD)
Jump to: navigation, search

Cross building on Linux for non-Windows/non-DOS operating systems is what can generally be described as a nightmare. Prepackaged cross compilers are not available, and various websites on the net explain how to build toolchains for either totally obsolete operating system releases or the solutions simply don't work. Having a recent native gcc on the host makes things a lot worse because older gcc versions and their support libraries can't be compiled with recent gcc. If in doubt, gcc documentation should not be followed unless you want to experience failure firsthand.

This page is an attempt to list what worked, what didn't work and where instructions are just crap.

First things first:

  • Get everything in a clean state. If you have any previous unfinished/non-working/working cross compiler, binutils, include files or libraries for a given target, use rm -rf liberally and start from scratch.
  • If you can download a prepackaged cross compiler for DOS (DJGPP) or Windows (cross MinGW), use it! I'm not going to cover this if I can help it.
  • If you can download a prepackaged cross compiler for non-x86 Linux, use it!
  • These instructions are for a host running an x86_64 installation of openSUSE Linux 12.2, but they should work on other distributions.
  • openSUSE has a repository with extra cross compilers in Torsten Duwe's home project at the Open Build Service.
  • Cross compilers and binutils are going to end up in /opt/cross/ .


FreeBSD

The cross-build environment will be installed in /opt/cross/x86_64-pc-freebsd9/ . Note that this script in the current state makes a few assumptions about the location of tarballs and unpacked source, assumes binutils have already been built and just need to be installed, and assumes you have write rights in /opt/cross . I am deeply indebted to Marcelo Gornstein who described the process for older compilers and older FreeBSD at http://marcelog.github.io/articles/cross_freebsd_compiler_in_linux.html .

#!/bin/bash
# This should build a cross-compiler for x86_64 FreeBSD 9 on x86_64 openSUSE 12.2. It should. Really.
#
# Written by Carl-Daniel Hailfinger shortly before the gcc-inflicted brain damage caused paralysis
# in the hope that it will be useful and save others from this cruel fate.
# Licensed under the WTFPL.
#
# Please note that gcc 4.7 is totally and utterly unable to build gmp<4.3, mpfr<2.4 and mpc<0.8 .
# It's a miracle it can build some older versions of itself at all.
#
rm -rf /opt/cross/x86_64-pc-freebsd9/; mkdir /opt/cross/x86_64-pc-freebsd9/
cd /opt/cross/x86_64-pc-freebsd9/
# This link is essential. Like most things released by the GNU project, configure and build scripts
# generated with autotools are crap. Would you expect gmp/mpfr/mpc libraries to install
# themselves by default in $PREFIX/lib64, and gcc to search those libraries in $PREFIX/lib64 ?
# No amount of specifying LD_LIBRARY_PATH and LD_RUN_PATH will help because "gcc knows better".
# Oh, and if you ever try to build such a cross compiler the way recommended by the GNU project
# (that is, have gmp/mpfr/mpc inside the gcc directory and have the gcc configure script handle
# everything else automatically), be prepared for a failing build. The officially recommended way
# to build was apparently never tested for building a cross compiler.
# "Jeder ist zu etwas nütze, und sei es nur als schlechtes Beispiel." (German proverb)
ln -s lib64 lib
mkdir -p /opt/cross/x86_64-pc-freebsd9/x86_64-pc-freebsd9/include
mkdir -p /opt/cross/x86_64-pc-freebsd9/x86_64-pc-freebsd9/lib
cd /opt/cross/x86_64-pc-freebsd9/x86_64-pc-freebsd9/
tar xv --strip-components=2 -f ~/cross-compilers/freebsd91-amd64-base.txz ./usr/include/
tar xv --strip-components=2 -f ~/cross-compilers/freebsd91-amd64-base.txz ./usr/lib/
tar xv --strip-components=1 -f ~/cross-compilers/freebsd91-amd64-base.txz ./lib/
cd lib/
find -type l|while read a; do readlink $a|grep -q / && { linktarget=$(readlink $a|sed "s_^/lib/__"); rm $a; ln -s $linktarget $a; }; done
echo "Press Enter to continue"
read

cd ~/cross-compilers/freebsd-amd64/

cd binutils-2.23.2/
# configure etc.
gmake install
cd ..
echo "Press Enter to continue"
read

# LD_LIBRARY_PATH and LD_RUN_PATH may be totally unnecessary. Or not. TODO: Check that.

rm -rf gmp-obj mpfr-obj mpc-obj gcc-obj
mkdir gmp-obj; cd gmp-obj/
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 ~/cross-compilers/gmp-4.3.2/configure --prefix=/opt/cross/x86_64-pc-freebsd9 --enable-shared --enable-static --enable-mpbsd --enable-fft --enable-cxx --host=x86_64-pc-freebsd9
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake -j 8
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake install
ldd /opt/cross/x86_64-pc-freebsd9/lib64/libgmp.so.*
cd ..
echo "Press Enter to continue"
read

mkdir mpfr-obj; cd mpfr-obj
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 ~/cross-compilers/mpfr-2.4.2/configure --prefix=/opt/cross/x86_64-pc-freebsd9 --with-gnu-ld --with-gmp=/opt/cross/x86_64-pc-freebsd9 --enable-static --enable-shared --host=x86_64-pc-freebsd9
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake -j 8
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake install
ldd /opt/cross/x86_64-pc-freebsd9/lib64/libmpfr.so.*
cd ..
echo "Press Enter to continue"
read

mkdir mpc-obj; cd mpc-obj
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 ~/cross-compilers/mpc-0.8.1/configure --prefix=/opt/cross/x86_64-pc-freebsd9 --with-gnu-ld --with-gmp=/opt/cross/x86_64-pc-freebsd9 --with-mpfr=/opt/cross/x86_64-pc-freebsd9 --enable-static --enable-shared --host=x86_64-pc-freebsd9
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake -j 8
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake install
ldd /opt/cross/x86_64-pc-freebsd9/lib64/libmpc.so.*
cd ..
echo "Press Enter to continue"
read

mkdir gcc-obj; cd gcc-obj
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 ~/cross-compilers/gcc-4.5.2/configure --without-headers --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --disable-nls --enable-libssp --enable-gold --enable-ld --target=x86_64-pc-freebsd9 --prefix=/opt/cross/x86_64-pc-freebsd9 --with-gmp=/opt/cross/x86_64-pc-freebsd9 --with-mpc=/opt/cross/x86_64-pc-freebsd9 --with-mpfr=/opt/cross/x86_64-pc-freebsd9 --disable-libgomp
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake -j 8
LD_LIBRARY_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 LD_RUN_PATH=/opt/cross/x86_64-pc-freebsd9/lib64 gmake install
cd ..
echo "Press Enter to continue"
read

Random notes

Random stuff which was written down during compilation...

  - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
    during execution
  - add LIBDIR to the `LD_RUN_PATH' environment variable
    during linking
  - use the `-Wl,-rpath -Wl,LIBDIR' linker flag

not that any of these have been particularly effective...