使用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 中