Until now, I used xapt and dpkg-cross to install cross libraries for armel, but since I’ve upgraded to Ubuntu 12.04, it appears to be broken. I’ve contacted Linaro about this issue, and the “cross-building” expert at Linaro (wookey) recommended me to use multiarch instead, as xapt/dpkg-cross will be eventually deprecated.
He provided me an example showing how-to use multiarch to build Chromium. I’ve been looking for a “How-to multiarch”, but haven’t been able to find something really clear and simple, so I thought I would post it here.
In the example, they used a chroot for cross-building, which is probably a good idea to avoid messing up with the system. It’s also possible multiarch is not 100% reliable, and I’ve read stories where people messed up their system when using multiarch with i386 (32-bit) and amd64 (64-bit).
Preparing a chroot for cross-building
I’ll use a 32-bit Ubuntu precise chroot, but you can use an older distribution (e.g. oneric) and 64-bit if needed:
sudo debootstrap --arch=i386 --variant=buildd precise /srv/precise-i386 sudo chroot /srv/precise-i386/ mount -t proc proc /proc
Setup the /etc/apt/sources.list:
deb [arch=i386] http://archive.ubuntu.com/ubuntu precise main universe deb [arch=armel] http://ports.ubuntu.com/ubuntu-ports precise main universe deb-src http://archive.ubuntu.com/ubuntu precise main universe
The file above is setup for armel, but you could also set it up for armhf or both [arch=armel,armhf].
Some packages might not be in precise, so it’s better to create /etc/apt/sources.list.d/linaro-maintainers.list to add Linaro ppas:
deb http://ppa.launchpad.net/linaro-maintainers/overlay/ubuntu precise main deb-src http://ppa.launchpad.net/linaro-maintainers/overlay/ubuntu precise main deb http://ppa.launchpad.net/linaro-maintainers/staging-overlay/ubuntu precise main deb-src http://ppa.launchpad.net/linaro-maintainers/staging-overlay/ubuntu precise main
Import the public key of the Overlay, to avoid the GPG error while accessing the PPA:
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7BE1F97B
dpkg --add-architecture is not available in the dpkg available in Ubuntu 12.04, so you’ll need to enable multiarch for dpkg manually in /etc/dpkg/dpkg.cfg.d/multiarch:
Create /etc/apt/apt.conf.d/10local to disable installing recommended and suggested packages:
APT::Install-Recommends "0"; APT::Install-Suggests "0";
Create /usr/sbin/policy-rc.d file to prevent daemons to start in the chroot:
echo "exit 101" > /usr/sbin/policy-rc.d chmod a+x /usr/sbin/policy-rc.d
Install linaro arm cross-toolchain and essentials:
apt-get update apt-get install g++-arm-linux-gnueabi build-essential
Installing armel packages
Now that your chroot is ready, it’s pretty simple to install armel packages as you just need to append the architecture after the package name, for example:
apt-get install libjpeg-dev:armel libpng12-dev:armel
The libraries are installed in /usr/lib/arm-linux-gnueabi/ and the header files are shared among all architectures in /usr/include, except for armel specific bits which are in /usr/include/arm-linux-gnueabi. If you use armhf instead the libraries will be located in /usr/lib/arm-linux-gnueabihf/.
If you are building your own software, you can just install the dependencies you need and set the CFLAGS, CXXFLAGS and LDFLAGS to the paths above.
Building known packages
Another great feature of multiarch is that you can build known packages with dpkg-buildpackage. When everything works perfectly, you’ll just need to run something like:
apt-get build-dep -aarmel chromium-browser apt-get source chromium-browser cd chromium* dpkg-buildpackage -b -B -aarmel 2>&1|tee ../chromium-browser.log
In the example above, once you’ve configured apt for multiarch, you just need to type 4 commands to retrieve the source and build the chromium-browser for ARM.
I’ve already used this method when building the Linux ARM kernel on Ubuntu 12.04.