Build Cross Compiler
Erzeugung eines Cross Compiler aus Sourcen.
Software
Auf dem Host System braucht es einen gcc. und wenn das Host System zu alte Versionen hat auch noch
Die folgenden Quellen
libc
Welche glibc? Es gibt diverse. Am verbreitesten dürfte die gnu-libc sein (glibc). Für den embedded Bereich mit beschränkten (Speicher-) Resourcen gibt es spezielle kleinere libc implementierungen (ulibc, dietlibc, etc). Diese sind nicht binärkompatibel zur glibc und implementieren manche funktionen nicht. Wenn man sein komplettes Embedded System mit diesen libc compiliert (und die Funktionen ausreichen) die erste Wahl.
Die Embedded Gnu libc (eglic) versucht binärkompatibel zur glibc zu sein und gleichzeitig besser geeignet für Cross Compiling zu sein. Sie basiert auf der glibc und wird auch regelmäßig mit ihr abgeglichen. Debian stellt mit Version 6.0 (Squeeze) auf eglibc um.
Build Schritte
- erzeugen von cross binutils
- minimaler statischer cross C compiler
- kernelheader für Zielsystem
- libc Header für Zielsystem
- cross C Compiler
- libc für Zielsystem
- vollständiger C und C++ cross compiler
Ein vollständiges Build script findet sich im
https://www-acc.gsi.de/viewvc/view/bel/embedded/trunk/crosscompiler/ Subversion
TARGET=powerpc-unknown-linux-gnu
TOOLCHAIN=/install/crosstools # die cross compiler
SYSROOT=/install/sysroot # libraries für das Zielsystem
die meisten gnu tools erwarten, dass der build out-of-tree erfolgt. Also nicht im ausgepackten tarball
cross Binutils
mkdir build/binutils && cd build/binutils
../../src/binutils/configure \
--target=$TARGET --prefix=$TOOLCHAIN --with-sysroot=$SYSROOT
statischer cross C Compiler
wenn gmp, mpc und mpfr des Host Systems zu alt sind, die entsprechenden Sourcen als Ordner in den gcc sourcetree legen
src/gcc # ausgepacktes gcc tarball
src/gcc/gmp # ausgepacktes gmp tarball (ohne versionsnummer)
src/gcc/mpc
src/gcc/mpfr
mkdir build/gcc-static && cd build/gcc-static
../../src/gcc/configure \
--target=$TARGET --prefix=$TOOLCHAIN \
--without-headers --with-newlib \ # do not search for any libc anywhere, newlib just has the right switches
--disable-shared --disable-threads \
--disable-libssp --disable-libgomp --disable-libmudflap \ # die brauchen teile der libc
--disable-nls \ # wer braucht schon sprachen ausser englisch
--enable-lanugages=c # nur c, kein c++, java, ada, etc..
make all-gcc # nur den C Compiler
make install-gcc
das muss im ausgepackten tarball erfolgen.
Wir konfigurieren nichts, wir wollen nur die Header.
make \
ARCH=powerpc \ # oder arm, oder x86_64 oder ...
INSTALL_HDR_PATH=$SYSROOT/usr \ # ergibt dann $SYSROOT/usr/include/{linux,asm,asm-generic,...}
CROSS_COMPILE=$TARGET \ # powerpc-unknown-linux-gnu
headers_install
BUILD_CC=gcc \ # wenn was für den Host compiliert werden soll
CC=$TOOLCHAIN/bin/$TARGET-gcc \ # alles dessen output "cross" sein soll
CXX=$TOOLCHAIN/bin/$TARGET-g++ \
AR=$TOOLCHAIN/bin/$TARGET_TUPLE-ar \
LD=$TOOLCHAIN/bin/$TARGET_TUPLE-ld \
RANLIB=$TOOLCHAIN/bin/$TARGET_TUPLE-ranlib \
../../src/eglibc/configure \
--prefix=/usr \ # immer /usr sonst wird libc unglücklich
--with-headers=$SYSROOT/usr/include \ # die kernel header
--build=$BUILD \ # das hostsystem i386-unknown-linux (nachsehen mit gcc -dumpmachine)
--host=$TARGET \ # das ziel
--disable-nls \
--disable-profile \
--without-gd --without-cvs \
--enable-add-ons
make \
install-headers \ # nur die header
install_root=$SYSROOT \ # und den angegebenen prefix a sysroot
install-bootstrap-headers=yes # ein paar workarounds
um einen gcc mit diesen Headern zu bauen braucht es aber noch ein paar Bibliotheken. Diese werden einzeln erzeugt
make csu/subdir_lib
mkdir -p $SYSROOT/usr/lib
cp csu/crt1.o csu/crti.o csu/crtn.o $SYSROOT/usr/lib
aus irgendeinen Grund besteht der gcc darauf eine libc zu haben, auch wenn er nicht dagegen gelinkt wird. Erzeugen einer dummy bibliothek die den richtigen namen hat.
$TOOLCHAIN/bin/$TARGET-gcc \
-nostdlib -nostartfiles \
-shared \
-x c /dev/null \
-o $SYSROOT/usr/lib/libc.so
cross C Compiler
mkdir build/gcc-min && cd build/gcc-min
../../src/gcc/configure \
--target=$TARGET --prefix=$TOOLCHAIN \
--with-sysroot=$SYSROOT \ # die header an den üblichen stellen
--disable-libssp --disable-libgomp --disable-libmudflap \ # die brauchen teile der libc
--disable-nls \ # wer braucht schon sprachen ausser englisch
--enable-lanugages=c # nur c, kein c++, java, ada, etc..
PATH=$TOOLCHAIN/bin:$PATH \ # damit er die cross-binutils findet
make
PATH=$TOOLCHAIN/bin:$PATH \
make install
libc für Zielsystem
# configure bleibt gleich, nur jetzt compilieren wir auch
PATH=$TOOLCHAIN/bin:$PATH \ # findet cross-binutils und cross-gcc
make
PATH=$TOOLCHAIN/bin:$PATH \ # findet cross-binutils und cross-gcc
make install install_root=$SYSROOT
vollständiger C und C++ cross compiler
mkdir build/gcc && cd build/gcc
../../src/gcc/configure \
--target=$TARGET --prefix=$TOOLCHAIN \
--with-sysroot=$SYSROOT \ # die header an den üblichen stellen
--disable-libssp --disable-libgomp --disable-libmudflap \ # wird nicht gebraucht
--disable-nls \ # wer braucht schon sprachen ausser englisch
--enable-__cxy_atexit \ # die glibc will das
--enable-lanugages=c,c++ #
PATH=$TOOLCHAIN/bin:$PATH \ # damit er die cross-binutils findet
make
PATH=$TOOLCHAIN/bin:$PATH \
make install
Ergebnis
in
$SYSROOT
liegt eine auf dem Zielsystem lauffähige libc und die zugehörigen Standardbibliotheken.
in
$TOOLCHAIN
liegen binutils und gcc als crosscompiler.
--
ChristophHandel - 15 Jun 2010