4133
Comment:
|
12001
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
= Building a Cross Compiler = This document will help you build Debian packages of a cross-compilation toolchain. It is based on [http://psas.pdx.edu/DebianCrossCompilerHowto a HOWTO] by Josh Triplett, with his kind permission. |
<<TableOfContents()>> = Installing a Cross Compiler = This document will help you obtain Debian packages of a cross-compilation toolchain. It is based on [[http://psas.pdx.edu/DebianCrossCompilerHowto|a HOWTO]] by Josh Triplett, with his kind permission. Note that most cross-toolchain combinations you might actually want within Debian are built by the Embedded Debian Project, so you may well just be able to apt-get what you need on their Toolchains page: http://www.emdebian.org/tools/crosstools.html . We'll say that again: '''MOST PEOPLE SHOULDN'T BE BUILDING THEIR OWN CROSS-TOOLCHAIN - THEY SHOULD JUST INSTALL A PRE-BUILT ONE LIKE ANY OTHER PACKAGE'''. == To install a prebuilt cross compiler == === What if I have an Ubuntu system or want to do multiarch-style crossbuilding? === If you have an Ubuntu (maverick/10.10, or later) system and want an armel or armhf toolchain then they are already part of your distro - just apt-get install arm-linux-gnueabi-gcc (for armel) or arm-linux-gnueabihf-gcc (for armhf). Backports for Lucid are available too. For other architecutures, or if you have a Debian system you need to get toolchains from Emdebian. Note that these toolchains search in the 'dpkg-cross' cross-lib/headers paths, not the new multiarch paths so are not very useful for multiarch cross-building. Currently (March 2012) you need to use the Ubuntu-supplied toolchains for that. === Installing cross-toolchains from Emdebian === Add the Emdebian keyring from Debian before you start. {{{ apt-get install emdebian-archive-keyring }}} Add two apt sources, one for your normal mirror and one for Emdebian: {{{ deb http://ftp.XX.debian.org/debian squeeze main deb http://www.emdebian.org/debian squeeze main }}} Create a new file in {{{/etc/apt/sources.list.d/}}} with the above lines. Use whatever is your normal Debian mirror for the first line which brings in some dependencies which are no longer in Wheezy or unstable. Now just install your toolchain, e.g. for armel: {{{ apt-get update apt-get install g++-4.4-arm-linux-gnueabi }}} Emdebian also maintain scripts which effectively do what this page describes. Take a look at the 'buildcross' package from Debian experimental, which will build a whole range of toolchains. http://packages.qa.debian.org/b/buildcross.html '''Most users do not need to build the cross-compiler''' |
Line 7: | Line 52: |
== If you do need to build the compiler == |
|
Line 8: | Line 55: |
==== Notes for Debian unstable ==== We build {{{gcc-4.4}}} whose cross package additionally build-depends on {{{gcc-4.4-source}}} which you henceforth must install. The package {{{linux-kernel-headers}}} is now called {{{linux-libc-dev}}} instead. The three packages {{{libc6-dev}}}, {{{libc6}}}, {{{linux-libc-dev}}} have additional dependencies, so you need to get the (native for the target arch) {{{gcc-4.4-base}}}, {{{libc-bin}}}, {{{libc-dev-bin}}} and {{{libgcc2}}} (libgcc1, libgcc4, whatever your target needs) packages additionally. Now, {{{dpkg-cross}}} refuses to convert those without “any useful files”, so you need to pass the -A option in addition to -b and -a $ARCH. A bit uglily, you get {{{libgcc2-m68k-cross}}} depending on {{{gcc-4.4-base-m68k-cross}}} from {{{dpkg-cross}}} and later, after compiling, {{{libgcc2-m68k-cross}}} depending on {{{gcc-4.4-m68k-linux-gnu-base}}}. Just remove the {{{dpkg-cross}}}-generated one once you got the new ones. |
|
Line 21: | Line 78: |
ARCH=arm | unset ARCH # make sure it’s not exported ARCH=arm # set to the value we want to use |
Line 49: | Line 107: |
While still in the binutils directory: {{{ TARGET=$ARCH-linux-gnu fakeroot debian/rules binary-cross > ../binutils.build 2>&1 || echo 'Build error' |
{{{ cd binutils-VERSION export TARGET=$(dpkg-architecture -a$ARCH -qDEB_HOST_GNU_TYPE 2>/dev/null) # this is for binutils <= 2.20 #fakeroot debian/rules binary-cross >../binutils.build 2>&1 || echo 'Build error' # this is for binutils >= 2.21 dpkg-buildpackage -b -uc -us -rfakeroot >../binutils.build 2>&1 || echo 'Build error' unset TARGET |
Line 53: | Line 116: |
sudo dpkg -i binutils-powerpc-linux-gnu_VERSION_HOSTARCH.deb }}} |
sudo dpkg -i binutils-${TARGET}_VERSION_HOSTARCH.deb }}} Note: the instructions are not totally correct. For example, with ARCH=amd64 you get TARGET=x86_64-linux-gnu and binutils-x86-64-linux-gnu (replace _ with - simply). For i386, you get TARGET=i486-linux-gnu but you’ll probably want i386-linux-gnu instead. |
Line 57: | Line 122: |
You will need cross-compilation packages for various libraries; dpkg-cross can convert native packages for the target architecture into packages usable for cross-compilation. {{{ wget http://ftp.XX.debian.org/debian/pool/main/g/glibc/libc6-dev_VERSION_$ARCH.deb wget http://ftp.XX.debian.org/debian/pool/main/g/glibc/libc6_VERSION_$ARCH.deb wget http://ftp.XX.debian.org/debian/pool/main/l/linux-kernel-headers/linux-kernel-headers_VERSION_powerpc.deb |
You will need cross-compilation packages for various libraries; dpkg-cross can convert native packages for the target architecture into packages usable for cross-compilation. '''Note''' that the mirror ftp.us.debian.org only has amd64 and i386 packages, so to build a cross-compilation toolchain for another architecture (e.g. arm), you will have to use a mirror other than ftp.us.debian.org. {{{ wget http://ftp.XX.debian.org/debian/pool/main/e/eglibc/libc6-dev_VERSION_$ARCH.deb wget http://ftp.XX.debian.org/debian/pool/main/e/eglibc/libc6_VERSION_$ARCH.deb wget http://ftp.XX.debian.org/debian/pool/main/l/linux-kernel-headers/linux-kernel-headers_VERSION_$ARCH.deb |
Line 65: | Line 130: |
It may be needed to download and convert {{{libc-bin}}} and {{{libc-dev-bin}}} packages too, otherwise the packages’ dependencies can maybe not be resolved. Use {{{dpkg-cross -a m68k -A -b l*.deb}}} in that case. If you have an architecture that needs a libgcc[124] package, such as libgcc2-m68k-cross, installed to build gcc itself, it’s useful to install that from a previous build first (otherwise, convert it now, the same way). June 2011, it's gotten worse. {{{dpkg-cross -M -b -a m68k -X libc-bin -X libc-dev-bin *_m68k.deb}}} converts the two eglibc packages, even though multiarch, and dropping the above-mentioned dependencies, and the linux-libc-dev package. |
|
Line 74: | Line 145: |
sudo dpkg -i *-4.0-$ARCH-linux-gnu*.deb *-$ARCH-cross_4.0*.deb | sudo dpkg -i *-VERSION-$ARCH-linux-gnu*.deb *-$ARCH-cross_VERSION*.deb }}} If you run into this error, or a similar one… {{{ dh_strip -plibgcc2-m68k-cross --dbg-package=libgcc2-dbg-m68k-cross objcopy: Unable to recognise the format of the input file `debian/libgcc2-m68k-cross/usr/m68k-linux-gnu/lib/libgcc_s.so.2' dh_strip: objcopy --only-keep-debug debian/libgcc2-m68k-cross/usr/m68k-linux-gnu/lib/libgcc_s.so.2 debian/libgcc2-dbg-m68k-cross/usr/lib/debug//usr/m68k-linux-gnu/lib/libgcc_s.so.2 returned exit code 1 make[1]: *** [stamps/08-binary-stamp-libgcc] Error 2 make[1]: Leaving directory `/home/tg/X/gcc-4.4-4.4.5' make: *** [binary] Error 2 dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 }}} … then this will help: {{{ tg@zigo:~/X/gcc-4.4-4.4.5 $ sudo apt-get install binutils-multiarch [sudo] password for tg: Reading package lists... Done Building dependency tree Reading state information... Done Starting Starting 2 Done The following NEW packages will be installed: binutils-multiarch 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/2127 kB of archives. After this operation, 7164 kB of additional disk space will be used. Selecting previously deselected package binutils-multiarch. (Reading database ... 32493 files and directories currently installed.) Unpacking binutils-multiarch (from .../binutils-multiarch_2.21.0.20110216-2_amd64.deb) ... Adding 'diversion of /usr/bin/nm to /usr/bin/nm.single by binutils-multiarch' Adding 'diversion of /usr/bin/objdump to /usr/bin/objdump.single by binutils-multiarch' Adding 'diversion of /usr/bin/objcopy to /usr/bin/objcopy.single by binutils-multiarch' Adding 'diversion of /usr/bin/strings to /usr/bin/strings.single by binutils-multiarch' Adding 'diversion of /usr/bin/strip to /usr/bin/strip.single by binutils-multiarch' Adding 'diversion of /usr/bin/size to /usr/bin/size.single by binutils-multiarch' Adding 'diversion of /usr/bin/ar to /usr/bin/ar.single by binutils-multiarch' Adding 'diversion of /usr/bin/ranlib to /usr/bin/ranlib.single by binutils-multiarch' Adding 'diversion of /usr/bin/addr2line to /usr/bin/addr2line.single by binutils-multiarch' Adding 'diversion of /usr/bin/gprof to /usr/bin/gprof.single by binutils-multiarch' Adding 'diversion of /usr/bin/readelf to /usr/bin/readelf.single by binutils-multiarch' Setting up binutils-multiarch (2.21.0.20110216-2) ... |
Line 122: | Line 235: |
=== Get all the libraries you need === apt-cross is in Lenny but no longer in Squeeze. [[DebPkg:pdebuild-cross|pdebuild-cross]] in Squeeze contains an early version of {{{xapt}}} or you can use the [[DebPkg:xapt]] {{{xapt}}} package from experimental until Squeeze is released. xapt usage (squeeze): {{{ xapt -a armel $LIBRARY }}} xapt usage (wheezy and unstable): {{{ xapt -a armel -m $LIBRARY }}} The -m is necessary if pulling in packages from testing or unstable because of the MultiArch changes. If you are still using Lenny, apt-cross is necessary. apt-cross reminders: {{{ apt-get install apt-cross dpkg-cross }}} Update {{{ apt-cross -a $ARCH -u }}} Fetch your cross favorite library {{{ apt-cross -a $ARCH -i $LIBRARY }}} ---- CategoryEmdebian |
Contents
Installing a Cross Compiler
This document will help you obtain Debian packages of a cross-compilation toolchain. It is based on a HOWTO by Josh Triplett, with his kind permission.
Note that most cross-toolchain combinations you might actually want within Debian are built by the Embedded Debian Project, so you may well just be able to apt-get what you need on their Toolchains page: http://www.emdebian.org/tools/crosstools.html .
We'll say that again: MOST PEOPLE SHOULDN'T BE BUILDING THEIR OWN CROSS-TOOLCHAIN - THEY SHOULD JUST INSTALL A PRE-BUILT ONE LIKE ANY OTHER PACKAGE.
To install a prebuilt cross compiler
What if I have an Ubuntu system or want to do multiarch-style crossbuilding?
If you have an Ubuntu (maverick/10.10, or later) system and want an armel or armhf toolchain then they are already part of your distro - just apt-get install arm-linux-gnueabi-gcc (for armel) or arm-linux-gnueabihf-gcc (for armhf). Backports for Lucid are available too.
For other architecutures, or if you have a Debian system you need to get toolchains from Emdebian.
Note that these toolchains search in the 'dpkg-cross' cross-lib/headers paths, not the new multiarch paths so are not very useful for multiarch cross-building. Currently (March 2012) you need to use the Ubuntu-supplied toolchains for that.
Installing cross-toolchains from Emdebian
Add the Emdebian keyring from Debian before you start.
apt-get install emdebian-archive-keyring
Add two apt sources, one for your normal mirror and one for Emdebian:
deb http://ftp.XX.debian.org/debian squeeze main deb http://www.emdebian.org/debian squeeze main
Create a new file in /etc/apt/sources.list.d/ with the above lines.
Use whatever is your normal Debian mirror for the first line which brings in some dependencies which are no longer in Wheezy or unstable.
Now just install your toolchain, e.g. for armel:
apt-get update apt-get install g++-4.4-arm-linux-gnueabi
Emdebian also maintain scripts which effectively do what this page describes. Take a look at the 'buildcross' package from Debian experimental, which will build a whole range of toolchains.
http://packages.qa.debian.org/b/buildcross.html
Most users do not need to build the cross-compiler
Commands you need to run as root assume you have already set up sudo on your system.
If you do need to build the compiler
We will be building a cross-compiler from the gcc-4.1 package. Specific version numbers for packages are listed as VERSION; substitute the version number of the latest package in unstable (or testing).
Notes for Debian unstable
We build gcc-4.4 whose cross package additionally build-depends on gcc-4.4-source which you henceforth must install.
The package linux-kernel-headers is now called linux-libc-dev instead.
The three packages libc6-dev, libc6, linux-libc-dev have additional dependencies, so you need to get the (native for the target arch) gcc-4.4-base, libc-bin, libc-dev-bin and libgcc2 (libgcc1, libgcc4, whatever your target needs) packages additionally. Now, dpkg-cross refuses to convert those without “any useful files”, so you need to pass the -A option in addition to -b and -a $ARCH.
A bit uglily, you get libgcc2-m68k-cross depending on gcc-4.4-base-m68k-cross from dpkg-cross and later, after compiling, libgcc2-m68k-cross depending on gcc-4.4-m68k-linux-gnu-base. Just remove the dpkg-cross-generated one once you got the new ones.
Build a cross-compilation toolchain
Create a working directory
mkdir -p ~/src/cross-toolchain cd ~/src/cross-toolchain
Some useful variables
These will be used in the commands in this document. Replace "arm" with the architecture for which you are building a cross-compiler.
unset ARCH # make sure it’s not exported ARCH=arm # set to the value we want to use
Get the source for binutils and GCC
apt-get source binutils gcc-4.1
Install Build-Depends
sudo apt-get build-dep binutils gcc-4.1
Note that gcc-4.1 may have build-dependencies that apt-get can't figure out; this is not a problem, just make sure you install all the ones that apt-get understands. Unfortunately, apt-get build-dep may give an error if such a situation arises; in this case, take the list of packages apt-get provided before giving an error, and install them using "sudo apt-get install pkg1 pkg2 pkg3 ...".
Install fakeroot
fakeroot allows you to build packages without being root.
sudo apt-get install fakeroot
Install dpkg-cross
dpkg-cross adds cross-compilation support to some of the basic Debian package tools. dpkg-cross can also convert packages designed for the target architecture into packages usable for cross-compilation to that architecture.
sudo apt-get install dpkg-cross
Build and install binutils
cd binutils-VERSION export TARGET=$(dpkg-architecture -a$ARCH -qDEB_HOST_GNU_TYPE 2>/dev/null) # this is for binutils <= 2.20 #fakeroot debian/rules binary-cross >../binutils.build 2>&1 || echo 'Build error' # this is for binutils >= 2.21 dpkg-buildpackage -b -uc -us -rfakeroot >../binutils.build 2>&1 || echo 'Build error' unset TARGET cd .. sudo dpkg -i binutils-${TARGET}_VERSION_HOSTARCH.deb
Note: the instructions are not totally correct. For example, with ARCH=amd64 you get TARGET=x86_64-linux-gnu and binutils-x86-64-linux-gnu (replace _ with - simply). For i386, you get TARGET=i486-linux-gnu but you’ll probably want i386-linux-gnu instead.
Convert library packages
You will need cross-compilation packages for various libraries; dpkg-cross can convert native packages for the target architecture into packages usable for cross-compilation. Note that the mirror ftp.us.debian.org only has amd64 and i386 packages, so to build a cross-compilation toolchain for another architecture (e.g. arm), you will have to use a mirror other than ftp.us.debian.org.
wget http://ftp.XX.debian.org/debian/pool/main/e/eglibc/libc6-dev_VERSION_$ARCH.deb wget http://ftp.XX.debian.org/debian/pool/main/e/eglibc/libc6_VERSION_$ARCH.deb wget http://ftp.XX.debian.org/debian/pool/main/l/linux-kernel-headers/linux-kernel-headers_VERSION_$ARCH.deb dpkg-cross -a $ARCH -b l*.deb sudo dpkg -i l*$ARCH-cross*.deb
It may be needed to download and convert libc-bin and libc-dev-bin packages too, otherwise the packages’ dependencies can maybe not be resolved. Use dpkg-cross -a m68k -A -b l*.deb in that case.
If you have an architecture that needs a libgcc[124] package, such as libgcc2-m68k-cross, installed to build gcc itself, it’s useful to install that from a previous build first (otherwise, convert it now, the same way).
June 2011, it's gotten worse. dpkg-cross -M -b -a m68k -X libc-bin -X libc-dev-bin *_m68k.deb converts the two eglibc packages, even though multiarch, and dropping the above-mentioned dependencies, and the linux-libc-dev package.
Build and install GCC
Now that you have all the necessary prerequisites, you can build a cross-compiling GCC.
cd gcc-VERSION export GCC_TARGET=$ARCH debian/rules control dpkg-buildpackage -us -uc -rfakeroot -b > ../gcc.build 2>&1 || echo 'Build error' cd .. sudo dpkg -i *-VERSION-$ARCH-linux-gnu*.deb *-$ARCH-cross_VERSION*.deb
If you run into this error, or a similar one…
dh_strip -plibgcc2-m68k-cross --dbg-package=libgcc2-dbg-m68k-cross objcopy: Unable to recognise the format of the input file `debian/libgcc2-m68k-cross/usr/m68k-linux-gnu/lib/libgcc_s.so.2' dh_strip: objcopy --only-keep-debug debian/libgcc2-m68k-cross/usr/m68k-linux-gnu/lib/libgcc_s.so.2 debian/libgcc2-dbg-m68k-cross/usr/lib/debug//usr/m68k-linux-gnu/lib/libgcc_s.so.2 returned exit code 1 make[1]: *** [stamps/08-binary-stamp-libgcc] Error 2 make[1]: Leaving directory `/home/tg/X/gcc-4.4-4.4.5' make: *** [binary] Error 2 dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2
… then this will help:
tg@zigo:~/X/gcc-4.4-4.4.5 $ sudo apt-get install binutils-multiarch [sudo] password for tg: Reading package lists... Done Building dependency tree Reading state information... Done Starting Starting 2 Done The following NEW packages will be installed: binutils-multiarch 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/2127 kB of archives. After this operation, 7164 kB of additional disk space will be used. Selecting previously deselected package binutils-multiarch. (Reading database ... 32493 files and directories currently installed.) Unpacking binutils-multiarch (from .../binutils-multiarch_2.21.0.20110216-2_amd64.deb) ... Adding 'diversion of /usr/bin/nm to /usr/bin/nm.single by binutils-multiarch' Adding 'diversion of /usr/bin/objdump to /usr/bin/objdump.single by binutils-multiarch' Adding 'diversion of /usr/bin/objcopy to /usr/bin/objcopy.single by binutils-multiarch' Adding 'diversion of /usr/bin/strings to /usr/bin/strings.single by binutils-multiarch' Adding 'diversion of /usr/bin/strip to /usr/bin/strip.single by binutils-multiarch' Adding 'diversion of /usr/bin/size to /usr/bin/size.single by binutils-multiarch' Adding 'diversion of /usr/bin/ar to /usr/bin/ar.single by binutils-multiarch' Adding 'diversion of /usr/bin/ranlib to /usr/bin/ranlib.single by binutils-multiarch' Adding 'diversion of /usr/bin/addr2line to /usr/bin/addr2line.single by binutils-multiarch' Adding 'diversion of /usr/bin/gprof to /usr/bin/gprof.single by binutils-multiarch' Adding 'diversion of /usr/bin/readelf to /usr/bin/readelf.single by binutils-multiarch' Setting up binutils-multiarch (2.21.0.20110216-2) ...
Test the cross-compile environment
Test compilation
Create a file "hello.c", containing the following code:
#include <stdio.h> int main() { printf("Hello cross-compiling world!\n"); return 0; }
Compile it statically with the new cross-compiler.
$ARCH-linux-gnu-gcc -static hello.c -o hello
Check the binary's type with "file".
file hello
You should see something like:
hello: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), for GNU/Linux 2.2.0, statically linked, not stripped
for the PowerPC architecture.
Install qemu
qemu is an emulator for various architectures. It supports both whole-system emulation as well as single-program emulation with system-call conversion.
sudo apt-get install qemu
Run the test program with qemu
To run the test program with qemu, just prefix it with "qemu-$ARCH" (assuming of course that your architecture is supported by qemu).
qemu-$ARCH ./hello
You should see:
Hello cross-compiling world!
Get all the libraries you need
apt-cross is in Lenny but no longer in Squeeze. pdebuild-cross in Squeeze contains an early version of xapt or you can use the xapt xapt package from experimental until Squeeze is released.
xapt usage (squeeze):
xapt -a armel $LIBRARY
xapt usage (wheezy and unstable):
xapt -a armel -m $LIBRARY
The -m is necessary if pulling in packages from testing or unstable because of the MultiArch changes.
If you are still using Lenny, apt-cross is necessary.
apt-cross reminders:
apt-get install apt-cross dpkg-cross
Update
apt-cross -a $ARCH -u
Fetch your cross favorite library
apt-cross -a $ARCH -i $LIBRARY