0

I'm on a Linux machine in which I don't have root access. This machine has Boost 1.36 on it, but I need a newer version of boost, so I installed a local version of Boost 1.62. I'm linking some object files with nvcc. The link also includes about 20 third-party dynamic libraries. The output result of the link is another dynamic library.

The problem is this: if I run 'ldd' on the output library, it tells me that library is dependent on both libboost_system.so.1.36.0 and libboost_system.so.1.62.0.

I can't figure out how the libboost_system.so.1.36.0 got in there. None of the other dynamic libraries are dependent on libboost_system.so.1.36.0 (I ran ldd on all of them). How can I tell where the libboost 1.36 dependency comes from?

Here is a brief description of the linker command that creates the output library:

nvcc --ptxas-options=-v --compiler-options '-fPIC' --shared
lots of object files
lots of -L/wherever -lwhatever options
-o libOutput.so
JB_User
  • 3,117
  • 7
  • 31
  • 51
  • How did you build your output library? What command did you use? At the problem's most basic, the dependency came from there. – Lightness Races in Orbit May 04 '17 at 14:04
  • I added a brief description of the link command to the original text. – JB_User May 04 '17 at 14:08
  • "lots of object files" "lots of -L/wherver -lwhatever options" Seriously? What are we supposed to do with vagueness like that lol – Lightness Races in Orbit May 04 '17 at 14:16
  • Sorry for the vagueness. It's necessary. The object files are a list of 30 .o files. The -Lwherever -lwhatever options are just that. I ran ldd on all of the .so files in the -L directories. I'm not sure if it would help if I provided the actual list. It contains about 60 files. – JB_User May 04 '17 at 14:19
  • No, it's not necessary, because after you've constructed your [MCVE] you can give us a simple one-liner demonstrating the problem. You should already have done that as part of your personal debugging efforts. – Lightness Races in Orbit May 04 '17 at 14:41
  • Not sure how to do what you suggested. If I remove object files from the linker command, then it won't link successfully. If I remove libraries from the linker command, it also won't link successfully. I'm not looking for someone to debug this for me. Just looking for advice on how to find what is causing the library dependency. – JB_User May 04 '17 at 15:20
  • Yes you have to modify the code to go along with it. This is a basic debugging technique: you narrow down your problem. Divide and conquer. – Lightness Races in Orbit May 04 '17 at 15:21
  • Yes, everyone knows that. In this case, that is not possible. Ther eare over a million lines of code. I was hoping that some with knowledge about linkers and dynamic libraries could explain how a dependency for libboost_system.so.1.36.0 could somehow appear in a library when there was no dependency in any of the libraries and object files from which it was built. – JB_User May 04 '17 at 16:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143420/discussion-between-jb-user-and-boundaryimposition). – JB_User May 04 '17 at 16:21
  • Sorry, no, it is always possible. It just takes time and effort. :) – Lightness Races in Orbit May 04 '17 at 16:25
  • Sorry, but it really isn't possible given my constraints. I would just like to know how a dependency for libboost_system.so.1.36.0 could somehow appear in a library when there was no dependency in any of the libraries and object files from which it was built. Do you know the answer to that? – JB_User May 04 '17 at 16:30
  • Sure. It isn't possible for a library to appear as a dependency out of nowhere. Part of your program or build process linked it. I tried to help you determine which part. Good luck! – Lightness Races in Orbit May 04 '17 at 17:02

3 Answers3

1

This problem is not specific to using nvcc. When you link the executable, you pass the paths to the 3rd party libraries with the -L flag to the linker. When you execute ldd or the binary that eventually uses your library, the dynamic loader is invoked. The ld.so(8) manual describes the order in which the loader searches the paths when it looks for the libraries. In your case the loader most likely finds the boost 1.36 libs first and only for the libs not present in the 1.36 release it falls back to the 1.62 version. I suggest you to check the order of the paths in the LD_LIBRARY_PATH environment variable.

Also note that ldd is recursive, so it does not show the libs that your library is linked to. You can use e.g. lddtree mentioned in this answer.

Community
  • 1
  • 1
Jakub Klinkovský
  • 1,248
  • 1
  • 12
  • 33
0

Use objdump -p libABCD.so | grep NEEDED to view dependencies on individual library files. Then follow on the output libraries.

minghua
  • 5,981
  • 6
  • 45
  • 71
-1

Instead of giving the boost libraries as -l on the linker command line, you can also give them with their full path and file name. This way the linker doesn't look for these libraries in the search path and you can make sure that the system version is not accidentally picked up.

If the problem persist, I'd suggest to test a minimal example that doesn't require any BOOST library to see whether nvcc pulls some system version boost-system library in anyway.

Gert Wollny
  • 529
  • 2
  • 8
  • Yeah, don't do this. You end up hardcoding the library path into your executable, and it becomes non-portable. – Lightness Races in Orbit May 04 '17 at 14:42
  • @BoundaryImposition According to the second and forth answers to [this question](https://stackoverflow.com/questions/7911752/how-to-build-a-shared-library-so-without-hardcoded-full-dependency-paths) if a library has a so-name, then giving it with its full path instead of with -l is okay, and I think that boost libraries have a so-name. – Gert Wollny May 04 '17 at 15:11
  • I always set the soname and this is not my experience – Lightness Races in Orbit May 04 '17 at 15:20
  • @BoundaryImposition On one hand I just checked it, and on my Gentoo Linux amd64 system a library with soname given with full path and without the -l flag on the linker command line is linked without specifying any path to that library in the executable (i.e. the rpath is empty and the library names are without any additional path component). On the other hand the OP could always use [chrpath](https://linux.die.net/man/1/chrpath) to remove the rpath later. – Gert Wollny May 05 '17 at 15:54