I am trying to install runtime dependencies on linux by calling file(GET_RUNTIME_DEPENDENCIES …) on my build output. According to the documentation of GET_RUNTIME_DEPENDENCIES, it uses objdump to look at the binaries’ RPATH or RUNPATH and search all resulting paths for the NEEDED libraries.
However, even with the RUNPATH containing all necessary paths containing the required shared objects, cmake still gives me a bunch of unresolved dependencies.
Passing the same paths that are set in RUNPATH to the DIRECTORIES argument of file(GET_RUNTIME_DEPENDENCIES …) succeeds in resolving all dependencies but gives me a warning for every dependency that I am unable to silence/turn off.
Here is the output of readelf -d libMylib_lin_x64d.so.1.0.0 | head -20
:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [liblog4cplus.so.9]
0x0000000000000001 (NEEDED) Shared library: [libcryptopp.so.8.3]
0x0000000000000001 (NEEDED) Shared library: [libdcmdata.so.18]
0x0000000000000001 (NEEDED) Shared library: [libofstd.so.18]
0x0000000000000001 (NEEDED) Shared library: [libxerces-c-3.2.so]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libMylib_lin_x64d.so.1]
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN:$ORIGIN/../lib:/home/gulasch/.conan2/p/b/cryptc8e13ae91e60f/p/lib:/home/gulasch/.conan2/p/b/log4c5df06e985f3a4/p/lib:/home/gulasch/.conan2/p/b/openc69d3d7db3b05a/p/lib:lib:/home/gulasch/.conan2/p/b/jaspe16a77cc27d1e4/p/lib:/home/gulasch/.conan2/p/b/opene862f5376d9366/p/lib:/home/gulasch/.conan2/p/b/imath0e51a887ff6ff/p/lib:/home/gulasch/.conan2/p/b/libti9f14735261ffd/p/lib:/home/gulasch/.conan2/p/b/libdea4b1ad00bdbd1/p/lib:/home/gulasch/.conan2/p/b/xz_ut1e858d36cea6d/p/lib:/home/gulasch/.conan2/p/b/libwe89f655e7182ab/p/lib:/home/gulasch/.conan2/p/b/quircb247a8c1bbf6d/p/lib:/home/gulasch/.conan2/p/b/sg_dc34b16dff6208b/p/lib:/home/gulasch/.conan2/p/b/xerce5f41203938bb6/p/lib:/home/gulasch/.conan2/p/b/qt696009b81d695/p/lib:/home/gulasch/.conan2/p/b/qt696009b81d695/p/bin/archdatadir/plugins/sqldrivers:/home/gulasch/.conan2/p/b/pcre20afe2d5ebf49c/p/lib:/home/gulasch/.conan2/p/b/doubl5d4c4d34d83a6/p/lib:/home/gulasch/.conan2/p/b/fontcfac338373bef7/p/lib:/home/gulasch/.conan2/p/b/freeta20d2c1e0c3e0/p/lib:/home/gulasch/.conan2/p/b/libpn402ee48efea0a/p/lib:/home/gulasch/.conan2/p/b/bzip2b31559afc869e/p/lib:/home/gulasch/.conan2/p/b/brotle2db4ab3cc1fd/p/lib:/home/gulasch/.conan2/p/b/expatb6e837219b758/p/lib:/home/gulasch/.conan2/p/b/util-b22aa04c21e8c/p/lib:/home/gulasch/.conan2/p/b/libjp26b7cedd82fcb/p/lib:/home/gulasch/.conan2/p/b/sqlit3f252b752839e/p/lib:/home/gulasch/.conan2/p/b/libmy582f77fd99038/p/lib:/home/gulasch/.conan2/p/b/opens0ee33e3382a6c/p/lib:/home/gulasch/.conan2/p/b/zlib6747250a5944a/p/lib:/home/gulasch/.conan2/p/b/lz45edd945259b6d/p/lib:/home/gulasch/.conan2/p/b/odbcba036906a7ae0/p/lib:/home/gulasch/.conan2/p/b/libto0d3eec5b51b1b/p/lib:/home/gulasch/.conan2/p/b/libic287f0d1508b00/p/lib:/home/gulasch/.conan2/p/b/zstdd5bad879821af/p/lib:]
0x000000000000000c (INIT) 0x128000
0x000000000000000d (FINI) 0x1f661c
0x0000000000000019 (INIT_ARRAY) 0x24c928
0x000000000000001b (INIT_ARRAYSZ) 80 (bytes)
0x000000000000001a (FINI_ARRAY) 0x24c978
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
And here is the generated script I use to resolve dependencies on the build library:
set(_INPUT_LIBS /mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/libMylib_lin_x64d.so.1.0.0)
set(_OUTPUT_PATH /mnt/c/Users/Gulasch/source/repos/MyProject/out/install/WSL-GCC-Debug/lib)
if(_INPUT_LIBS)
set(_LIBS_SECTION LIBRARIES ${_INPUT_LIBS})
endif()
file(GET_RUNTIME_DEPENDENCIES
${_LIBS_SECTION}
RESOLVED_DEPENDENCIES_VAR _r_deps
UNRESOLVED_DEPENDENCIES_VAR _u_deps
PRE_EXCLUDE_REGEXES
"libc\\.so\\..*"
"libgcc_s\\.so\\..*"
"libm\\.so\\..*"
"libstdc\\+\\+\\.so\\..*"
POST_EXCLUDE_REGEXES
"^/lib.*"
"^/usr/lib.*"
)
file(INSTALL
DESTINATION ${_OUTPUT_PATH}
TYPE SHARED_LIBRARY
FOLLOW_SYMLINK_CHAIN
FILES
${_r_deps}
)
foreach(_file IN ITEMS ${_u_deps})
message(WARNING "Unresolved dependencies for ${_INPUT_LIBS}: ${_file}")
endforeach()
And here is the output of running the script with cmake -P <script>
:
CMake Warning at MylibCopyRuntimeDependencies_PostBuild_Debug.cmake:54 (message):
Unresolved dependencies for
/mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/libMylib_lin_x64d.so.3.6.0:
libcharset.so.1
/mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/Mylib/MylibCopyRuntimeDependencies_PostBuild_Debug.cmake(54): message(WARNING Unresolved dependencies for ${_INPUT_LIBS}${_INPUT_EXES}: ${_file} )
CMake Warning at MylibCopyRuntimeDependencies_PostBuild_Debug.cmake:54 (message):
Unresolved dependencies for
/mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/libMylib_lin_x64d.so.3.6.0:
libiconv.so.2
/mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/Mylib/MylibCopyRuntimeDependencies_PostBuild_Debug.cmake(54): message(WARNING Unresolved dependencies for ${_INPUT_LIBS}${_INPUT_EXES}: ${_file} )
CMake Warning at MylibCopyRuntimeDependencies_PostBuild_Debug.cmake:54 (message):
Unresolved dependencies for
/mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/libMylib_lin_x64d.so.3.6.0:
liboflog.so.18
/mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/Mylib/MylibCopyRuntimeDependencies_PostBuild_Debug.cmake(54): message(WARNING Unresolved dependencies for ${_INPUT_LIBS}${_INPUT_EXES}: ${_file} )
CMake Warning at MylibCopyRuntimeDependencies_PostBuild_Debug.cmake:54 (message):
Unresolved dependencies for
/mnt/c/Users/Gulasch/source/repos/MyProject/out/build/WSL-GCC-Debug/lib/libMylib_lin_x64d.so.3.6.0:
libofstd.so.18
I manually set the BUILD_RPATH to contain all linked lib dirs and $ORIGN, but leaving the BUILD_RPATH property empty results in a much slimmer RUNPATH line in the objdump/readelf, but the script output does not change.
Does GET_RUNTIME_DEPENDENCIES use some different heuristic here or am I calling something wrong? just to cover my bases, the paths in RUNPATH do contain the required libs. for example an ll /home/gulasch/.conan2/p/b/libic287f0d1508b00/p/lib
returns
total 1228
drwxr-xr-x 2 gulasch gulasch 4096 May 17 12:44 ./
drwxr-xr-x 6 gulasch gulasch 4096 May 17 12:44 ../
lrwxrwxrwx 1 gulasch gulasch 19 May 17 12:44 libcharset.so -> libcharset.so.1.0.0*
lrwxrwxrwx 1 gulasch gulasch 19 May 17 12:44 libcharset.so.1 -> libcharset.so.1.0.0*
-rwxr-xr-x 1 gulasch gulasch 29496 May 17 12:44 libcharset.so.1.0.0*
lrwxrwxrwx 1 gulasch gulasch 17 May 17 12:44 libiconv.so -> libiconv.so.2.6.1*
lrwxrwxrwx 1 gulasch gulasch 17 May 17 12:44 libiconv.so.2 -> libiconv.so.2.6.1*
-rwxr-xr-x 1 gulasch gulasch 1216144 May 17 12:44 libiconv.so.2.6.1*
so it contains both the reportedly missing libcharset.so.1 and libiconv.so.2.
This both happens with cmake 3.30 and cmake 3.26