Packages affected: dpkg-dev, debhelper, all libraries
Status: implemented - see UsingSymbolsFiles
The goal is to improve dpkg-shlibdeps so that it generates the minimal dependency required to make the application work instead of blindly using the dependency provided by the shlibs file.
In many cases, the dependency generated is too strict as the application doesn't necessarily use the newly-added symbols which justify the dependency bump in the shlibs file. This has many consequences, it can block the propagation of a package in testing waiting for the new version of the library while it would work perfectly fine with the version in testing. The same could even be true between unstable and stable.
- rdesktop doesn't work at all in etch but this bug is fixed in sid. Thanks to the improved dependency generation, the fixed package doesn't depend on the newer libc6 and users can grab the corrected version directly from sid without needing to update the libc6 at the same time.
Thanks to the improved dependencies, the library transitions block a lot less packages and the release managers have less work. Lenny is thus released on time and of higher quality.
The library packages should provide a new file <package>.symbols along the traditional <package>.shlibs. This file indicates (in theory) for each symbol in which version of the library it got introduced in its current functionality. However since we're not going to do historical research to find the right version, we can use whatever first version we want. In general, it probably makes sense to initiate that file with the symbols coming from the stable version of the library (when the soname hasn't changed and no symbol gained functionality.).
dpkg-shlibdeps will then be modified to extract the list of symbols used by each application and will identify the first version of the library that provides all required symbols.
Storage of the symbols file
The format of the symbols file is the following:
<soname> <main dependency template> [| <alternative dependency template>] [ as many alternative dependency templates as needed ] <symbol> <first-version>[ <id of dependency template>] [ as many symbols as needed ]
A dependency template is a full dependency that might integrate "#MINVER#". This place-holder is then replaced by the appropriate "(>= <min-version>)" when the real dependency is generated. The minimal version is generated by finding the biggest <first-version> out of all the symbols used by the application that are affected to this dependency template. Note that #MINVER# can be empty if the application doesn't use any symbols from a library that it's still linked with.
If a symbol has no explicit <id of dependency template>, then it's supposed to be affected to the main dependency template (id=0). Otherwise the number refers to the <n>'th alternative dependency template.
The file is distributed as part of dpkg's control file in /var/lib/dpkg/info exactly like the current shlibs file.
However we need to keep a copy of that file from one version to the next since it's of no interest if we generate it from scratch each time (listing thus always a dependency on the last version of the library). It would seem logical to store them in the source package itself.
- Create the tool that generates the symbols file.
- Modify dpkg-shlibdeps.
- Find a nice way to integrate the call to this tool in the package generation (dh_makeshlibs is a logical place).
- Discussion on -devel:
- Integration in dpkg
- Merged in the master branch since 2007-10-08.
- Integrated in dpkg 1.14.8.
- Many libraries export private symbols which generate noise in the symbols file.
- dpkg-gensymbols can detect new symbols and automatically add version information from them, but it cannot
- detect if a symbol changed meaning or extended its functionality. This always needs maintainer intervention.
- A full-source build could auto-update a symbols file in the debian/ directory but binary-only builds can't and we can't assume that the set of symbols is the same on all arches.
- Idea 1:
The full-source build generates a debian/package.symbols.default file used by all architectures.
We could have debian/package.symbols.arch manually handled by the maintainer and the binary-build could FTBFS if there's any major discrepancy. The build log would include the details of symbols which are not present, as well as the supplementary symbols.
- Idea 2:
- We could have a script update-symbols that downloads the latest version of the symbols file from a Debian server and put it in debian/. That script would have to be called once each time that the maintainer packages a new upstream version.
- On the server side, the package would simply extract the latest version of the symbols file from the real .deb. (This can be easily automated with Mole)
- During a binary build, the symbols file from the debian directory is used a a start, the newer symbols are merged in automatically and the result is shipped in the package.
- Idea 1:
- We must pay attention to symbol hashing. Currently a package compiled on sid won't run on etch even if the version if etch provides all needed symbols. The change is that symbols are not hashed in the same way and ld.so of etch doesn't cope with the symbols available in packages compiled on sid. The glibc shlibs has been bumped (and slightly abused) to make sure that recently compiled packages depend on an glibc new enough to understand the new hashing mechanism.
RaphaelHertzog: If something needs to be done for that, it's probably a hack in dpkg-shlibdeps that detects the hashing method used and add the corresponding dependency. I don't think it makes sense to integrate the notion of hashing in the "symbols" file. Update: all affected packages got recompiled to have both hashing.
- If the system has enough knowledge at the symbol level, it can be used to detect errors and make package FTBFS from for example if a symbol is dropped and the soname is not changed. Of course, an override file could then be used to explicitely ignore this (some private symbols can be dropped at any time).
Guillem Jover has worked on another solution which would work only for libraries providing versioned symbols. dpkg-shlibdeps would extract the version from all symbols used and use that as a base to compute the minimal dependency. The maintainer still has to supply a mapping between "version of symbols" and "version of package".