2017-02-20 80 views
1

从CMake的FIND_PACKAGE获取包含和库路径时,你知道一个技巧来获得统一的输出术语吗?Unifying CMake的FIND_PACKAGE

有时它是FOO_INCLUDE。有时候它是FOO_INCLUDE_PATH。等

例如,我想找到一种方法来确保FOO_INCLUDE和FOO_LIB在FOO_FOUND设置为TRUE后调用FIND_PACKAGE后总是定义。

+1

现代查找包的实现确实提供了像'Foo :: Foo'这样的IMPORTED目标(以避免需要知道包含路径,库等依赖关系及其变量符号)。 – Florian

+0

谢谢你的回答弗洛里安。你能给我一个这样一个导入目标的例子吗?据我了解CMake的FIND_PACKAGE函数的文档,这些目标应该在FindFOO.cmake文件中定义,但并非总是如此(例如FindMPI)。因此,说通过输入目标可以达到统一可能是真实的,但是现在认为它是统一的是错误的。因此,它不能解决我的问题。 – Aleph

+1

除了'FOO_FOUND'和一些特殊的“查找”变量外,CMake **不强制执行'Find'脚本来设置特定的变量**。所以你的问题的答案是'不,没有统一的方式。'然而,你可以编写自己的函数/宏来处理'find_package'的后处理结果。在该函数中,您可以检查常见模式(* FOO_INCLUDE *,* FOO_INCLUDE_PATH *,* FOO_INCLUDE_DIR *等)并将所需变量设置为适当的值。 – Tsyvarev

回答

0

谈到我的意见为答案

为了避免需要知道include路径,图书馆等的依赖和他们的变量符号现代find_package的实施确实提供了像Foo::FooIMPORTED目标。但是,正如@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查找模块结果进行了测试。

+0

非常感谢!我会在今天测试您的解决方案并在此处作出回复。 – Aleph