我正在开发一个需要链接非标准包的科学代码,因此find_package
之类的东西对我不起作用。用户必须能够准确指定链接的目录和库(两个缓存变量:LIBRARY_PATHS和LIBRARIES)。因为我在最顶层的CMakeLists.txt中创建了目标,然后使用各种target_*
命令来构建它们,所以我不能使用link_directories
,如果目标已经不能使用find_library
已定义。
在定义目标后,是否有一种简单的方法可以指定要包含在链接中的目录?我正在考虑定义一个宏,它接受LIBRARY_PATHS和LIBRARIES并使用{{1}}将LIBRARIES转换为具有完整路径的库列表。然而,这样的黑客似乎违背了CMake理念,所以我想知道是否有更好的方法。
答案 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()
目标。这种方法在Find
和Config
- 模块中非常常见。这可能会让你开始:
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