bug-libtool
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bugreport: Incorrect forwarding of a shared library's -R flags when this


From: Stefan Muller
Subject: Bugreport: Incorrect forwarding of a shared library's -R flags when this library is linked to an executable
Date: Tue, 5 Jan 2010 20:01:29 -0800

Dear libtool maintainers,

I think I have found a bug in libtool regarding the "forwarding" of a shared library's "-R" flags when this library is linked to an executable.

My configuration is as follows:

$ uname -a
Linux plaspc01 2.6.28-16-generic #57-Ubuntu SMP Wed Nov 11 09:49:32 UTC 2009 x86_64 GNU/Linux

$ libtool --version
ltmain.sh (GNU libtool) 2.2.6b
...

I tried to build a libtool library, libfft.la, which itself links against the Intel Math Kernel Library (MKL). I now have two different versions of the MKL library:

/opt/intel/mkl/9.0/lib/em64t/*
/opt/intel/mkl/10.2.3.026/lib/em64t/*

These have vastly different interfaces, but both define a library libguide.so, so the runtime linker is stuck with the first version it finds on its path in ld.so.conf.

I wanted to decide during ./configure which version of the MKL library to use in libfft.so, without having to modify the path of the runtime linker, so I find the "-R" flag, which is described in the manual:

"-R libdir
If output-file is a program, add libdir to its run-time path. If output-file is a library, add -Rlibdir to its dependency_libs, so that, whenever the library is linked into a program, libdir will be added to its run-time path."

This seems to be the right behavior, so I do in fft/Makefile.am:

libfft_la_LIBADD = address@hidden@ address@hidden@ -l...

Then I have a test program for libfft, called fft_test, where fft_test/Makefile.am contains:

fft_test_LDADD = $(top_builddir)/fft/libfft.la -lm

Libtool produces a libfft.la which contains:

# Libraries that this one depends upon.
dependency_libs=' -R/opt/intel/mkl/10.2.3.029/lib/em64t  -L/opt/intel/mkl/10.2.3.029/lib/em64t -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread'

However, the command line to link fft_test that Libtool produces is:

/bin/bash ../libtool --tag=CC   --mode=link gcc  -g -O2   -o fft_test fft_test.o ../fft/libfft.la -lm 
libtool: link: gcc -g -O2 -o .libs/fft_test fft_test.o  ../fft/.libs/libfft.so -L/opt/intel/mkl/10.2.3.029/lib/em64t -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -Wl,-rpath -Wl,/usr/local/torpex_cyl/lib

Clearly, the "-R" runtime path got dropped, so my executable looks like:

$ ldd fft_test 
linux-vdso.so.1 =>  (0x00007fffe328f000)
libfft.so.0 => /usr/local/torpex_cyl/lib/libfft.so.0 (0x00007f9cbef10000)
libmkl_intel_lp64.so => not found
libmkl_sequential.so => not found
libmkl_core.so => not found
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f9cbecf4000)
libm.so.6 => /lib/libm.so.6 (0x00007f9cbea6f000)
libc.so.6 => /lib/libc.so.6 (0x00007f9cbe6fd000)
libmkl_intel_lp64.so => /opt/intel/mkl/10.2.3.029/lib/em64t/libmkl_intel_lp64.so (0x00007f9cbe2fd000)
libmkl_sequential.so => /opt/intel/mkl/10.2.3.029/lib/em64t/libmkl_sequential.so (0x00007f9cbdb7b000)
libmkl_core.so => /opt/intel/mkl/10.2.3.029/lib/em64t/libmkl_core.so (0x00007f9cbd93b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9cbf113000)
libdl.so.2 => /lib/libdl.so.2 (0x00007f9cbd737000)

...which doesn't work since the reference to the 3 MKL libraries that was introduced during the linking of fft_test is unresolved. However, the reference to these libraries coming from libfft is resolved, as it should be.

So, by (unnecessarily) repeating the MKL libraries during the linking of fft_test, libtool ruined the executable, since it dropped the -R runtime path.

Ideally, all references to MKL would be masked by libfft, so I proceed by manually telling libtool in libfft.la that there are no unresolved references (i.e. that are not resolved by my "-R" runtime paths):

# Libraries that this one depends upon.
dependency_libs=''

This works great. However, patching libfft.la at every build seems messy, so I look why libtool dropped the "-R" flags in the first place. I find the following section in ltmain.sh, with the crucial line #6002 (exclamation marks):

        for var in $vars dependency_libs; do
          # Add libraries to $var in reverse order
          eval tmp_libs=\"\$$var\"
          new_libs=
          for deplib in $tmp_libs; do
            # FIXME: Pedantically, this is the right thing to do, so
            #        that some nasty dependency loop isn't accidentally
            #        broken:
            #new_libs="$deplib $new_libs"
            # Pragmatically, this seems to cause very few problems in
            # practice:
            case $deplib in
            -L*) new_libs="$deplib $new_libs" ;;
            -R*) ;;                                                             # !!!!!!!!!!!!!!
            *)
              # And here is the reason: when a library appears more
              # than once as an explicit dependence of a library, or
              # is implicitly linked in more than once by the
              ...

So I comment out this line and suddenly libtool produces:

/bin/bash ../libtool --tag=CC   --mode=link gcc  -g -O2   -o fft_test fft_test.o ../fft/libfft.la -lm 
libtool: link: gcc -g -O2 -o .libs/fft_test fft_test.o  ../fft/.libs/libfft.so -L/opt/intel/mkl/10.2.3.029/lib/em64t -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -Wl,-rpath -Wl,/usr/local/torpex_cyl/lib -Wl,-rpath -Wl,/opt/intel/mkl/10.2.3.029/lib/em64t

...which works.

So I claim that the

-R*) ;;

on line #6002 of ltmain.sh is a bug.

Additionally, even if this worked for me, I noticed that other linker flags, such as 

-Wl,--start-group ... -Wl,--end-group

got dropped, which looks like trouble on the long run.

As a more general comment, it is quite unsatisfactory that there seems to be no mechanism to tell libtool that the dependencies on MKL are completely resolved within libfft's runtime path, so that any program just has to link against libfft and everything would work like a charm. In particular, one could easily replace the FFT engine, say by building a libfft2.la that links against FFTW. Then all "downstream" programs could just link against libfft2 instead of libfft, without ever having to worry about what engines these libraries are using.

In any case, it seems important to fix the "-R" forwarding bug in libtool, since it leads to broken executables.

Best regards,
Stefan


reply via email to

[Prev in Thread] Current Thread [Next in Thread]