How to avoid linking to system libraries

Hello everyone, first post!
Anyway, I am configuring the deal.II library on a server, and there is a nasty linking issue (https://github.com/dealii/dealii/issues/11245). We have two Boost libraries, one in /lib64 and the one I want (the ‘external’).
Configuration goes without trouble, but libraries are linked preferently to the objects in /lib64 whenever they are found. In a small test case I can unset implicit libraries and it fixed this (see linked issue):

UNSET(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES)
UNSET(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES)
UNSET(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES)
UNSET(CMAKE_C_IMPLICIT_LINK_DIRECTORIES)

but the same fix does not work for the entire library, as implicit libraries still get built and the spurious links happen anyway. I have tried:

  1. Unsetting the implicit cmake variables as I’ve shown in the beginning of the cmake configuration
  2. Same thing but setting to “” with SET(… “”)
  3. Set includes and links to be set BEFORE:
    SET(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
    SET(CMAKE_LINK_DIRECTORIES_BEFORE ON)

Nothing works, whenever I check the resulting links with ‘ldd’, I always see that cmake preferred linking to /lib64. How can I avoid this?

Best regards

The ldd does not show you which library has been used during build time but rather what the runtime linker finds. And this is influenced by few things like RPATH, or the LD_LIBRARY_PATH (and few others).
Check your build commands (-DCMAKE_VERBOSE_MAKEFILE=ON) to find out what is used at build time.

Thank you for the suggestion, I didn’t know about that option. I created the make output here:


and could not find any references to /usr/lib whatsoever. The only place where this reference is mentioned is in the CMakeFiles/3.17.1/CMakeCXXCompiler.cmake file, where I can see all default directories (/lib, /usr/lib, etc) in the CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES and CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES variables. The library I am finding can be traced back to the implicit link directories (this is a very narrowed down output):

set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES “/MyDir/glm-0.9.7.1/lib64;many other externals with same structure(symengine, sundials, suite-sparse, etc);/lib64;/usr/lib64; again many external libraries (open ssl, zlib, etc)”)

Implicit include directories look similar, meaning that they have some system libraries in between.

Found this link: http://cmake.3232098.n2.nabble.com/setting-LINKER-LANGUAGE-still-adds-lstdc-td7581940.html
I am testing it to see if it works, but I think that implicit calls should be called last by default, I have found many references to this problem and solutions are very ad-hoc.

I took a quick look at the output - the header directory for boost seems to be set correctly (-isystem …/boost-1.72.0-…) but the link directory is not (while it is set for, for example, zlib ( -L …/zlib-1.2.11-…/lib)). That would indicate that the link directory for boost is not added correctly.

Thanks for helping! So I reconfigured and recompiled by setting the boost directory explicitly. By doing this, when I go to the pkgconfig directory, I see a new line with the link path:

-L/MyBoost/lib -lboost_iostreams-mt -lboost_serialization-mt -lboost_system-mt -lboost_thread-mt

but ldd states otherwise:

$ ldd lib/libdeal_II.so | grep boost
libboost_iostreams-mt.so.1.53.0 => /lib64/libboost_iostreams-mt.so.1.53.0
libboost_serialization-mt.so.1.53.0 => /lib64/libboost_serialization-mt.so.1.53.0
libboost_regex-mt.so.1.53.0 => /lib64/libboost_regex-mt.so.1.53.0

The package is found merely by using FIND_PACKAGE and then included with INCLUDE. How can I further specify where to pick up the library?

So now it really should be about two things: rpath and runtime environment. Your linker line seems to define RPATH for various libs like zlib: -Wl,-rpath -Wl,....../zlib-1.2.11-....../lib. Does it now define a similar thing for boost?
And even if so, if something is linked indirectly (a dependency of boost library itself) it may still be picked up from system location. In this case you either need to control that dependency build (and set its RPATH correctly) or you set LD_LIBRARY_PATH environment variable to point to your libraries.

There’s also a possibility re-configure dynamic linker but it’s system-wide and you almost for sure don’t want it.

I’m adding this for future reference as I could not solve this: I have seen similar issues and they are always related to using spack in a cluster, so this is very much dependent on how such an environment was built. Of course, more customization makes this harder and harder to track… at least in my experience.
My final solution was to stop using spack :slight_smile:.