我有一个链接到外部库的 C++ 项目 该库由供应商提供,其中仅包含一个 .h header 目录和一个共享对象文件“libabc.so”。
在我项目的 CMakeLists 中,我有一个使用外部库的 obj(我将其构建到 bar.so)。
在构建最终的可执行文件时,我尝试了多种方法。
add_library(bar STATIC /some/source/file/bar.cpp)
add_library(abc_lib SHARED IMPORTED)
set_property(TARGET abc_lib PROPERTY IMPORTED_LOCATION /path/to/external/lib/libabc.so)
add_executable(foo /some/file/to/main.cpp)
target_link_libraries(foo bar abc_lib)
这构建正常并且链接正常,但是当我这样做时
ldd foo
,abc_lib没有以
abc.so =>/path/to/external/lib/libabc.so
相反,它以独立的形式出现
/path/to/external/lib/libabc.so
,根据我最近读到的一些帖子,这表明库没有直接链接。
但是当我执行 chrpath -d foo
或 patchelf --remove-rpath foo
时,可执行文件仍然包含路径并且不会使用我在 LD_LIBRARY_PATH 中提供的路径
所以我尝试了另一种方式
add_library(bar STATIC /some/source/file/bar.cpp)
add_library(abc_lib SHARED IMPORTED)
set_property(TARGE abd_lib PROPERTY IMPORTED_SONAME abc)
link_libraries(/path/to/external/lib)
add_executable(foo /some/file/to/main.cpp)
target_link_libraries(foo bar abc_lib)
然而这次,它提示 abc_lib-NOTFOUND
总结一下我的问题,我想要一个针对本地共享对象的项目构建链接,同时我应该能够使用 chrpath
或 清理 rpath patchelf
以便我可以将可执行文件复制到具有类似环境但可能与外部库路径不同的服务器,我想使用 LD_LIBRARY_PATH 覆盖该路径。
最佳答案
您要查找的 key 是IMPORTED_NO_SONAME . 您可以向共享的导入库目标添加一个额外的属性:
set_property(TARGET abc_lib PROPERTY IMPORTED_NO_SONAME TRUE)
或在一个 cmake 命令中更好:
set_target_properties(abc_lib PROPERTIES
IMPORTED_LOCATION /path/to/external/lib/libabc.so
IMPORTED_NO_SONAME TRUE
)
CMake 将使用 /path/to/external/lib/libabc.so 而不是 -L/path/to/external/lib -llibabc.so 作为链接如果 libabc.so 在其 ELF header 中没有 soname,则为选项。 您可以通过以下方式验证这一点:
readelf -d /path/to/external/lib/libabc.so
官方 cmake 文档:Imported Libraries解释更多细节。
关于c++ - cmake 将外部库与 IMPORT_SONAME ro IMPORT_LOCATION 链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68164903/