dpkg-buildpackage environment export vs. debhelper
cjwatson at ubuntu.com
Tue Nov 1 12:25:30 UTC 2011
We have a nasty little problem in precise, and unfortunately it's mainly
of our own making. I've been discussing this with a few people at UDS
(mainly Steve Langasek, Adam Conrad, and Matthias Klose), but I want to
have something on the record, in part so I don't forget the details.
Historically, Ubuntu's dpkg-buildpackage has set some compiler and
linker flags in the environment. This dates from Ubuntu 8.04 LTS and
started life in https://wiki.ubuntu.com/DistCompilerFlags. Debian
exported these flags to the environment for a while too. However,
Debian has now stopped doing this in favour of packages using
this is a better-designed system and we want to switch to it (not to
mention the lower friction associated with staying close to Debian's
build rules), but it's opt-in; so to avoid regressing the default build
flags for lots of packages in an LTS cycle we decided to keep the
dpkg-buildpackage export behaviour until after 12.04 LTS.
I tried to start CD builds for precise yesterday, and noticed as a
result that libvisual-plugins was failing to build on amd64 due to an
implicit pointer conversion. Oddly, though, this was supposed to have
been fixed already by adding -D_GNU_SOURCE to CFLAGS, so I investigated
further. In version 0.4.0.dfsg.1-4, Steve had converted this package to
dh(1), compat level 9, and dpkg-buildflags, so the CFLAGS change was now
being done using 'export DEB_CPPFLAGS_MAINT_APPEND := -D_GNU_SOURCE' in
debian/rules, and using dh_auto_*'s behaviour of automatically picking
up dpkg-buildflags output at compat level 9 and above. Unfortunately,
debhelper only exports flags that don't already exist in the
environment. This means that if something is set between
dpkg-buildpackage and debhelper (e.g. DEB_*_MAINT_* in debian/rules)
that affects the output of dpkg-buildflags, then that will have no
effect in Ubuntu right now.
This is subtle but obviously bad. libvisual-plugins is using pretty
much the most modern available packaging style, and we can expect the
use of that style to increase as time goes on. To make matters worse,
the symptom is not always a build failure, but is sometimes a misbuild
instead; for example, we believe that pam is currently missing large
file support in precise due to this.
So, what can be done? Dropping the dpkg-buildpackage workaround would
be the simplest option, syncing us up with Debian, but I think we've
already established that it's going to be too much work to ensure that
everything we care about is converted to dpkg-buildflags for 12.04 LTS.
We talked about applying a corresponding debhelper workaround to always
override environment variables with dpkg-buildflags output at compat
level 9 (see e.g.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=544844#137), but I'm
concerned about the effect of that on existing debian/rules files that
export CFLAGS et al directly, and I think such a workaround would be
harder to undo later since it's possible or even likely that Ubuntu
packages might come to depend on it; also I'd prefer to keep all the
workarounds contained in dpkg-dev if possible so that they can easily be
undone in one go for 12.10. We even talked about having
dpkg-buildpackage grep debian/rules for DEB_*_MAINT_* variables, but I'm
pretty sure that idea makes everyone involved feel physically ill!
What I think we settled on as the least bad option is to refine the
dpkg-buildpackage workaround so that it does not export environment
variables if the package it's building is using debhelper compat level 9
or above, and to manually review all such existing packages to make sure
that they will continue to do the right thing given that change. Such a
change to dpkg-buildpackage would absolutely be a layering violation -
dpkg-dev is not supposed to know about anything in debhelper - but it
would at least be contained to the same paragraph as the existing
transitional workaround so that it can be removed all in one go, it
*reduces* the scope of the existing transitional workaround, and (if we
ignore the deprecated DH_COMPAT) it can be written quite simply.
Furthermore, this means that packages using the most modern packaging
style are built in line with how Debian builds them, which I think is
the right direction even if the way we get there is temporarily a bit
Many packages are saved by other behaviours of debhelper. Not only do
the dh_auto_* tools fetch dpkg-buildflags output at compat level 9, but
also dh itself does so, which means that anything run as a subprocess of
dh, including override_dh_* rules, will have build flags exported. cdbs
has some similar sets of behaviour, albeit conditional.
Given Debian's current behaviour, none of this should get any worse, as
packages will now build incorrectly in Debian if they get this wrong; so
we can safely just audit the current state of precise.
If my grep is correct (oh for lintian.ubuntu.com ...) there are 119
packages using debhelper compat level 9 in precise right now. I've
examined all of these, and have so far refined that list to 16 packages
that look as though their behaviour may be changed in Ubuntu by this
additional dpkg-buildpackage workaround:
I'm still working through these, and I expect most of these will
actually be false positives.
Colin Watson [cjwatson at ubuntu.com]
More information about the ubuntu-devel