不能使用find_package时替代link_directories

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不能使用find_package时替代link_directories相关的知识,希望对你有一定的参考价值。

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

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

答案

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

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

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

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

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

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

以上是关于不能使用find_package时替代link_directories的主要内容,如果未能解决你的问题,请参考以下文章

find_package(Boost) 返回空的 Boost_LIBRARIES

cmake:Windows编译支持HTTPS的curl库及find_package查找CURL时需要注意的问题

find_package的默认搜索路径是什么( )使用cmake时的功能?

CMake中find_package的使用

使用find_package链接assimp库

Cmake命令之find_package介绍