【发布时间】: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