Summary: -------- gen_ld_script is removing a vital unversioned symlink from some packages, and this breaks libtool lt_dlopenext consumers at runtime.
Details: -------- While examining bug #486640, I discovered a concerning interaction [1] between libtool's lt_dlopenext and gen_ld_script. I don't have a good handle on how many packages are affected, but it would be an code that uses lt_dlopenext to try and find a library. For our example, we're using the fact that sys-power/nut wants to use libusb from dev-libs/libusb-compat. dev-libs/libusb-compat has these files: /usr/lib64/libusb.so (from gen_ld_script) /lib64/libusb-0.1.so.4.4.4 /lib64/libusb-0.1.so.4 (symlink to 4.4.4) lt_dlopenext is given the basename of a library to find. In this case, the (modified) code tries both libusb and libusb-0.1, with slightly different failures: 1. lt_dlopenext cannot parse linker scripts at all, so the libusb.so from gen_ld_script cannot be opened. 2. lt_dlopenext only tries to append .so, it doesn't add version specifiers. If I manually add a symlink: /lib64/libusb-0.1.so -> /lib64/libusb-0.1.so.4 then lt_dlopenext succeeds. This led me to looking at the libusb-compat in more detail. Before gen_ld_script runs, it has the library and two symlinks in /usr/lib64: /usr/lib64/libusb-0.1.so.4.4.4 /usr/lib64/libusb-0.1.so.4 (symlink) /usr/lib64/libusb.so (symlink) At this stage, lt_dlopenext works still. Now after gen_ld_script, the unversioned symlink is replaced by a linker script. The versioned symlink and base file have moved to /lib64. Since lt_dlopenext cannot handle the linker script, and the unversioned symlink is gone, we now get a failure. Proposed Fix: ------------- I would like to propose that gen_ld_script does NOT remove the unversioned symlinks, but instead moves them along with the versioned symlinks. Questions: ---------- How can we sanely get all user systems updated for this subtle bug? Comments: --------- In bug #4411, comment 43, vapier noted: > any package that does dlopen("libfoo.so") without the version info like > ".so.X" is broken. In this case, the lt_dlopenext consumer is explicitly testing multiple versions of libusb at runtime, and picking the correct interface: it doesn't need to depend on a specific version. This is also because the lt_dlopenext interface does NOT accepted files versioned after the .so: it needs the filename with no extensions. [1] I do half-expect vapier, flameeyes or patrick to shoot me down, and tell me the package is doing something wrong, but I've also got a chance of this actually being a system breakage. -- Robin Hugh Johnson Gentoo Linux: Developer, Infrastructure Lead E-Mail : robb...@gentoo.org GnuPG FP : 11ACBA4F 4778E3F6 E4EDF38E B27B944E 34884E85