c++ - 针对错误版本的库的 CMake 链接
问题描述
我有一些依赖于 Protobuf v2.5 的 CMake 包,以及一个依赖于 Protobuf v3.4 的包。我在系统范围内安装了 v2.5 /usr
,而 v3.4 仅在单个包中使用。因此,我将 v3.4 的标头放在3rdparty
使用它的包内的子目录中,然后调用include_directories(3rdparty)
我的 CMakeLists.txt 以便可以找到它。
至于共享库,v2.5 的 .so 文件存在于.so 中/usr/lib/x86_64-linux-gnu
,我将 v3.4 的 .so 文件安装到/usr/lib
. 简而言之,目录结构如下所示:
v2.5:
标题:/usr/include
库:/usr/lib/x86_64-linux-gnu
v3.4:
标题:<MY_PACKAGE_SRC_DIRECTORY>/3rdparty
库:/usr/lib
现在,当我尝试链接到 v3.4 时,问题就出现了。为了简化事情,我不使用任何 CMake 模块文件来查找 protobuf v3.4,而是/usr/lib/libprotobuf.so
在创建目标时将硬编码路径添加到要链接的库列表中。但即便如此,当我运行时ldd my_target_executable
,结果是:
libprotobuf.so.8 => /usr/lib/x86_64-linux-gnu/libprotobuf.so.8
这意味着它正在链接 v2.5 in 的库/usr/lib/x86_64-linux-gnu
,即使我在构建此可执行文件时/usr/lib
的调用中添加了指向正确 .so 文件的硬编码路径。target_link_libraries
值得注意的是,如果我删除 .so 中的文件/usr/lib/x86_64-linux-gnu
,那么它会链接到 .so 中的正确文件/usr/lib
,因此似乎出于某种原因,CMake 在/usr/lib/x86_64-linux-gnu
使用我提供的库路径之前会进行搜索。如何更改此行为,或以任何其他方式解决此问题?
更新
v3.4 的库文件/usr/lib/x86_64-linux-gnu/libprotobuf.so
是一个链接,/usr/lib/x86_64-linux-gnu/libprotobuf.so.14
而该链接又是指向实际文件的链接/usr/lib/x86_64-linux-gnu/libprotobuf.so.14.0.0
。
target_link_libraries
现在,如果我将我提供的硬编码路径更改为/usr/lib/x86_64-linux-gnu/libprotobuf.so
第二个符号链接 /usr/lib/x86_64-linux-gnu/libprotobuf.so.14
或实际文件/usr/lib/x86_64-linux-gnu/libprotobuf.so.14.0.0
,那么我的可执行文件会正确链接到 v3.4。似乎提供的符号链接的名称对 CMake 的行为有一些影响。
解决方案
这不是专门针对 cmake 的,而是使用 gcc 和共享库在 Linux 上的工作方式。
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
当您指定target_link_libraries( target /usr/lib/x86_64-linux-gnu/libprotobuf.so)
时,将链接设置为-lprotobuf
. 在这种情况下,它应该只使用它首先找到的任何版本的库。
target_link_libraries( target /usr/lib/x86_64-linux-gnu/libprotobuf.so.14)
调整 cmake 生成的链接行以使用特定的库版本。这似乎告诉 gcc 链接到该版本,这将改变运行时和库搜索时发生的情况。
在某些情况下,CMake 可能会要求链接器搜索库(例如 /usr/lib/libfoo.so 变为 -lfoo),例如当检测到共享库没有 SONAME 字段时。有关另一种情况的讨论,请参见政策 CMP0060。
推荐阅读
- python - 围绕字符串某些部分的python单引号
- odoo-8 - 字段更改时产品添加到行
- angular - Angular 6 - 从工作区嵌入应用程序
- office365 - 通过图形API直接在office365中离线打开单盘文档
- java - HashSet使用HashTable作为数据结构,HashMap作为集合?不推荐使用内存视点数组?
- html - 使用 HashLocationStrategy 时如何导航到页面的特定部分
- python - CoreML - 多数组输入需要在应用程序或模型中进行预处理?
- python - 从numpy数组中删除连续数字
- xpath - Xpath,使用两个查询返回两条信息而不是同时返回
- javascript - 移动设备上的vue路由器延迟