SWIG和CMake:利用`target_include_directories()`提供的信息

时间:2016-05-13 08:42:14

标签: c++ cmake include swig include-path

使用CMake 2.8+,您可以避免使用target_include_directories()以冗余方式设置包含目录。

E.g。通过写作

add_libary(mylib SHARED ${SOURCES})
target_include_directories(mylib PUBLIC ./include)

..您只需链接mylib即可向目标添加所需的包含文件夹。

但是当我必须使用不使用此功能的CMake模块时,如何才能使用这些信息呢? (在我的情况下是SWIG)

当我配置SWIG项目时,我目前必须硬编码很多信息:

set(SWIG_MODULE_${PYTHON_MODULE_NAME}_EXTRA_DEPS
    "../long/relative/path/1/include/some/header1.h"
    "../long/relative/path/1/include/some/header2.h"
    "../long/relative/path/2/include/some/header1.h"
    "../long/relative/path/2/include/some/header2.h")

我还必须使用旧式include_directories()来让swig生成器知道它需要知道的内容:

include_directories(
    "../long/relative/path/1/include
    "../long/relative/path/2/include)

否则%include文件中的.i语句将不再起作用。

当然我可以设置包含路径的变量但是我会提供我想要摆脱的信息..

有没有办法从目标中提取目录信息,或者(当然更好)使SWIG CMake模块正确使用它?

我目前的解决方案:

使用一些(非常漂亮的)CMake魔法,您可以自动列出来自库的接口部分的所有头文件并设置包含目录:

function(swig_add_library_dependencies swig_module library_names)
    foreach(library_name ${library_names})
        get_property(LIBRARY_INCLUDES 
                     TARGET ${library_name}
                     PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
        foreach(INCLUDE_PATH ${LIBRARY_INCLUDES})
            include_directories(${INCLUDE_PATH})
            file(GLOB_RECURSE header_files "${INCLUDE_PATH}/*.h")
            list(APPEND SWIG_MODULE_${swig_module}_EXTRA_DEPS ${header_files})
            # export variable to parent scope
            set(SWIG_MODULE_${swig_module}_EXTRA_DEPS 
              ${SWIG_MODULE_${swig_module}_EXTRA_DEPS} PARENT_SCOPE)
        endforeach()
    endforeach()
endfunction()

这样使用:

swig_add_library_dependencies(<swig_module_name> "library1;library2")

或像这样离散:

swig_add_library_dependencies(<swig_module_name> library1)
swig_add_library_dependencies(<swig_module_name> library2)

缺点:

  • 使用GLOB_RECURSE
  • 仅在正确使用target_include_directories时才有效
  • 为包含目录
  • 中的所有头文件创建依赖关系

1 个答案:

答案 0 :(得分:1)

查看get_property的文档:

https://cmake.org/cmake/help/v3.0/command/get_property.html?highlight=get_property

你会做这样的事情:

get_property(MY_INCLUDES TARGET my_target PROPERTY INTERFACE_INCLUDE_DIRECTORIES)

获取接口包含目标my_target中的目录并将它们存储在变量MY_INCLUDES