[buildd-tools-devel] re buildd's resolver and package's build deps

Roger Leigh rleigh at codelibre.net
Tue Feb 22 17:08:18 UTC 2011


On Mon, Feb 21, 2011 at 07:42:32PM -0600, Raphael Geissert wrote:
> Hi everyone, Roger,
> 
> Roger Leigh has filed a few bug reports related to how the buildd's resolver
> (either internal or any of the new ones: apt{,itude}) and I'm not sure I
> quiet agree.
> Let's take for example the one filed against php5 [#614413]:
> 
> [...]
> > Severity: important
> > 
> > php5 is using these alternative build dependencies:
> > 
> > automake (>= 1.11) | automake1.11
> > libcurl4-openssl-dev | libcurl-dev
> > libdb-dev (>= 4.7) | libdb4.8-dev | libdb4.6-dev,
> > libjpeg-dev | libjpeg62-dev
> > libmysqlclient-dev | libmysqlclient15-dev
> > 
> > The build dependency resolver is currently only using the first
> > alternative.  Newer resolvers use the other alternatives, and
> > this can potentially lead to inconsistency between builds.
> 
> Agreed that it can lead to build-deps inconsistencies.
> 
> > Please only use one package, the one you specifically want for
> > the build, and drop the alternatives.  The use of alternatives
> > in build dependencies is not supported.  In particular, you really
> > only want one specific version of libdb (4.8?); there must be no
> > uncertainty about this when the build dæmon installs the build
> > dependencies.  The same thing applies to automake and the other
> > packages using alternatives.
> 
> I disagree here.
> Alternatives in build-* relationships *are* mentioned by policy. In fact, 
> there's even an example in section 7.1.

This is correct.  I was thinking about drafting a patch for Policy
about this.  Current Policy defines the allowed syntax for
Build-Depends.  It does not however, make any mention of existing
conventions and best practices, which I feel should be addressed.

The current "internal" build dependency resolver does not make
any use of the alternative dependencies.  It always picks the first.
As a result:

· other alternatives are untested (never used)
· we always have consistent builds (because there's only a single
  solution)
· we have recommended against using alternative build dependencies
  since they were introduced; this was partly because sbuild didn't
  support them, but mainly because we want complete consistency

> There's also no stated guarantee *anywhere* (including release policy) that 
> the package's build deps should be consistent, much less the result.

I agree that the documentation is sorely lacking in this regard.
It is, however, an  unofficial and unwritten policy.  The need for
this is fairly self-explanatory: we don't want builds to vary.
Taking one of php5's dependencies as an example:

  libdb-dev (>= 4.7) | libdb4.8-dev | libdb4.6-dev

This dependency permits building against no less than *three* different
Berkeley DB versions.  Given that these versions are typically
incompatible, imagine if a new upload caused a version change.  It
could break all existing databases when the user upgrades and they are
no longer readable.  If could even be a downgrade.  The same applies
to any other libraries.

> Also, alternatives have been used ever since I joined the project for making
> backporting easier. Requiring stricter build-deps also affects that use case.

This is one of the two non-broken use cases for alternatives (the
other being arch-specific deps) I am aware of.  However, given that
the infrastructure has never supported alternative build-deps, I'm not
sure how this is working out in practice.  In order for it to not be
broken, only one of the alternatives should be avilable in each suite
you are targetting.

I would recommend keeping backports on a separate VCS branch rather than
having a single unified package.  It keeps things which should be
separate, separate, and will give unambiguous results for each suite.
It also makes which suite needs which dep self-documenting, and old
deps will not make the current version untidy and potentially buggy.

> After thinking about it for a while, my opinion is that if anyone wants
> consistency to be guaranteed (e.g. in php's case that a rebuild doesn't end
> up linking php to libdb4.6 instead of libdb4.8) it should be handled on
> buildd/release team's side. The build deps as provided by the source package
> are valid.

The specific library versions you link with are up to you, the
maintainer.  This is not something that can be delegated, since it might
well require special handling to migrate data between the different db
versions.  If you always want to build against the current version, then
this is what a simple depends on "libdb-dev" would achieve (with no
alternatives).

About the only thing that's not delegated the the basic system toolchain
in build-essential.  And even then, you aren't forced to use it.

As a result, the Build-Depends should contain a dependency on the
specific version of each library you need, which could be a generic
"current version" one if you don't really care about a specific
version (if it will build with all versions).

> If the package fails to build because the dependencies were resolved in a
> non- standard way then an RC bug should be filed and fixed.
> I abhor the idea of uselessly tightening dependencies.

This is the reason the bug was filed.  There was a discrepancy in the
installed package set when building with a build-dep resolver that /can/
use alternatives.  This wasn't a discrepancy that caused a build
failure, or even linking against the wrong library version, but after
checking the php5 build-deps, I found the abiguous use of alternatives.


The rest of this mail isn't specific to php5; it's about alternative
and virtual depends, and I was going to send this today in any case
(because it's a much more general thing).


Currently, 1294 packages use alternatives in build dependencies.  These
fall into these categories:

· Standard alternative use in the form "concrete|virtual", as used for
  normal deps on virtual packages.  Is this sensible?
· Architecture-specific dependencies
· Broken uses.  Dependencies on multiple different libraries which will
  lead to inconsistent builds.  This affects only a tiny minority of
  packages.  The most obviously broken one I found is already fixed.


What are build dependencies for?

They specify the minimal package set for building the package.
Many packages can be built with a wide variety of different packages,
either optional features which are enabled/disabled appropriately,
or even entirely different set of tools (compilers, code generators,
document processing systems, etc.).

The main issue here is one of scope: should the Build-Depends
describe:
· every potential combination of tools and libraries which
  are possible to successfully build the package
· a set of commonly used ones
· or just a single combination?

The build infrastructure wants the latter: a single, tested, consistent
package set.  Ultimately, this is the entire purpose of the
Build-Depends field: to instruct a build dæmon to install those
packages.  If the package set is ambiguous, with multiple possible
solutions, then we fail key quality metric: reproducible and consistent
builds.

The package set a random developer might have installed to do the build
may well be different, and there's nothing to stop people building with
different packages; but is Build-Depends the place for a relaxed set?
My opinion here is that it is not.


Examples:
· Correct
  libselinux1-dev [!kfreebsd-amd64 !kfreebsd-i386] | libselinux-dev [!kfreebsd-amd64 !kfreebsd-i386]
    Could use kfreebsd-any, but otherwise OK.

· concrete|virtual
  libgl1-mesa-dev | libgl-dev
  libglu1-mesa-dev | libglu-dev
  emacs23 | emacsen
  libsamplerate0-dev | libsamplerate-dev
  automake | automaken
  libncurses-dev | ncurses-dev
  libsdl1.2-dev | libsdl-dev
  mono-devel | c-sharp-compiler
  openjdk-6-jdk | default-jdk

· Dummy package
  libreadline5-dev | libreadline-dev  

· Pointless and/or broken
  flex (>= 2.5.32) | flex-old
  bsd-mailx | mailx
  clisp | cmucl
  perl (>= 5.10) | libmodule-build-perl
  emacs23 | emacs22 | emacs21 | emacs-snapshot
  libgd2-noxpm-dev | libgd2-xpm-dev | libgd2-dev | libgd-noxpm-dev | libgd-xpm-dev | libgd-dev
  default-jdk-builddep | openjdk-6-jdk | sun-java6-jdk | sun-java5-jdk | sun-j2sdk1.4 | java2-compiler
  libblas-dev | libatlas-base-dev, liblapack-dev | libatlas-base-dev
  texlive-font-utils | texlive-extra-utils (<< 2009)
  libwxgtk2.8-dev | libwxgtk2.6-dev
  gcj-jdk | gjdoc
  libstdc++6-4.5-dev | libstdc++6-4.4-dev
  libsnmp-dev (>= 5.4.2.1~dfsg-4~) | libsnmp-dev | libsnmp9-dev, libsnmp-dev (>= 5.4.2.1~dfsg-4~) | perl (<< 5.10.1~rc2-1~)
  bison | byacc
  libcurl4-gnutls-dev | libcurl3-gnutls-dev
    why not just a versioned depends or single depends?
  docbook-dsssl | docbook-stylesheets (>= 1.72-0potato2)
    docbook build-deps are generally a complex mess

OK, the above are a selection of things I pulled out of the current
Sources file.

It's common to depend on concrete|virtual.  For normal packages, it's
like saying "I want y, but if it's not available, install x as a
default implementation of y".  Is this appropriate for a build
dependency?  It certainly works /technically/, but do we want that
level of ambiguity, especially when it concerns libraries?

Another common form is tool1|tool2, where both tools do the same thing
(e.g. yacc variants).  Should the maintainer list all possible tools,
or just make up their minds and pick one that works?  Do we really need
to build with every version of emacs, or just the current one?

Multiple library dev packages are another.  Look at libgd2 above; it's
totally horrific!  The same applies to libsnmp.

Some cases are obviously supporting multiple suites, such as the
texlive and wx examples.  The question here is, should we be doing
this, or only support what's needed to build in the targetted suite,
e.g. unstable?


The need for concrete|virtual is a fundamental deficiency in our
package management that's been unaddressed for years (see old -devel
discussions).  If it was possible to simply depend on a virtual
package, and have the default set for that release, it would save
each package having to pick a different default, and that would
remove much unnecessary variability (in both Build-Depends and regular
Depends); individual packages should not need to impose system-wide
policy.

This is solved for some, e.g. default-jre.  But it's a general problem
that could use a general solution.  This should be fixed for *all*
virtual packages.  It shouldn't require solving separately for each
virtual dep.

Java and DocBook are the two worst offenders WRT build-deps.  Both
have multiple implementations and virtual packages.  Many packages
use different concrete packages in their Build-Depends and regular
Depends.  The result: exactly what is installed is dependent upon
package ordering, and you might even get multiple implementations
installed.  The dependencies are simply awful, and IMO it would
be a useful excercise for these groups of packages to tidy up their
dependencies.


The good news is that although about 15% of the source packages use
alternatives (not filtering out arch-specific), they are mostly
currently benign because they don't actually do anything (i.e. they
are entirely pointless).  Removing them would be simple.

It would probably be a good idea to get lintian to warn if any
alternative other than an arch-specific alternative is used.  Or
even treat it as an error if we decide it's appropriate.


So, questions:
· Do we allow any alternative dependencies other than arch-specific?
If so:
· Do we allow concrete|virtual?
· Do we allow alternative libraries?
· Do we allow different versions of the same library?
· Do we allow use of alternative toolsets?

My take on this is that anything other than arch-specific alternatives
should be strongly discouraged, if not outright banned, and that this
should be put into Policy.  Alternative viewpoints, with examples and
rationale would be useful to hear.

One thing we could do is get sbuild to strip all non-arch-specific
alternatives from the Build-Dependsi, so it would never use
alternatives, ever.  This is for the "apt" and "aptitude" resolvers,
not "internal".  Note that sbuild and other Build-Depends users only
have control over the first-order dependencies; there's another
level of variance in the higher-order indirect dependencies which
is where the variation in my resolver tests came from; we might also
wish to consider restricting some of the alternatives in the regular
package dependencies as well to reduce variability here as well.


Regards,
Roger

-- 
  .''`.  Roger Leigh
 : :' :  Debian GNU/Linux             http://people.debian.org/~rleigh/
 `. `'   Printing on GNU/Linux?       http://gutenprint.sourceforge.net/
   `-    GPG Public Key: 0x25BFB848   Please GPG sign your mail.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.alioth.debian.org/pipermail/buildd-tools-devel/attachments/20110222/91a9bbc8/attachment.pgp>


More information about the Buildd-tools-devel mailing list