从CMake的FIND_PACKAGE获取包含和库路径时,你知道一个技巧来获得统一的输出术语吗?Unifying CMake的FIND_PACKAGE
有时它是FOO_INCLUDE。有时候它是FOO_INCLUDE_PATH。等
例如,我想找到一种方法来确保FOO_INCLUDE和FOO_LIB在FOO_FOUND设置为TRUE后调用FIND_PACKAGE后总是定义。
从CMake的FIND_PACKAGE获取包含和库路径时,你知道一个技巧来获得统一的输出术语吗?Unifying CMake的FIND_PACKAGE
有时它是FOO_INCLUDE。有时候它是FOO_INCLUDE_PATH。等
例如,我想找到一种方法来确保FOO_INCLUDE和FOO_LIB在FOO_FOUND设置为TRUE后调用FIND_PACKAGE后总是定义。
谈到我的意见为答案
为了避免需要知道include路径,图书馆等的依赖和他们的变量符号现代find_package
的实施确实提供了像Foo::Foo
IMPORTED
目标。但是,正如@Tsyvarev所评论的那样 - 远远没有通过所有CMake的find modules统一。
所以推广的CMake's Sample Find Module implementation,你可以用一个覆盖find_package()
宏版本类似下面的统一你find_package()
电话:
cmake_minimum_required(VERSION 3.2)
project(UnifiedFindPackage)
macro(unify_vars _result)
set(${_result} "")
foreach(_i IN ITEMS ${ARGN})
if (${_i})
list(APPEND ${_result} "${${_i}}")
endif()
endforeach()
endmacro()
macro(find_package _name)
_find_package(${_name} ${ARGN})
if (${_name}_FOUND AND NOT TARGET ${_name}::${_name})
add_library(${_name}::${_name} STATIC IMPORTED GLOBAL)
unify_vars(_var ${_name}_LIBRARY ${_name}_LIB)
if (_var)
set_target_properties(${_name}::${_name} PROPERTIES IMPORTED_LOCATION "${_var}")
endif()
if (${_name}_LIBRARY_RELEASE)
set_property(TARGET ${_name}::${_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(${_name}::${_name} PROPERTIES IMPORTED_LOCATION_RELEASE "${${_name}_LIBRARY_RELEASE}")
endif()
if (${_name}_LIBRARY_DEBUG)
set_property(TARGET ${_name}::${_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(${_name}::${_name} PROPERTIES IMPORTED_LOCATION_DEBUG "${${_name}_LIBRARY_DEBUG}")
endif()
if (${_name}_LIBRARIES)
set_property(TARGET ${_name}::${_name} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${${_name}_LIBRARIES}")
endif()
unify_vars(_var ${_name}_INCLUDE_DIRS ${_name}_INCLUDE_PATH)
if (_var)
set_property(TARGET ${_name}::${_name} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${_var}")
endif()
unify_vars(_var ${_name}_COMPILE_FLAGS ${_name}_DEFINITIONS)
if (_var)
set_property(TARGET ${_name}::${_name} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${_var}")
endif()
endif()
endmacro()
find_package(MPI REQUIRED)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} MPI::MPI)
这应该只展示一个可能的统一,可以按需要的基础上延长。
编辑:把它变成社区维基答案。请随时贡献。
该代码在本示例中用MPI
查找模块结果进行了测试。
非常感谢!我会在今天测试您的解决方案并在此处作出回复。 – Aleph
现代查找包的实现确实提供了像'Foo :: Foo'这样的IMPORTED目标(以避免需要知道包含路径,库等依赖关系及其变量符号)。 – Florian
谢谢你的回答弗洛里安。你能给我一个这样一个导入目标的例子吗?据我了解CMake的FIND_PACKAGE函数的文档,这些目标应该在FindFOO.cmake文件中定义,但并非总是如此(例如FindMPI)。因此,说通过输入目标可以达到统一可能是真实的,但是现在认为它是统一的是错误的。因此,它不能解决我的问题。 – Aleph
除了'FOO_FOUND'和一些特殊的“查找”变量外,CMake **不强制执行'Find'脚本来设置特定的变量**。所以你的问题的答案是'不,没有统一的方式。'然而,你可以编写自己的函数/宏来处理'find_package'的后处理结果。在该函数中,您可以检查常见模式(* FOO_INCLUDE *,* FOO_INCLUDE_PATH *,* FOO_INCLUDE_DIR *等)并将所需变量设置为适当的值。 – Tsyvarev