[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Dependencies of -dev packages


(Parts of this topic has been discussed before, but the issues were not
solved, so let's try again).

Today I wanted to install libcurl-openssl-dev, because I wanted to build
an application locally that can utilize libcurl (and for the curious, I
choose libcurl-openssl-dev because the application already uses OpenSSL
natively and I felt no reason to link both OpenSSL and gnutls into the
same binary). The problem with this was that libcurl-openssl-dev wanted
to remove heimdal-dev which I also use for developing an other
application in favour of libkrb5-dev. So we have 2 problems that are
somewhat connected:

1. libcurl-openssl-dev Depends: on libkrb5-dev
2. libkrb5-dev Conflicts: with heimdal-dev

(the exact packages do not matter, they are just used to demonstrate the

libcurl-openssl-dev Depends: on libkrb5-dev

This issue was already discussed, last time due to link failures caused
by missing libtool .la files. But the thing is, .la files only show the
symptom, not the real problem.

The real problem is that -dev packages should contain everything needed
for both shared _and_ static linking, but the dependency information is
_different_ for static and shared linking. Therefore, the Depends: line
in the control file cannot describe both properly.

Things needed for shared linking:
- if an installed header #includes a header from an other -dev package,
  then a Depends: on that package

Note: we do _not_ need to depend on any packages that are used
internally but are not exposed in the public headers.

Things needed for static linking:
- if an installed header #includes a header from an other -dev package,
  then a Depends: on that package
- if the .a library references a symbol from an other package, then a
  Depends: on that package

This means that static dependencies are a superset of shared
dependencies. So, if the Depends: line in the control file wants to
cover static linking, then a lot of other packages that are not
neccessary for shared-only linking will be pulled in, and people have
already complained about that.

On the other hand, if the Depends: line in the control file covers only
shared linking, then people wanting to link statically need to know a
lot about how the Debian package was built to be able to install the
dependencies. For example, in the libcurl case, they'd need to know not
only that they need Kerberos development libraries, but also they should
know which one, since they are not ABI-compatible.

The proper solution were to move the headers and static libraries to
separate packages: the Depends: line of the header-package would follow
the requirements of dynamic linking, and the Depends: line of the static
library package would follow the requirements of static linking. This
would also solve the "missing libtool .la file" problem if all .la files
were included in the static library packages.

The downside is obvious: double the number of -dev packages. So I
propose a different solution, which is not perfect, but is better than
the current situation:

- -dev packages should only Depend: on other -dev packages neccessary
  for shared linking
- -dev packages should Recommend: any other -dev packages that are
  neccessary for static linking
- Make pkg-config mandatory. pkg-config can already handle the case that
  different libraries are needed for static and shared linking.
  pkg-config also helps the second problem (conflicting -dev packages),
  see below

How this would work:

- The Depends: line ensures that shared linking is always possible
- Due to the Recommends:, people tight on space do not have to install
  a horde of other -dev packages if they do not want static linking, but
  people wanting to link statically can still get the right dependencies
- pkg-config's .pc file properly documents what other libraries are
  needed for static linking, even if the same API (but not the same ABI)
  is provided by multiple packages

What is not solved here is the "missing libtool .la file" problem. But
pkg-config's .pc files can provide the almost the same functionality as
the .la files, so most .la files could simply be removed (there are a
small number of applications that parse .la files run-time though).

Sort test on my current desktop:
$ dpkg -l | grep -- "-dev " | wc -l
$ pkg-config --list-all | wc -l

So making pkg-config mandatory in the not-too-distant future (etch + 1?)
does not look unreasonable.

libkrb5-dev Conflicts: heimdal-dev

The problem here is that this "Conflicts:" assumes that the system has
just one user, which is simply not true. It is perfectly valid that on
the same system user A wants to use MIT Kerberos for his own application
while user B wants Heimdal. Or, better example, user A wants to use
libcurl3-gnutls-dev due to licensing reasons while user B wants to use
libcurl3-openssl-dev because he is already relying on OpenSSL.

pkg-config comes handy again. If every package provides a .pc file, then
conflicting libraries and headers can simply be moved to separate
directories (/usr/lib/heimdal, /usr/lib/mit-krb5, /usr/include/heimdal,
/usr/include/mit-krb5) and can peacefully coexist. Configuration scripts
(/usr/bin/krb5-config etc.) can use the alternatives system. Man pages
can either use the alternatives system, or use different sub-sections
(xyz.3heimdal, xyz.3mit).

Conflicting packages built from the same source (like
libcurl-openssl-dev and libcurl-gnutls-dev) can use alternatives on the
.pc file to select the system-wide default version, while normal users
(and other packages that depend on a particular version) could set
PKG_CONFIG_PATH if they want to use the other version.

Hmm, this got pretty long. Comments?


     MTA SZTAKI Computer and Automation Research Institute
                Hungarian Academy of Sciences

Reply to: