7

以下列方式设置链接库时

target_link_libraries (SOME_TARGET -L/somedir -lfoo)

cmake 不处理 RPATH。使用“-L”和“-l”不是最佳实践,还是完全错误?在创建我自己的 Find*.cmake 时,我通常使用find_library(),但我得到的 find 脚本没有这样做,而是使用“-L”和“-l”采用上述形式。

文档并没有真正解释 RPATH 是如何收集的,文档也不清楚它是如何处理“-l”和“-L”的,你得到的唯一指针是

“以 - 开头但不是 -l 或 -framework 的项目名称被视为链接器标志”

4

2 回答 2

9

通常不建议指定依赖于工具链的标志,例如-land ,因为它破坏了可移植性并且可能会产生与您预期不同的效果。-L

设置链接器路径的正确方法是link_directories命令。

CMake 中惯用的解决方案是find_library用于定位库,然后将完整路径传递给链接器,因此您根本不需要担心链接目录。

现在,RPATH 是一个不同的野兽,因为它还决定了动态库在运行时的位置。通常,默认设置在这里可以正常工作。如果您发现自己处于不幸的境地,但它没有,有许多目标属性和 CMake 变量会影响这一点:

有一些属性用于指定 RPATH 规则。INSTALL_RPATH 是一个以分号分隔的列表,指定要在已安装目标中使用的 rpath(对于支持它的平台)。INSTALL_RPATH_USE_LINK_PATH 是一个布尔值,如果设置为 true,则会将链接器搜索路径中和项目外部的目录附加到 INSTALL_RPATH。SKIP_BUILD_RPATH 是一个布尔值,指定是否跳过自动生成允许目标从构建树运行的 rpath。BUILD_WITH_INSTALL_RPATH 是一个布尔值,指定是否将构建树中的目标与 INSTALL_RPATH 链接。这优先于 SKIP_BUILD_RPATH 并且避免了在安装之前重新链接的需要。INSTALL_NAME_DIR 是一个字符串,用于指定 Mac OSX 上共享库的“install_name”字段的目录部分,以在已安装的目标中使用。创建目标时,变量 CMAKE_INSTALL_RPATH、CMAKE_INSTALL_RPATH_USE_LINK_PATH、CMAKE_SKIP_BUILD_RPATH、CMAKE_BUILD_WITH_INSTALL_RPATH 和 CMAKE_INSTALL_NAME_DIR 的值用于初始化这些属性。

(来自set_target_properties文档

此外,您可能想查看RPATH 处理的 CMake Wiki 页面

不幸的是,整个 RPATH 业务相当复杂,彻底的解释需要比 StackOverflow 答案更多的空间,但我希望这足以让你开始。

于 2014-08-19T08:59:56.637 回答
1

基本上,你用target_link_libraries()错了。根据文档,您应该提供目标、库以及一些CMake特定的链接标志。

例如这样的:

target_link_libraries(my_build_target somedir/foo.so)

如果您使用自己精心设计Find*.cmake的解决方案,通常是这样完成的:

find_library(foo)
//build main target somewhere here
//now link it:
target_link_libraries(my_build_target ${FOO_LIBRARIES})

注意:我假设您制作的Find*.cmake文件遵循这些准则并填充 CMake 变量,如SOMELIB_LIBRARIES, 和/或SOMELIB_INCLUDE_DIRS等。

注意2:就我个人而言,target_link_directories()这很痛苦,如果不是真的需要,你应该避免使用它。很难维护和使用相对于当前源目录的路径。

于 2014-08-19T09:00:55.913 回答