我有一些 CMake 包依赖于 Protobuf v2.5,还有一个依赖于 Protobuf v3.4。我在系统范围内安装了 v2.5 /usr
,而 v3.4 仅在单个包中使用。因此,我将 v3.4 的 header 放在 3rdparty
中。使用它的包内的子目录,然后我调用 include_directories(3rdparty)
在我的 CMakeLists.txt 中,以便可以找到它。
至于共享库,v2.5 的 .so 文件存在于 /usr/lib/x86_64-linux-gnu
中,我将 v3.4 的 .so 文件安装到 /usr/lib
.简而言之,目录结构如下所示:
v2.5:
header :/usr/include
图书馆:/usr/lib/x86_64-linux-gnu
v3.4:
header :<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
意味着它正在链接 /usr/lib/x86_64-linux-gnu
中的 v2.5 库,即使我在 /usr/lib
中添加了指向正确 .so 文件的硬编码路径在调用 target_link_libraries
在构建此可执行文件时。
值得注意的是,如果我删除/usr/lib/x86_64-linux-gnu
中的.so文件, 然后它会链接到 /usr/lib
中正确的 .so 文件,所以看起来出于某种原因,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
到第二个符号链接(symbolic link) /usr/lib/x86_64-linux-gnu/libprotobuf.so.14
, 或实际文件 /usr/lib/x86_64-linux-gnu/libprotobuf.so.14.0.0
,然后我的可执行文件正确链接到 v3.4。所提供的符号链接(symbolic link)的名称似乎对 CMake 的行为有一些影响。
最佳答案
这不是具体的 cmake,而是在 Linux 上如何使用 gcc 和共享库工作。
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 链接到那个版本,这将改变运行时和库搜索时发生的事情。
There are some cases where CMake may ask the linker to search for the library (e.g. /usr/lib/libfoo.so becomes -lfoo), such as when a shared library is detected to have no SONAME field. See policy CMP0060 for discussion of another case.
关于c++ - CMake 链接到错误版本的库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53594469/