When developing apps for the phone, one of the biggest hurdles is trying to compile armhf binaries on an amd64 system. There are several ways of doing this, all with their pros and cons.
At one end of the spectrum, a full armhf environment can be created and run in an emulator, using something like qemu. This has the advantage of simplifying the package management and build tools, but at the expense of poor performance.
At the other extreme, it is possible to create a whole cross-compiling toolchain within the existing amd64 install. Whilst this will perform well, there is a high maintenance burden with complex package management and dependency issues.
The Ubuntu SDK team have adopted a middle ground, using a cross-compiling toolchain in a hybrid chroot, which is overlaid on top of the existing install. The process is explained clearly in an excellent blog post by Benjamin Zeller. Beyond the need to create “kits”, the process is transparent to the SDK user. I have used this approach for most of my phone development (albeit, usually from the command line). As there is no emulation, the performance is excellent. However, managing package dependencies in the hybrid chroot can cause problems if the armhf packages conflict with the necessary amd64 package infrastructure.
Over the past few days I have been trying to build Hedgewars for the Ubuntu Phone. Unfortunately, the SDK click-chroot process has not proved suitable for this task. Some of the code is written in Pascal. Ubuntu does not provide a cross-compiler for Pascal code. Furthermore, the codebase and assets are too large to compile on the phone itself.
My solution to the problem has been to try qemu emulation, but using the “user” emulation approach rather than full “system” emulation. This involves creating a chroot containing all the userspace armhf binaries which are translated on-the-fly by qemu. The kernel side, however, remains amd64 to try to maintain some performance. It works better than expected, with only a few failed system calls.
HowTo
Install debootstrap and qemu-user-static on the Ubuntu desktop. Create a large sparse file for the armhf image:
$ truncate -s 100G vivid_base.img
As this is a sparse file, it will not take up much space on the disk but will expand as needed up to 100GB. To be useful, it must be formatted:
$ mkfs.ext4 -F vivid_base.img
Using this approach gives a chrooted filesystem which can be copied, cloned and shared. Create a mount point and mount the filesystem:
$ mkdir -p ~/vivid_armhf/mount $ sudo mount -o loop vivid_base.img ~/vivid_armhf/mount
Using special flags to debootstrap, we can begin the process of building an armhf Ubuntu system in the chroot:
$ sudo debootstrap --arch armhf --foreign vivid ~/vivid_armhf/mount
The --foreign flag tells debootstrap to stop before trying to run any armhf binaries. We cannot do that until qemu is installed:
$ sudo cp /usr/bin/qemu-arm-static ~/vivid_armhf/mount/usr/bin/
For the chroot to function properly, it is necessary to mount proc and sys:
$ sudo mount -t proc /proc ~/vivid_armhf/mount/proc $ sudo mount -t sysfs /sys ~/vivid_armhf/mount/sys $ sudo chroot ~/vivid_armhf/mount
The debootstrap install can now be completed from within the chroot:
(chroot)# debootstrap/debootstrap --arch=armhf --second-stage (chroot)# exit
The vivid install has a known bug which prevents this step from being completed cleanly, but it is safe to ignore the warnings as the install is easily fixed. The next step is to create a sensible sources.list using ports.ubuntu.com/ubuntu-ports as the mirror, and copy to ~/vivid_armhf/mount/etc/apt/sources.list. An example would be:
###### Ubuntu Main Repos deb http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe multiverse deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe multiverse ###### Ubuntu Update Repos deb http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse deb http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe multiverse deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe multiverse
Chroot back in and fix the install:
$ sudo chroot ~/vivid_armhf/mount (chroot)# apt-get install -f
The armhf environment is now ready to use. Of course, it will be necessary to set up users, hostnames, development packages and such. When things are arranged to your linking, you can copy vivid_base.img to create a snapshot.