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

SWIG and CMake: make use of information provided by `target_include_directories()`

本文关键字:信息 directories include CMake 利用 target SWIG      更新时间:2023-10-16

使用CMake 2.8+,您可以通过使用target_include_directories()来避免冗余地设置include目录。

例如,通过写入

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

您只需要链接到mylib,就可以将所需的include文件夹添加到您的目标中。

但是,当我必须使用尚未使用此功能的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)

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

当然,我可以设置包含路径的变量,但之后我会提供我想去掉的信息。。

有没有办法从目标中提取目录信息,或者(当然更好)让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的情况下才有效
  • 创建对include目录中所有头文件的依赖项

查看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获取接口include目录,并将它们存储在变量my_INCLUDES 中