0

I am working with a large CMake project, and trying to debug why an rpath in a shared library is not getting set at all. Digging through the verbose output, the build command can be found to be:

 /usr/bin/c++  -fPIC  -DVERSION_INFO=\"0.0.1\"  -fPIC -std=c++14 \
-fopenmp -Wall -Wextra -O2 -DNDEBUG  -Wl,-rpath \
-Wl,/usr/lib/openmpi/lib  -Wl,--enable-new-dtags -shared \
-Wl,-soname,libScannerBitCAPI.so.1 \
-o ../../../../../lib.linux-x86_64-3.6/pyscannerbit/libScannerBitCAPI.so. \
CMakeFiles/ScannerBitCAPI.dir/ScannerBit/examples/ScannerBit_CAPI.cpp.o \
<tonnes more object files> \ 
/usr/lib/openmpi/lib/libmpi_cxx.so /usr/lib/openmpi/lib/libmpi.so \
/usr/lib/openmpi/lib/libmpi.so -ldl -lgsl -lgslcblas -lm \
/home/farmer/anaconda3/envs/general/lib/libhdf5.so -lrt -lpthread \
/home/farmer/anaconda3/envs/general/lib/libz.so -ldl -lm \
/home/farmer/anaconda3/envs/general/lib/libpython3.6m.so \
../../../../../lib.linux-x86_64-3.6/pyscannerbit/libyaml-cpp.so.0.6.2 \
-lgsl -lgslcblas /home/farmer/anaconda3/envs/general/lib/libhdf5.so \
-lrt -lpthread /home/farmer/anaconda3/envs/general/lib/libz.so \
/home/farmer/anaconda3/envs/general/lib/libpython3.6m.so \
-Wl,-rpath,/home/farmer/anaconda3/envs/general/lib/python3.6/site-packages/pyscannerbit:/usr/lib/openmpi/lib:/home/farmer/anaconda3/envs/general/lib \

Now, the thing that stands out to me here is that the -rpath command appears twice, and the first one is empty. That seems pretty suspicious.

But before I go trying to chase down how those flags end up there, I wanted to check; is that actually how the compiler (gcc in this case) will interpret these flags? In the event of multiple occurences of -rpath, are all except the first ignored? My interpretation of the manual is no, that isn't how it works:

-rpath=dir
       Add a directory to the runtime library search path.  This is used when linking an ELF executable with shared objects.  All
       -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime.

This seems to suggest that you can add many -rpaths by using the flag multiple times.

So what else could be wrong? Why doesn't this command result in any rpaths getting set in my libScannerBitCAPI.so shared library?

Ben Farmer
  • 2,387
  • 1
  • 25
  • 44
  • Can you show your CMakeLists that generates rpath? – Matthieu Brucher Nov 16 '18 at 14:57
  • 1
    And the first one is not empty, the argument is the next -Wl – Matthieu Brucher Nov 16 '18 at 14:58
  • Not really, there are many layers to it, and this part just comes from an add_library command, with nothing special about the rpath. I set the rpath with things like CMAKE_INSTALL_RPATH, rather than anything specific to this target. However, I see another possibility: the -Wl,--enable-new-dtags part. Apparently this tells the linker to set RUNPATH rather than RPATH? Indeed, looking in the built object, it appears that the RUNPATH contains the path from the last -Wl,-rpath command. So I need to figure out how to get CMake to turn that off... – Ben Farmer Nov 16 '18 at 15:00
  • What is telling you that "an rpath in a shared library is not getting set at all"? – Mike Kinghan Nov 16 '18 at 15:04
  • Do you set CMAKE_INSTALL_RPATH? What is in CMAKE_SHARED_LINKER_FLAGS? – Matthieu Brucher Nov 16 '18 at 15:05
  • `readelf -d /libScannerBitCAPI.so |grep -i rpath` returns nothing. However I discovered that `readelf -d /libScannerBitCAPI.so |grep -i runpath` DOES contain a path. So I guess it works, it just set RUNPATH rather than RPATH due to this --enable-new-dtags flag. It doesn't seem like this should be a problem though, this just means it gets searched after LD_LIBRARY_PATH, right? So it should still find what it needs. Maybe my problems is something else. – Ben Farmer Nov 16 '18 at 15:08
  • That's what I thought you'd find, so I agree maybe the problem is elsewhere. – Mike Kinghan Nov 16 '18 at 15:11

0 Answers0