The answer is that a package created with equivs-build
from a control file which contains a variation on the name (libc6-local for ex.) of an existing package and a higher version, will trigger the removal of the older package, not because of the execution to prerm
or postrm
scripts from neither the new or old package, but by design.
Now, it is possible to create a package with an entirely different name, and set in the control file that it provides a package like libc6. More specifically, consider the following control file (only relevant portion shown) for a proposed virtual package:
Package: 6cbil-local //libc6 backwards is good enough
Version: 2.9
Provides: glibc-2.9
Section: libs
Compare this with the control file in libc6 2.17-0ubuntu5 (my machine):
Package: libc6
Source: eglibc
Version: 2.17-0ubuntu5
Architecture: amd64
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Installed-Size: 10441
Depends: debconf (>= 0.5) | debconf-2.0, libgcc1
Suggests: glibc-doc, locales
Conflicts: prelink (<= 0.0.20090311-1), tzdata (<< 2007k-1), tzdata-etch
Breaks: lsb-core (<= 3.2-27), nscd (<< 2.17)
Replaces: libc6-amd64
Provides: glibc-2.17-1
Section: libs
Priority: required
Multi-Arch: same
Then consider an empty package based on this control file:
Package: using6
Version: 1.0
Depends: libc6 (= 2.9) // it requires that specific version
Then build the packages. Our virtual package which provides glib-2.9 installs and doesn't remove any installed libc6. When you try installing our package which depends on glibc-2.9 we get an error in apt
(set up as 2.2 here):
The following packages have unmet dependencies:
using6 : Depends: libc6 (= 2.9) but 2.17-0ubuntu5 is to be installed
E: Unable to correct problems, you have held broken packages.
or dpkg
:
dpkg: dependency problems prevent configuration of using6:
using6 depends on libc6 (= 2.9); however:
Version of libc6:amd64 on system is 2.17-0ubuntu5.
Go back to our initial virtual package and replace what it provides with:
Provides: glibc-2.9, libc6
Then try to reinstall our package which depends on glibc-2.9. dpkg
gives the same error message but not apt
!!!! Apt actually changed its mind the minute I built the packages after changing the provide value then pushed changes to the Packages.gz and updated apt with dpkg-scanpackages dirwithpackages | gzip > dirwithpackages/Packages.gz
then sudo apt-get update
:
The following packages have unmet dependencies:
using6 : Depends: libc6 (= 2.9) //notice the reference to 2.17 is gone!!
E: Unable to correct problems, you have held broken packages.
This is actually a bit different from the explanation I had missed in the Debian Handbook:
5.2.1.4.3. Current Limitations
Virtual packages suffer from some troubling limitations, the most significant of which being the absence of a version number. To return to the previous example, a dependency such as Depends: libdigest-md5-perl (>= 1.6), despite the presence of Perl 5.10, will never be considered as satisfied by the packaging system — while in fact it most likely is satisfied. Unaware of this, the package system chooses the least risky option, assuming that the versions do not match.
GOING FURTHER Virtual package versions Although today virtual packages
can't have versions, this will not necessarily always be the case.
Indeed, apt is already able to manage the versions of virtual packages
and it is likely that dpkg eventually will too. We will then be able
to write fields such as Provides: libstorable-perl (= 1.7) to indicate
that a package provides the same functionality as libstorable-perl in
its 1.7 version.
The experience above shows that apt
and dpkg
behaved somewhat differently (insofar as error messages change) with my setup (Xubuntu 13.04, dpkg=1.16.10 (amd64) and apt=0.9.7.7ubuntu4 (amd64)). Apt
acknowledges that it sees that this package we installed provides libc6, but it doesn't see that it provides exactly version 2.9. Ultimately apt calls dpkg so dpkg should be the bottleneck.
It seems on my setup the only value that makes a difference for
"Provides" in a control file under your scenario is libc6. But
that won't be enough to allow installing software with reliance on a
specific version because of current limitations and design.
Finally, as you know, ld.config.so is the facility to take care of all the linking as demonstrated in this example of the chain of ld.so.conf files and directories. The linking infrastructure and the $LD_LIBRARY_PATH variable to shared objects take priority over default library locations such as /lib and /usr/lib in this context.
Best Answer
Being able to reproduce a specific setup, down to the exact version, is your requirement, not Debian’s.
Debian only supports a single version of each binary package in any given release; the counterpart of that is that great care is taken to ensure that package updates in any given release don’t introduce regressions, and when such care isn’t possible, to document that fact. Keeping multiple versions of a given package would only increase the support burden and the test requirements: for example, package maintainers would have to test updated packages against all available versions of the libraries they use, instead of only the currently-supported versions... Packages are only updated in a stable release when really necessary, i.e. to fix a serious bug (including security issues). In the kernel’s case, this sometimes means that the kernel ABI changes, and the package name changes as a result of that (to force rebuilds of dependent packages); there are meta-packages which you can pull in instead of hard-coding the ABI (
linux-image-amd64
,linux-headers-amd64
, etc.).There is however a workaround for your situation: every published source and binary package is archived on snapshot.debian.org. When you create a versioned setup, you can pick the corresponding snapshot (for example, one of the September 2019 snapshots) and use that as your repository URL:
If you end up relying on this, please use a caching mirror of some sort, for example Apt-Cacher NG. This will not only reduce the load on the snapshot server, it will ensure that you have a local copy of all the packages you need.
(The situation with regards to source packages is slightly more complex, and the archives do carry multiple versions of some source packages in a given release, because of licensing dependencies. But that’s not relevant here. Strictly speaking, Debian does provide multiple versions of some binaries in supported releases: the current version in the current point release, along with any updates in the security repositories and update repositories; the latter are folded in at the next point release. So maintaining a reproducible, version-controlled system configuration is feasible without resorting to snapshots, as long as you update it every time a point release is made.)