1

Is it possible to link to a specific shared library with g++/cmake such that my application will not run if the exact version is not present on the target machine? Ultimately, I don't want to use any library versions I haven't directly tested with.

I've seen this question, but it doesn't handle the case of rejecting versions.

I understand that the dynamic linker does do this to some extent via the SONAME, e.g. libmylib.so.0 won't link to an application requiring libmylib.so.1. But is there a way to discriminate at higher version resolution than the SONAME supplies (e.g. only link if libmylib.so.1.5.3 is present)? Or is this just bad practice?

qdin
  • 268
  • 3
  • 15
  • "only link if libmylib.so.1.5.3 is present" - Use `target_link_libraries(your_exe /path/to/libmylib.so.1.5.3)`. – Tsyvarev Mar 05 '19 at 12:50
  • I tried exactly that, but the resulting application will link on any version of libmylib.so that has an SONAME of libmylib.so.1. I'd like it to fail on libmylib.so.1.6.3, but since its SONAME is also libmylib.so.1 it links successfully. – qdin Mar 05 '19 at 13:38
  • 1
    Hm, linking to `/path/to/libmylib.so.1.5.3` shouldn't succeed unless exactly given file exists. And if the file isn't a symlink, the linker should store its filename (ended with `.so.1.5.3`), so the file should be present on the target machine for being able to run the program. Could you show your code? (The part, which links with the library). – Tsyvarev Mar 05 '19 at 14:33
  • I just realized we need to be careful and distinguish build-time linking (i.e. during make) with dynamic linking (at runtime). :) When you say 'linking to /path/...' are you talking about at runtime? – qdin Mar 05 '19 at 15:49
  • In my cmake, I typically have the line target_link_libraries(my_target PRIVATE /path/to/fribidi-0.19.7/lib/libfribidi.so.0.3.6). For this experiment I created a fake version of the .so called libfribidi.so.0.4.0, and then updated my cmake to match. I ran cmake, which linked fine. I then moved my_target to the system that has libfribidi.so.0.3.6 but not 0.4.0 and it dynamically linked fine (presumably because it found something which matched libfribidi.so.0, the soname) – qdin Mar 05 '19 at 15:56
  • Yes, it is a good idea to diffirentiate *build-time* and *runtime* linking. In my previous comment I meant both of them: the first one in the first sentence, and the second one in the second. After the library is built, you may check with `ldd ` which files will be searched at runtime for load libraries. What `ldd` shows for your executable about `libfribidi` library? – Tsyvarev Mar 05 '19 at 16:10
  • Even though I build-time link to fribidi.so.0.4.0, calling ldd on my_target shows an entry for libfribidi.so.0 (=>...), with one digit only. But this makes sense: objdump -p libfribidi.so shows us that the SONAME embedded in the shared object is libfribidi.so.0. I’m pretty sure the build-time linker uses this, regardless of how many digits you specify in the cmake call. – qdin Mar 06 '19 at 04:47
  • Ok, you are right: when the linker creates an entry for dynamic loader, it uses not an library file extension, but a soname embedded into the library. It seems that you have no other way than modify binary file after it is created. See e.g. this SO question: https://stackoverflow.com/questions/2759254/how-can-i-change-the-filename-of-a-shared-library-after-building-a-program-that. – Tsyvarev Mar 06 '19 at 08:31

0 Answers0