07 March 2012

95. Cross-compiling 32 bit binaries on 64 bit system

There are many ways of setting up toolchain for cross compiling. This is the method I've had more success with, and feel more comfortable with. It introduces more overhead than some other approaches.

My motivation for wanting to cross compile is because I have a slow 32 bit headless server, and a couple of fast multiu-core 64 bit systems. Compiling kernel 3.2.9 on my 32 bit server takes up to 3 hours, while it takes less than half an hour on a more modern box.

This method allows you to compile without it affecting the host system. Everything will happen in a jail made up chroot. You will only be able to use architectures for which your hardware is compatible i.e. i386 and amd64. Cross-compiling for other architectures is a future project.

-- Start Here --

create a directory where you can store you architectures e.g.
mkdir -p /home/me/tmp/architectures/i386
cd /home/me/tmp/architectures

sudo apt-get install debootstrap

You will use scripts to point your jailed systems apt to the right place. Here's how to see what's available:

ls /usr/share/debootstrap/scripts/
breezy  edgy  etch-m68k  gutsy  hoary         intrepid  karmic  lucid     natty      oneiric  precise  sarge.buildd      sid      stable   unstable  warty.buildd  woody
dapper  etch  feisty     hardy  hoary.buildd  jaunty    lenny   maverick  oldstable  potato   sarge    sarge.fakechroot  squeeze  testing  warty     wheezy        woody.buildd

Time to get busy:
sudo debootstrap --arch i386 testing /home/me/tmp/architectures/i386/ http://ftp.au.debian.org/debian/

I: Retrieving Release
I: Retrieving Release.gpg
I: Checking Release signature
I: Valid Release signature (key id 9FED2BCBDCD29CDF762678CBAED4B06F473041FA)
I: Retrieving Packages
I: Configuring perl...
I: Configuring tasksel...
I: Base system installed successfully

You can look at e.g. ftp://ftp.au.debian.org/debian/dists/wheezy/ to see what other architectures are available. In this particular case, it's amd64, armel, i386, ia64, powerpc etc. You won't be able to chroot into an architecture your hardware doesn't support, so you're effectively limited to amd64 and i386. Cross-compiling for other architectures will be a future project.

Go to Jail

make sure you're in /home/me/tmp/architectures
sudo chroot i386

You're in. To convince yourself it's real -- and that you can't escape from the /home/me/tmp/architectures/i386/ folder -- you can navigate around your system.

You still need to install all your build tools
apt-get install build-essential

Do you want to continue [Y/n]?
Get:1 http://ftp.au.debian.org/debian/ testing/main libgmp10 i386 2:5.0.4+dfsg-1 [264 kB]
Get:2 http://ftp.au.debian.org/debian/ testing/main libgomp1 i386 4.6.2-12 [27.3 kB]

Note what architecture we're installing packages for...it's really that simple. Also, no need for sudo since you're root. With only build-essential installed the entire system is ca 450 Mb.

Install kernel-package as well, so you can build 32 bit kernels. This bring it up to ca 550 Mb.

You'll want checkinstall to make .deb packages.

Finally, set all locale parameters to C by running this in the terminal

export LC_ALL=C
export LANG=C

Save yourself that headache in the future by
apt-get install locale
Exit your chroot jail, and start it again:
sudo chroot i386

dpkg-reconfigure locales
and pick the same as your host system, in my case en_AU.UTF-8

Build something

We'll build a 32 bit kernel, but you could really build anything you want.

From outside the chroot jail (i.e. another terminal)
sudo cp ~/tmp/linux3.2.9.tar.bz2 ~/tmp/architectures/i386/usr/src/
Inside the chroot jail
root@tantalum:/# ls /usr/src/

cd /usr/src/
tar -xvf linux-3.2.9.tar.bz2
cd linux-3.2.9/

either copy a .config from an existing 32 bit kernel version (see http://verahill.blogspot.com.au/2012/03/debian-testing-kernel-329.html for more information), or
make defconfig

fakeroot make-kpkg -jN --initrd --revision=3.2.9 kernel_image kernel_headers
Choose the default for most of the questions. N is the number of cores+1 on the host system, e.g. 5 for a four-core CPU.

With -j5 I made a full build in 1m 21 s. That's a fairly minimal kernel build though.
Using the .config generated from an existing 32 bit debian system and following this I got a full build in about 25 minutes.

Following method 3 on this: http://verahill.blogspot.com.au/2012/01/debian-testingwheezy-64-bit-installing.html
cd /usr/src
wget http://prdownloads.sourceforge.net/wine/wine-1.3.35.tar.bz2
tar -xvf wine-1.3.35.tar.bz2
cd wine-1.3.35

apt-get install bison flex gcc libc6-dev libfontconfig-dev libfreetype6-dev libglu-dev libgsm1-dev libice-dev libjpeg-dev libldap-dev libmpg123-dev libncurses5-dev libopenal-dev libpng-dev libsm-dev libssl-dev libusb-dev libx11-dev libxcomposite-dev libxcursor-dev libxext-dev libxi-dev libxinerama-dev libxml2-dev libxrandr-dev libxrender-dev libxslt-dev libxt-dev libxxf86vm-dev make libcapi20-dev liblcms-dev libsane-dev libhal-dev libdbus-1-dev valgrind prelink libcups2-dev libv4l-dev libncurses5-dev libasound2-dev libz-dev

make -j5
checkinstall --install=no

In the future
Next time you want to cross compile, just
cd /home/me/tmp/architecture
sudo chroot i386
and you're ready to go.

No comments:

Post a Comment