5

Some background: I'm using Debian 7 as my main environment, and I want to tell my system that I have glibc = 2.15 in addition to the environment's required glibc = 2.13 for the purposes of using some more recent applications.

I got the glibc from the various tutorials on the web for installing eg.: Steam. It is unpacked in /usr/local/lib/libc6-2.15 and I've tested it with some applications such as Pidgin 2.10, Boinc 7 and Stellarium, it's working well (so far, I do expect it to eventually fail gracefully). Since it'd be much better if I could install those applications from packaged sources as well (both clang and Boinc are in testing for example), I'd like to tell my system via a virtual package that I do, in fact, have a glibc 2.15 available.

Of course I know about equivs as a tool to create virtual packages for stuff that one does not have installed from repositories, but I have found no good documentation so far on how to use equivs to create a virtual package that can update an already installed package, ideally without breaking.

I first tried the obvious:

Package: libc6
Version: 2.15-1

And dpkg-installed the generated package, with the expected result that it uninstalled the already present libc to update and left the system in an unusable state. (Of course, I tried this in a VM). I've also tried

Version: >= 2.13

Without any good results.

I tried to look for a way of using Provides or Enhances by creating a package of a different name

Package: local-libc6
Version: 2.15
# Either this:
Provides: libc6
# Or this:
Enhances: libc6 (< 2.15)

But so far I have had no success in getting equivs to create an installable package (aptitude complains about an invalid Provides or Enhances), or even to create a package at all.

Of course, the idea is to create a virtual package for libc that won't uninstall the already installed one, and merely "provides" the new version. But I've found the documentation horribly lacking in that respect so far (and I really don't want to have to delve deep and become lost into the DPKG Encyclopedia; usually I have the disposition and time to do such tasks, but these days my focus is needed elsewhere).

So, I guess the base question is: can I use equivs to create an update for a package without uninstalling the original, or achieve something to that effect? What general cares do I need to exercise when specifying versions to equivs?

  • Have you tried to hold the 2.13 package before with sudo apt-mark hold package_name? Or force reinstalling it after it was removed? Did you compile glibc from source? (if so see checkinstall, even to see the type of output control file that comes from it and it's also supposed to allow a package to install independently from other packages so maybe dpkg reacts differently? and dh_make in the context of creating packages.) – user44370 Aug 9 '13 at 21:53
  • Further interesting reads: a slightly more complex example of package building, detailed specifications of the fields in the control file, an exotic use of the version field to achieve unusual results... and finally, info on the architecture spec for packages. – user44370 Aug 9 '13 at 22:43
  • @illuminÉ: didn't try holding, though it sounds like it shouldn't work. I mean, doesn't holding it mean that no other versions can be installed, ever? As for the links you've provided, nice info - I only had one of those. I'll be checking the VM later to try some of those. – Luis Machuca Aug 9 '13 at 23:50
2

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.

  • The /etc/ld.conf.so.d/ tree is one of the ways how I am allowing the applications using libc6=2.15 to run, and I've had little problem with that. The issue is how to install those applications a better way than by having to do the old compile-from-source ceremony: they are provided packaged! From what I'm seeing from the various links and related help files, it seems the only ways is I'd have to create another partition and install a more advanced distro live there via debootsrtap. Or just use a VM. – Luis Machuca Aug 10 '13 at 15:10
  • So basically it can't be done in a Debian system by design? Given that I already have the ld.config.so facility working, could I just force-install the packages? – Luis Machuca Aug 16 '13 at 21:38
  • Design and the limitations I exposed. I wish someone with more experience than me would comment as I don't know the best practices. Force installing is always a hazard, and when you end up with a conflicting state it's a mess and you lose the ability to leverage dpkg at the same time so you can't install before you resolve conflicts. Pretty sure the way to go is install from source or compile from source then package then install - those won't need dependencies and will uninstall easily. But it's time consuming. On Solaris you have boot environments and zfs rollback to alleviate the pain. – user44370 Aug 17 '13 at 2:41
  • Just found this... maybe that's something to try! 2.7.2--2.7.7. – user44370 Aug 17 '13 at 5:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.