统一CMake的FIND_PACKAGE

时间:2017-02-20 13:57:59

标签: cmake

从CMake的FIND_PACKAGE获取包含和库路径时,您是否知道获得统一输出术语的技巧?

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

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

1 个答案:

答案 0 :(得分:1)

将我的评论转化为答案

为了避免需要知道包含路径,库等依赖关系及其变量符号,现代find_package的实现确实提供了IMPORTED目标,如Foo::Foo。但这是 - 正如@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查找模块结果测试了代码。