The system has been “normally” installed and administered.
Maybe the implementation in cmake is overly complex and can be done a lot easier and less error prone. The tool “ldd” returns the full path to the dependent shared objects. These can be taken as is and do not need any search paths, e.g. returned from ldconfig. This works for 64Bit builds as well as 32Bit builds which is probably not the case using the paths returned by ldconfig.
The problem with using ldd is that it returns things that might otherwise have been excluded by the {PRE,POST}_{INCLUDE,EXCLUDE}_REGEX arguments of file(GET_RUNTIME_DEPENDENCIES).
It is. The problem is that there is not a way to make ldd work with the REGEXes, because ldd will continue to follow dependencies that would have otherwise been excluded by the REGEXes.
For example, if your program depends on /usr/lib/libfoo.so, and that in turn depends on /lib/bar.so, and you have regexes that exclude /usr/lib, then you could filter /usr/lib/libfoo.so from the ldd output, but you would still get /lib/bar.so. With our approach, all of /usr/lib/libfoo.so’s dependencies are also excluded (unless they’re pulled in by something else) because it doesn’t make sense to pull in a dependency for something that we’re not including in the first place.
This is effectively what we do (we also extract RPATH and RUNPATH at this point). However, we then perform the search manually because we don’t want to have LD_LIBRARY_PATH interfere here (and we can’t necessarily clear it because it may be necessary to make ldd run).
We are using OpenSuse Leap. I am not a Linux specialist and regrettfully cannot tell you why /usr/lib and /usr/lib64 are in the list, what ldconfig is used for and how the loader works. Most probably it needs to have some idea of the architectur else it could not distinguish 32Bit and 64Bit libraries which may reside with the same name in /lib and /lib64.
Arghhhh: the usual hassle when using global variables such as environment variables.
My understanding of LD_LIBRARY_PATH is that the loader evaluates the variable and gives libraries on LD_LIBRARY_PATH precedence over system defaults or other locations where libraries can be found. This means that other libraries may be used at load time than were used at link time. I do not think that this is what is desired when using cmake to detect dependencies for packaging. We want to have exactly those libraries defined when linking. To my understanding this means that LD_LIBRARY_PATH may not be set when using ldd for the purpose. If ldd does not work correctly without LD_LIBRARY_PATH then there may be a more serious problem on the build system. The approach currently taken by cmake seems to require reimplemenation of some of the logic of the linker/loader which could be very fragile.
Please take all of this with a grain of salt: I have no intimate knowledge of loader/linker and an extreme allergy against global variables.
Cross compilation (though a naked ldconfig is a problem in this case anyways I guess), custom binutils… I can’t seem to find the emails where we discussed using ldd vs. a re-implementation right now; maybe it was a face-to-face meeting. I seem to remember symlinks being involved now that I’m writing this (ldd does realpath on its found libraries maybe?). But we do need to search on Windows (because its lookup rules are just searches anyways) and macOS (we also memoize library IDs and whatnot for future bundling).
It basically is a reimplementation. We had problems with O(n²) on big projects when we couldn’t cache the lookups (not all builds happen on SSDs ). Memoizing found library dependency results cut our times on some projects down by 90% or so (IIRC; they were large in any case). Now some of that was because of the CMake → Python implementation that had been done for that. I don’t know the performance difference between those Python scripts and the resolvers in CMake.