#723638 libtool: buggy library symlink install due to use of ldconfig

#723638#5
Date:
2013-09-18 11:17:44 UTC
From:
To:
Some MPFR user found the following problem:

https://sympa.inria.fr/sympa/arc/mpfr/2013-09/msg00018.html

which I can reproduce below.

When installing two different versions of MPFR in the same directory,
I get:

[...]
libtool: install: /usr/bin/install -c .libs/libmpfr.so.4.1.2 /home/vlefevre/tmpmpfr/lib/libmpfr.so.4.1.2
libtool: install: (cd /home/vlefevre/tmpmpfr/lib && { ln -s -f libmpfr.so.4.1.2 libmpfr.so.4 || { rm -f libmpfr.so.4 && ln -s libmpfr.so.4.1.2 libmpfr.so.4; }; })
libtool: install: (cd /home/vlefevre/tmpmpfr/lib && { ln -s -f libmpfr.so.4.1.2 libmpfr.so || { rm -f libmpfr.so && ln -s libmpfr.so.4.1.2 libmpfr.so; }; })
[...]

for the first one (MPFR 3.1.2), and:

[...]
libtool: install: /usr/bin/install -c .libs/libmpfr.so.4.1.0 /home/vlefevre/tmpmpfr/lib/libmpfr.so.4.1.0
libtool: install: (cd /home/vlefevre/tmpmpfr/lib && { ln -s -f libmpfr.so.4.1.0 libmpfr.so.4 || { rm -f libmpfr.so.4 && ln -s libmpfr.so.4.1.0 libmpfr.so.4; }; })
libtool: install: (cd /home/vlefevre/tmpmpfr/lib && { ln -s -f libmpfr.so.4.1.0 libmpfr.so || { rm -f libmpfr.so && ln -s libmpfr.so.4.1.0 libmpfr.so; }; })
[...]

for the second one (MPFR trunk r8680), which yields:

lrwxrwxrwx 1      16 2013-09-18 12:42:10 libmpfr.so -> libmpfr.so.4.1.0
lrwxrwxrwx 1      16 2013-09-18 12:42:10 libmpfr.so.4 -> libmpfr.so.4.1.2
-rwxr-xr-x 1 1913565 2013-09-18 12:42:10 libmpfr.so.4.1.0
-rwxr-xr-x 1 1821786 2013-09-18 12:41:21 libmpfr.so.4.1.2

libmpfr.so.4 doesn't have the correct target!

After looking at strace output, the change of libmpfr.so.4 to point
back to libmpfr.so.4.1.2 is done by ldconfig after the installation
of the symlinks:

libtool: finish: PATH="/home/vlefevre/eftests/bin:/home/vlefevre/bin:/home/vlefevre/x86_64/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/games:.:/sbin" ldconfig -n /home/vlefevre/tmpmpfr/lib

This is probably not what the user expects and leads to confusion.
Either ldconfig should no longer be executed or the "make install"
should fail with a clear error message if the installed library is
not the "most recent" one.

("most recent" is the term used by ldconfig, but in practice, the
highest-version library may not be the most recent due to development
versions, which may not have accurate versioning information yet.)

#723638#12
Date:
2013-09-18 16:08:17 UTC
From:
To:
I'm not sure why you find this suprising.  If libmpfr.so.4 is the
soname, than both libmpfr.so.4.1.0 and libmpfr.so.4.1.2 are valid
versions to point to and libmpfr.so.4.1.2 is the latest, so it
makes sense to point to that.


Kurt

#723638#17
Date:
2013-09-18 20:02:35 UTC
From:
To:
Both are valid, but one may be more buggy than the other, for
instance, or at least they have different kinds of "bugs". So, there
may be a good reason to use a different version from the largest one
(I wouldn't say the latest, because in practice, due to branches and
3rd-party patches, there isn't much a notion of time ordering). Then
"make install" should create the symlinks to use the version that
has just been installed. BTW, if the user wanted to use the largest
("latest") version, why would he install another version? This doesn't
make sense!

Moreover, in most documentation, it is said that to install some
software, the process is "./configure && make && make install" (and
one assumes that the software that has just been installed is ready
to be used, if the user's path environment variables are up-to-date,
of course). But this is not the case with the current behavior.

#723638#22
Date:
2013-09-18 20:12:42 UTC
From:
To:
If you do not want to use the version with the highest number, I
suggest you remove it.  At any time you install something ldconfig
is going to be run and update it to point to the latest version.
That is what ldconfig is supposed to do.

I think that also assumes you want to install a newer version,
where newer is a higher number.  That might at that time not
run ldconfig, but more then likely it will get run at some point.


Kurt

#723638#27
Date:
2013-09-18 21:05:23 UTC
From:
To:
Perhaps, but AFAIK, this is not documented (and if it is, this is
hidden somewhere).

This is not what is documented. The libtool manual says that ldconfig
is to be run manually via "libtool -n finish ..." (if the user wants
too):

   Then, running 'libtool -n finish LIBDIR' can give you further hints
on what to do (*note Finish mode::):

     burger# libtool -n finish /usr/local/lib
     PATH="$PATH:/sbin" ldconfig -m /usr/local/lib
     -----------------------------------------------------------------
     Libraries have been installed in:
        /usr/local/lib

     To link against installed libraries in a given directory, LIBDIR,
     you must use the `-LLIBDIR' flag during linking.

      You will also need to do one of the following:
        - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
          during execution
        - add LIBDIR to the `LD_RUN_PATH' environment variable
          during linking
        - use the `-RLIBDIR' linker flag

     See any operating system documentation about shared libraries for
     more information, such as the ld and ld.so manual pages.
     -----------------------------------------------------------------
     burger#

But my point is that it shouldn't be run by "make install".
The Automake manual says:

   After everything has been built, and maybe tested, it is time to
install it on the system.  That means copying the programs, libraries,
header files, scripts, and other data files from the source directory to
their final destination on the system.  The command 'make install' will
do that.

That's just installation of files, not running ldconfig.

ldconfig should normally be run only when the user instructs to do so.

#723638#32
Date:
2013-09-18 21:14:35 UTC
From:
To:
I mean, if you install any library via a Debian package, it should
result in ldconfig being run.  But I would also find it normal
that a "make install" doesn't run ldconfig.

I'm not sure what I expect the result of "make install" to be.
Should it update the symbolic link?  Or should it just copy the
file?  I'm actually expecting it to just install the file and
not update any symbolic link and that ldconfig should do that.
But I'm not sure everybody agrees to that, and I think many
cases of "make install" will result in the symblink being
updated somehow.


Kurt

#723638#37
Date:
2013-09-18 22:05:27 UTC
From:
To:
Note that the library was *not* installed via a Debian package.
In my case it was installed under my home directory.

But ldconfig as run via Debian package installation must not touch
non-system directories, in particular libraries under the user's
home directory. So, such directories should be completely safe.

Even for system directories, the user may want to test various
versions of the library in /usr/local/lib just after installing
them, so that it won't normally be affected by installation of
Debian packages if the tests are done immediately. Anyway the
user should be aware that specific things may occur with system
directories, which are partly controlled by the system and should
normally not be used for experimentation.

Also the fact that the system does special things with system
directories is not a valid reason for doing such things via
"make install".

It should do the minimal steps
  1. to make the software (application, library...) directly usable
     (the installed version, not a different one);
  2. without touching other software, except when absolutely necessary
     to fulfill (1).

In practice, (2) means that other versions (previously installed) of
the installed software (and other software depending on them) may no
longer work.

If for some reason, it can be detected that (1) cannot be fulfilled,
then the installation process should end with an error: a clear error
message and a non-zero exit status. This will allow the user to detect
the problem and decide what to do.

I think that the symbolic link should be updated to the installed
version, because the ultimate goal of library installation is to
be able to use it.

Also note that the current description of Libtool's versioning system
(Libtool manual Sections 7.2 and 7.3) clashes with ldconfig behavior
(and more generally with library installation, but ldconfig makes this
worse). As I've said in

https://sympa.inria.fr/sympa/arc/mpfr/2013-09/msg00019.html
-------- # Libtool -version-info CURRENT[:REVISION[:AGE]] for libmpfr.la # # 1. No interfaces changed, only implementations (good): # ==> Increment REVISION. # 2. Interfaces added, none removed (good): # ==> Increment CURRENT, increment AGE, set REVISION to 0. # 3. Interfaces removed or changed (BAD, breaks upward compatibility): # ==> Increment CURRENT, set AGE and REVISION to 0. Now assume that there are two MPFR versions x.y and x.y' with entirely (backward *and* forward) compatible interfaces, for instance because only some algorithms have changed. Then these two different versions would have the same CURRENT and same AGE values. For patch releases, one could make sure to increase REVISION by skipping values already used by the other version, but if such releases get installed, this could mean that the highest version would not necessarily be used. For instance, one could have the successive releases: version -version-info 5.2.0 17:0:6 5.3.0 17:1:6 5.2.1 17:2:6 When 5.2.1 is released (fixing bugs only present in 5.2.0), if it is installed while 5.3.0 is also already installed, then 5.2.1 will be chosen instead of 5.3.0 by the linker. -------- With ldconfig, this makes such things worse, because even if 5.3.0 is (re)installed after 5.2.1, ldconfig will revert the version to 5.2.1 (due to higher REVISION). So, I've said then: IMHO, to avoid such problems, I think that we should always increment CURRENT for new MPFR minor or major versions; revisions would just be incremented for patch releases. i.e. increment CURRRENT even if the most recent interface remains the same. If this is the good way to do, then Libtool manual Sections 7.2 and 7.3 should be corrected.