'Why can't cmake locate C++/C++ABI runtime dependencies?

I was trying to write a cmake script to auto install my targets:

set_target_properties(tiflash PROPERTIES INSTALL_RPATH "$ORIGIN/")
install (TARGETS A
         COMPONENT A-release
         DESTINATION "."
         RUNTIME_DEPENDENCY_SETA-dependency)
install (RUNTIME_DEPENDENCY_SET A-dependency
         COMPONENT A-release
         DESTINATION "."
         POST_EXCLUDE_REGEXES "libdl.*" "libc-.*" "libc\\..*" "libgcc_s.*" "librt.*" "libm.*" "ld-.*" "libpthread.*")

In this case, RUNTIME_DEPENDENCY_SET is supposed to include libc++.so.1 and libc++abi.so.1 as I was using LLVM toolchain and I wanted to package the runtime libs with my executables.

CMake did include the expected libs; but it complained that cmake cannot locate libc++.so.1 and libc++abi.so.1. (I suppose this was because libc++.so.1 and libc++abi.so.1 were installed in an unregistered location /usr/local/lib/x86_64-unknown-linux-gnu).

I can walk around this problem by adding sth like DIRECTORIES /usr/local/lib/x86_64-unknown-linux-gnu to the install function. However, warnings will be issued. The document says:

If it is found in such a directory, a warning is issued, because it means that the file is incomplete (it does not list all of the directories that contain its dependencies)

I am curious what does it does not list all of the directories that contain its dependencies mean here? In what list? Rpaths or something else?

I tried to put /usr/local/lib/x86_64-unknown-linux-gnu to BUILD_RPATH of my target. It did not work. (I have checked the generated install script, it calls file(GET_RUNTIME_DEPENDENCIES) on the building target; so I suppose install rpath won't affect the results.)

I also have LD_LIBRARY_PATH and LIBRARY_PATH set in my environment (which contains /usr/local/lib/x86_64-unknown-linux-gnu). And CMAKE_PREFIX_PATH is pointing to /usr/local/.



Solution 1:[1]

I just noticed that cmake explained the resolution procedure:

  1. If the depending file does not have any RUNPATH entries, and the library exists in one of the depending file's RPATH entries, or its parents', in that order, the dependency is resolved to that file.

  2. Otherwise, if the depending file has any RUNPATH entries, and the library exists in one of those entries, the dependency is resolved to that file.

  3. Otherwise, if the library exists in one of the directories listed by ldconfig, the dependency is resolved to that file.

  4. Otherwise, if the library exists in one of the DIRECTORIES entries, the dependency is resolved to that file. In this case, a warning is issued, because finding a file in one of the DIRECTORIES means that the depending file is not complete (it does not list all the directories from which it pulls dependencies).

  5. Otherwise, the dependency is unresolved.

So, I set the runtime path, what is the problem then?

It turns out that A depends on an imported lib, let us say, B.

However, B also depends on libc++.so.1 and it does not set the runtime path. I guess cmake do the resolution in a DFS manner and finalize all leaves before roots. So, the error is actually generated for B.


As a solution, I think it would be better if I do ldconfig properly.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1