Debian now has good support for crossbuilding packages using multiarch. This page describes how to do it.
You can build on your main system but it is recommended to use a chroot, because:
- The build environment is clean, especially if you use a tarball/lvm snapshot
- You don't end up with lots of build-deps and foreign architecture packages in your main system
- There is no risk of accidentally messing up your system if something important gets swapped to the wrong architecture
There are less conflicts of packages lacking Multi-Arch: same.
This page documents the both manual procedures and building using sbuild and pbuilder.
- Building with sbuild
- Building with pbuilder
- Building with dpkg-buildpackage
- Building manually outside of packages
- Install tools
- Set up a chroot
- Changing the sources in the chroot
- Using the chroot
- Configuring cross-toolchains in schroot
- Manual chroot setup
It needs to be noted that tools listed here use a naming of architecture roles inherited from the GNU autotools, which some people used to nomenclature from other tools might perhaps find confusing. The difference is in perspective, either system-centric (this nomenclature) or object-centric (the other variant):
build means the architecture of the chroot/dpkg/compiler's executable, i.e. the architecture of the build system (called host by cmake/kernel/etc)
host means the architecture of produced executable objects, i.e. the architecture of the host system where these guest objects will run on (called target or sometimes build elsewhere)
target is what the produced executable objects will generate when producing executable objects, i.e. the architecture of the systems the built programs target their results to run on (relevant only for compilers and similar)
Building with sbuild
- an schroot chroot (to do builds in). A standard chroot for native building just works for cross building since stretch.
Either download the package source, enter it and run sbuild, or give an explicit package_version
apt-get source acl cd acl-2.2.52/ sbuild --host=armhf -d buster
sbuild --host=armhf -d buster acl_2.2.52
Building with pbuilder
You need to be pbuilder from stretch (or newer) to support cross-building; the feature was introduced in version 0.227.
You must use the apt "satisfydepends" resolver with pbuilder. This can be done by adding the following line to your ~/.pbuilderrc:
If you're missing the above you might see the following error: E: Cross building is possible only with the APT dependency resolver
If you don't already have a pbuilder base chroot (for native building), create one now by simply running:
pbuilder create cowbuilder --create
Now to cross-build a package simply use the --host-arch option, eg. to build "my-package" for armhf use:
pbuilder build --host-arch armhf my-package.dsc pdebuild -- --host-arch armhf
Building with dpkg-buildpackage
If you are building packages with no library dependencies (such as kernels or bootloaders), and using a standalone cross-toolchain, then you don't need to enable the foreign architecture. Nearly all packages will need the foreign architecture enabling.
Enable the foreign architecture
sudo dpkg --add-architecture armhf sudo apt-get update sudo apt-get install build-essential crossbuild-essential-armhf
sudo apt-get build-dep -aarmhf <package> cd <package>-<version> CONFIG_SITE=/etc/dpkg-cross/cross-config.<host_arch> DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -aarmhf -Pcross,nocheck
more to come here
Building manually outside of packages
You can look at the code for how debhelper does cross-compiling.
The dpkg_architecture_value() function returns values that can be found in the output of the dpkg-architecture command.
You need sbuild installed. This will also bring in schroot and build-essential.
sudo apt-get install sbuild
Set up a chroot
This can be done lots of ways (debootstrap, mksbuild, multistrap, pbuilder create). sbuild-createchroot is good because it does the schroot config for you too, and can make tarballs trivially, for clean builds.
sudo sbuild-createchroot --make-sbuild-tarball=/srv/chroots/jessie-sbuild.tgz jessie /srv/chroots/jessie http://httpredir.debian.org/debian/
will create a base chroot, pack it up into /srv/chroots/jessie-sbuild.tgz, and add the config for it to schroot (in /etc/schroot/chroot.d)
If you have not used sbuild before on this machine it needs setting up on your machine:
sudo sbuild-adduser <your-username>
to allow your username to run builds, and
to enable installation of build-dependencies in the chroot. (This command can take a really long time on servers with insufficient entropy - running it locally and copying the keyfiles over to the build machine can be a good idea in that case)
Check the new chroot exists with
Which on an amd64 machine will display:
(sbuild-createchroot adds the arch name by default when naming chroots - this is quite useful if you have more than one)
That is one chroot, accessible in two different ways:
- the clean chroot chroot:jessie-amd64-sbuild, where none of your changes are saved so it's the same every time.
- the actual chroot tarball source:jessie-amd64-sbuild, where changes are packed up again and saved for next time.
Normally you use the clean chroot, and that's the default if you just say "jessie-amd64-sbuild" (the sbuild-shell command is an exception to this, as it implicitly uses the source: version)
Changing the sources in the chroot
By default the apt sources for the build are the one given on the sbuild-createchroot command line. If that's not what you want you need to change them:
First you need an editor in the chroot - there is none by default (choose vim.tiny, zile, nano) as you see fit). A few tools in the chroot are useful, but for clean builds you don't want too much stuff in there.
sudo sbuild-apt jessie-amd64-sbuild apt-get install zile
Now enter the chroot to edit /etc/apt/sources.list or /etc/apt/sources.list.d/customsource.list
sudo sbuild-shell jessie-amd64-sbuild
Making your home dir available in the chroot
It's very handy to have your home directory automatically mounted in the chroot. The default sbuild-createchroot command does not set this up. If you only ever do sbuild-builds then it doesn't matter. But if you enter the chroot to run manual builds or tests having your home dir available is really useful.
Do this by changing
Using the chroot
Basic usage to enter the chroot:
schroot -c jessie-amd64-sbuild
Normal users and networking are available inside (and your home dir if you enabled that) so (if you install sudo) you can use sudo, download stuff, use files. If you are less interested in clean builds than conveninence then you can install lots of stuff permanently in the chroot.
Read the sbuild man pages for lots of clever stuff you can do. sbuild supports sessions, so once started you can leave and re-enter a chroot session. They can even be recovered after rebooting. The same commands can be run in multiple chroots. They can be updated from outside. command-hooks can be used to run things before builds, after builds, on entry etc.
Seeing how many schroot sessions you have (old ones can collect, and need tidying up sometimes):
Configuring cross-toolchains in schroot
Manual chroot setup
If you did not use sbuild-createchroot
Qt cross-architecture development in Debian by Enrico Zini