⇤ ← Revision 1 as of 2012-03-30 10:28:46
Size: 4558
Comment:
|
Size: 4632
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 19: | Line 19: |
{{{ | |
Line 24: | Line 25: |
}}} | |
Line 27: | Line 29: |
Classic cross-compiling assumes never running any host architecture binaries, and this remains good policy, but we often have QEMU or similar emulation available these days so it makes sense to control this separately where we can. In practice this means running tests, which should be controlled with DEB_BUILD_OPTS=nocheck rather than 'are we cross-compiling or not'. Cross-build tools will set this by default, but it can be enabled when approapriate. | Classic cross-compiling assumes never running any host architecture binaries, and this remains good policy, but we often have QEMU or similar emulation available these days so it makes sense to control this separately where we can. In practice this means running tests, which should be controlled with DEB_BUILD_OPTS=nocheck rather than 'are we cross-compiling or not'. Cross-build tools will set 'nocheck' by default, but it can be enabled when approapriate. |
Line 87: | Line 89: |
Simply hardcoding 'gcc' will not allow cross-building, and is arguably wrong for other reasons. | Simply hardcoding 'gcc' will not allow cross-building, and is arguably wrong for other reasons (like using clang instead) |
Line 110: | Line 112: |
set DEB_BUILD_OPTIONS=nocheck |
Guidelines for cross-build friendly packages
This page describes good (and bad) practice in packaging (and upstream code) with respect to cross-building Debian-based packages. Little of this is yet mnandated by policy, but some is and more will be in the future.
There are often lots of ways of 'fixing' a cross-build problem, but unless you are expert it he area it will not be clear what the implications of using one method over another are. This page endeavours to document standard guidelines so that packagers can use it as a reference, and Debian and derivatives can develop policy in this area.
Terminology
- HOST is the machine we are building for
- BUILD is the machine we are building on
This somewhat confusing terminology is GNU's fault.
Principles
dpkg-architecture is responsible for translating between triplets, Debian architecture names and multiarch paths. This provides a consistent interface and namespace.
cross-building is defined as BUILD != HOST. more explicitly in debian.rules:
ifeq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) native build else crossbuild endif
We cannot run tests to determine aspects of the host machine which will be different on the build machine.
Classic cross-compiling assumes never running any host architecture binaries, and this remains good policy, but we often have QEMU or similar emulation available these days so it makes sense to control this separately where we can. In practice this means running tests, which should be controlled with DEB_BUILD_OPTS=nocheck rather than 'are we cross-compiling or not'. Cross-build tools will set 'nocheck' by default, but it can be enabled when approapriate.
When cross-building the build must select the correct tools who's output varies with architecture. This is usually done with an explicit GNU triplet prefix (arm-linux-gnueabi- ia64-linux-gnu-). This applies to the following tools: gcc, g++, binutils (ld, as, strip, ar, readelf etc), pkg-config
Build environment
Various things need to be set in the environment for cross-builds to work correctly. These are the things that are set by various tools:
dpkg-buildpackage
all the dpkg-architecture variables:
DEB_BUILD_ARCH DEB_BUILD_ARCH_OS DEB_BUILD_ARCH_CPU DEB_BUILD_ARCH_BITS DEB_BUILD_ARCH_ENDIAN DEB_BUILD_GNU_CPU DEB_BUILD_GNU_SYSTEM DEB_BUILD_GNU_TYPE DEB_BUILD_MULTIARCH DEB_HOST_ARCH DEB_HOST_ARCH_OS DEB_HOST_ARCH_CPU DEB_HOST_ARCH_BITS DEB_HOST_ARCH_ENDIAN DEB_HOST_GNU_CPU DEB_HOST_GNU_SYSTEM DEB_HOST_GNU_TYPE DEB_HOST_MULTIARCH
(it also sets some FAKEROOT stuff that we don't care about here, and sanitises a load of stuff out of your normal environment)
sbuild
sbuild duses dpkg-buildpackage so sets the same things as that, and:
CONFIG_SITE/etc/dpkg-cross/cross-config.$DEB_HOST_ARCH (for autoconf cache settings provided by dpkg-cross) DEB_BUILD_OPTS+=nocheck
anything else configured to be set in build environment
xdeb
xdeb duses dpkg-buildpackage so sets the same things as that, and:
CONFIG_SITE=/etc/dpkg-cross/cross-config.$DEB_HOST_ARCH (for autoconf cache settings provided by dpkg-cross) DEB_BUILD_OPTS+=nocheck GTEST_INCLUDEDIR=/usr/$DEB_HOST_GNU_TYPE/include GTEST_LIBDIR=/usr/$DEB_HOST_GNU_TYPE/lib
make
Make sets some things itself too. Some of them not very helpfully, like the implicit $(CC)=cc
Setting correct compiler
Simply hardcoding 'gcc' will not allow cross-building, and is arguably wrong for other reasons (like using clang instead)
Normally you want to set gcc for native builds and $(DEB_HOST_GNU_TYPE)-gcc for cross-builds. Sadly we can't just set $(DEB_HOST_GNU_TYPE)-gcc always because that doesn't work natively
So normally people do this:
ifeq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) CC=gcc else CC=$(DEB_HOST_GNU_TYPE)-gcc endif
But it should also be possible to override the compiler for the build from the environment so that for example LLVM test builds or strangly-named external toolchains can be used.
Unfortunately make always sets $(CC) (to 'cc') so you can't just test if it is already set, and set it if not. CC ?= $(CC)
This state can be detected with $(origin CC) see http://theory.uwinnipeg.ca/localfiles/infofiles/make/make_80.html I wonder if we should be doing something clever with ifeq "$(origin CC)" "default" ?...
Running/skipping tests
Normally you don't want to run tests when cross-building.
set DEB_BUILD_OPTIONS=nocheck