不能使用find_package时替代link_directories

时间:2018-03-05 03:29:51

标签: cmake

我正在开发一个需要链接非标准包的科学代码,因此find_package之类的东西对我不起作用。用户必须能够准确指定链接的目录和库(两个缓存变量:LIBRARY_PATHS和LIBRARIES)。因为我在最顶层的CMakeLists.txt中创建了目标,然后使用各种target_*命令来构建它们,所以我不能使用link_directories,如果目标已经不能使用find_library已定义。

在定义目标后,是否有一种简单的方法可以指定要包含在链接中的目录?我正在考虑定义一个宏,它接受LIBRARY_PATHS和LIBRARIES并使用{{1}}将LIBRARIES转换为具有完整路径的库列表。然而,这样的黑客似乎违背了CMake理念,所以我想知道是否有更好的方法。

1 个答案:

答案 0 :(得分:1)

  

在定义目标后,是否有一种简单的方法可以指定要包含在链接中的目录?

您可以使用以下代码将链接器标志添加到特定目标:set_target_properties(<target> PROPERTIES LINK_FLAGS <flags>)。在您的情况下,<flags>将是一个路径列表,其中每个路径都以相应的链接器标志作为前缀,(-L如果您使用的是Clang / GCC)。

示例: -L<path1> -L<path2>

  

我正在考虑定义一个带有LIBRARY_PATHS和LIBRARIES的宏,并使用find_library将LIBRARIES转换为具有完整路径的库列表。然而,这样的黑客似乎违背了CMake理念,所以我想知道是否有更好的方法。

您可以考虑在CMake的结果中创建find_library()目标。这种方法在FindConfig - 模块中非常常见。这可能会让你开始:

foreach(_LIBRARY ${LIBRARIES})
    find_library(_LIB ${_LIBRARY} PATHS ${LIBRARY_PATHS})
    if(_LIB)
        message(STATUS "Found '${_LIBRARY}' at '${_LIB}'")
        add_library(${_LIBRARY} UNKNOWN IMPORTED)
        set_target_properties(${_LIBRARY} PROPERTIES IMPORTED_LOCATION ${_LIB})
    else()
        message(FATAL_ERROR "Could not find '${_LIBRARY}'.")
    endif()
    unset(_LIB CACHE)
endforeach()

这将创建CMake目标(导入的库)并将其映射到LIBRARIES中的每个条目。然后,您可以像往常一样链接到这些目标中的任何一个:target_link_libraries(<target> <SCOPE> <some-item-from-LIBRARIES>)

为什么add_library(),为什么不使用find_library()的结果?

你可以。未来对target_link_libraries()的调用看起来完全一样。但是,创建“真正的”CMake目标会增加更多灵活性,因为您可以在CMake目标上获取/设置属性。 See here for some examples