【问题标题】:SWIG and CMake: make use of information provided by `target_include_directories()`SWIG 和 CMake:利用 `target_include_directories()` 提供的信息
【发布时间】:2016-09-09 08:55:05
【问题描述】:

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

例如通过写作

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)

否则.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 时才有效
  • 创建对包含目录中的所有头文件的依赖项

【问题讨论】:

  • 如有关 target_include_directories 的文档中所述,当与 PUBLIC 关键字一起使用时,它会填充目标的 INTERFACE_INCLUDE_DIRECTORIES。因此,您可以通过阅读此属性来提取信息。
  • +1 因为它对include_directories 有帮助,但我仍然需要SWIG_MODULE_*_EXTRA_DEPS 的冗余信息

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


【解决方案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 中

【讨论】:

  • 这确实可以解决include_directories 的问题 - 但您仍然需要为SWIG_MODULE_*_EXTRA_DEPS 部分发明一些东西。但是由于我明确询问如何提取该信息,您当然回答了我的问题。我会在修改get_property 的同时保持问题开放..
  • @frans 啊,我明白了。那些EXTRA_DEPS,可以通过算法获得吗?例如,通过使用编译器对某些源文件运行依赖扫描?
  • 目前我正在尝试编写一个迭代 INTERFACE_INCLUDE_DIRECTORIES 的 CMake 宏 - 我会将结果添加到我的问题中。
  • 我只是希望以前有人这样做过 :)
  • @frans 是的,我在 CMAKE 上花了很多时间希望同样的事情。我正在逐步构建自己的有用宏集合,以使 CMakeLists.txt 文件易于遵循和维护...
猜你喜欢
  • 1970-01-01
  • 2014-12-02
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 2022-07-10
相关资源
最近更新 更多