--- PRE --- This document has been wikified here: https://wiki.gentoo.org/wiki/Embedded_Handbook/General/Creating_a_cross-compiler It is also newer than the text here, so please refer to that. ----- Intro ----- 2006-06-08 Mike Frysinger brain dumpage of cross-compiling low level details target audience: people who (for some stupid reason or another) really really want to create their own cross compiler with binutils/(glibc|uclibc)/gcc all by themselves. what this isn't: this document makes no attempt whatsoever to cover the myriad of build failures you are likely to see along the way. if you need such help, see the References section at the end of this file for some pointers. don't bug me :P if you're just confused and want a cross-compiler now, then please use the http://crosstool-ng.org/ project. it works on a ton of distros and handles a lot of common errors related to building cross-compilers. -------- Overview -------- There are generally two ways to build up your cross-compiler. The "accepted" way, and the cheater's shortcut. The current "accepted" way is: (1) binutils (2) kernel headers (3) libc headers (4) gcc stage1 (c-only) (5) libc (6) gcc stage2 (c/c++/etc...) The cheater's shortcut is: (1) binutils (2) gcc stage1 (c-only) (3) kernel headers (4) libc (5) gcc stage2 (c/c++/etc...) The reason people are keen on the shortcut is that the libc headers step tends to take quite a while, especially on slower machines. It can also be kind of a pain to setup kernel/libc headers without a usuable cross compiler. Note though that if you seek help with cross-compilers, upstream projects will not want to help you if you took the shortcut. Also note that the shortcut requires the gcc stage1 to be "crippled". Since you're building without headers, you cannot enable the sysroot option nor can you build up proper gcc libs. This is OK if the only thing you use the stage1 is building the C library and a kernel, but beyond that you need a nice sysroot based compiler. Below I will describe the "accepted" way as the steps are pretty much the same. You just need some extra patches for gcc in order to take the shortcut. ------- Targets ------- ------- Sysroot ------- We will be cross-compiling using the sysroot method. But wtf is sysroot ? From the gcc docs: Tells GCC to consider dir as the root of a tree that contains a (subset of) the root filesystem of the target operating system. Target system headers, libraries and run-time object files will be searched in there. The structure of the sysroot dir is the same as the root filesystem of the machine you're targeting with the cross-compiler. In Gentoo/portage terms, it's like using ROOT. Let's look at the typical setup. The top level dir is commonly rooted in /usr/$CTARGET /usr/$CTARGET/ |-- bin/ |-- lib/ critical runtime libs (libc/ldso/etc...) `-- usr/ |-- include/ development headers | |-- linux/ like the linux kernel | `-- asm/ like the arch-specific `-- lib/ non critical runtime libs / development libs As you can see, it's just like the directory setup / but in /usr/$CTARGET. This setup is on purpose so you can easily migrate applications/libraries out of /usr/$CTARGET and into / on your target board. Non-sysroot note: The old style of cross-compilers was to use --prefix=/usr/$CTARGET. If you are using versions of binutils/gcc that predate sysroot support, you may have to do just this. -------- Binutils -------- Grab the binutils-2.16.1.tar.bz2 tarball and unpack it. The --disable-werror configure option is to prevent binutils from aborting the compile due to warnings. Great feature for developers, pita for users. To configure/build/install: $ ./configure \ --target=$CTARGET \ --prefix=/usr \ --with-sysroot=/usr/$CTARGET \ --disable-werror $ make $ make install DESTDIR=$PWD/install-root The reason we install into the localdir is so we can remove crap that doesn't belong. For example, a normal install will give us /usr/lib/libiberty.a which doesn't belong in our host /usr/lib. So clean out stuff first: $ rm -rf install-root/usr/{info,lib,man,share} And install what's left: # cp -a install-root/* / -------------- Kernel headers -------------- Grab the linux-2.6.16.tar.bz2 tarball and unpack it. $ yes "" | make ARCH=$ARCH oldconfig prepare With 2.6.x, this will probably end in an error because you don't have a gcc cross-compiler yet, but you can ignore that. Just copy over the headers: # mkdir -p /usr/$CTARGET/usr/include # cp -a include/linux include/asm-generic /usr/$CTARGET/usr/include/ # cp -a include/asm-$ARCH /usr/$CTARGET/usr/include/asm ------------ libc headers ------------ -- glibc -- Grab the glibc-2.4.tar.bz2 tarball and unpack it. Glibc is picky, so you'll have to compile in a dir separate from the source code. Again, you'll probably see errors because you don't have a gcc cross-compiler yet, but just ignore them. $ mkdir build $ cd build $ ../configure \ --host=$CTARGET \ --prefix=/usr \ --with-headers=/usr/$CTARGET/usr/include \ --disable-sanity-checks # make -k install-headers install_root=/usr/$CTARGET glibc sucks at life so you have to do a few things by hand: # mkdir -p /usr/$CTARGET/usr/include/gnu # touch /usr/$CTARGET/usr/include/gnu/stubs.h # cp bits/stdio_lim.h /usr/$CTARGET/usr/include/bits/ -- uClibc -- Grab the uClibc-0.9.28.tar.bz2 tarball and unpack it. ---------- GCC stage1 ---------- We first have to help gcc find the current libc headers. # ln -s usr/include /usr/$CTARGET/sys-include Grab the gcc-4.1.1.tar.bz2 tarball and unpack it. $ mkdir build $ cd build $ ../configure \ --target=$CTARGET \ --prefix=/usr \ --with-sysroot=/usr/$CTARGET \ --enable-languages=c \ --disable-shared \ --disable-checking \ --disable-werror \ --disable-libmudflap \ --disable-libssp $ make $ make install DESTDIR=$PWD/install-root Same as binutils, gcc leaves some stuff behind we don't want. $ rm -rf install-root/usr/{info,include,lib/libiberty.a,man,share} Install what's left: # cp -a install-root/* / ---------- libc ---------- -- glibc -- Nuke the old glibc build dir and recreate it. $ rm -rf build $ mkdir build $ cd build $ ../configure \ --host=$CTARGET \ --prefix=/usr $ make # make install install_root=/usr/$CTARGET -- uClibc -- ---------- GCC stage2 ---------- $ ./configure \ --target=$CTARGET \ --prefix=/usr \ --with-sysroot=/usr/$CTARGET \ --enable-languages=c,c++ \ --enable-shared \ --disable-checking \ --disable-werror $ make # make install ---- Help ---- Where to seek help: The crossgcc mailing list: https://sourceware.org/ml/crossgcc/ Google: https://www.google.com/ ---------- References ---------- Gentoo Homepage: https://wiki.gentoo.org/wiki/Embedded_Handbook crosstool: http://www.kegel.com/crosstool/ crosstool-ng: http://crosstool-ng.org/ Binutils Homepage: https://sourceware.org/binutils/ Binutils Download: https://ftp.gnu.org/gnu/binutils/ Binutils Manual: https://sourceware.org/binutils/docs/ GCC Homepage: https://gcc.gnu.org/ GCC Download: https://ftp.gnu.org/gnu/gcc/ GCC Manual: https://gcc.gnu.org/onlinedocs/ GCC Install Docs: https://gcc.gnu.org/install/ Glibc Homepage: https://www.gnu.org/software/libc/ Glibc Download: https://ftp.gnu.org/gnu/glibc/ Glibc Manual: https://www.gnu.org/software/libc/manual/ Glibc Install Docs: https://www.gnu.org/software/libc/manual/html_node/Installation.html#Installation uClibc Homepage: https://www.uClibc.org/ uClibc Download: https://www.uclibc.org/downloads/ Linux Kernel Homepage: https://www.kernel.org/ Linux Kernel Download: https://www.kernel.org/pub/linux/kernel/