CMake 有没有办法利用“swig -MM”生成的依赖项?
Posted
技术标签:
【中文标题】CMake 有没有办法利用“swig -MM”生成的依赖项?【英文标题】:Is there a way for CMake to utilize dependencies generated by `swig -MM`? 【发布时间】:2015-09-09 12:55:46 【问题描述】:SWIG 使用接口 (.i) 文件以所需的目标语言(Python、Java、C# 等)从您的 C/C++ 生成包装器代码,该文件指定要包装的输入代码,如 SWIG tutorial 中所述。 CMake 可用于调用 swig,以便从 .i 接口生成目标代码,如SWIG documentation 中所述。
但是,使用这种方法,CMake 只会为接口文件本身生成依赖关系,而不会为其包含的源文件生成依赖关系。可以manually add dependencies,但 SWIG 可以使用 -MM 选项自动生成依赖项,我希望 CMake 使用这些。
有一个 commit to CMake 使用了由 swig -MM
但 it was later reverted 生成的依赖项,因为在调用 swig 时生成的源不存在的问题。目前,问题似乎仍未解决。
所以我把这个问题提交给了出色的 *** 社区:当前的 CMake 有没有办法在接口文件(a ) 不包括生成的代码(例如 config.h),而 (b) 包括生成的代码?
这是一个可用于实验的小示例 (download it here)。
// swig_example.h
int foo(int n);
//*** comment this declaration after compiling once to witness dependency failure ***/
int another_function();
// swig_example.cpp
#include "swig_example.h"
int another_function() return -1;
int foo(int n)
if (n <= 1) return 1;
else return another_function();
// swig_example: example.i
%module example
%
#include "swig_example.h"
%
%include "swig_example.h"
# swig_example: CMakeLists.txt
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE($SWIG_USE_FILE)
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES($PYTHON_INCLUDE_PATH)
INCLUDE_DIRECTORIES($CMAKE_CURRENT_SOURCE_DIR)
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
#add manual dependencies (must be called before SWIG_ADD_MODULE)
#SET(SWIG_MODULE_example_EXTRA_DEPS $CMAKE_SOURCE_DIR/swig_example.h)
SWIG_ADD_MODULE(example python example.i swig_example.cpp)
SWIG_LINK_LIBRARIES(example $PYTHON_LIBRARIES)
编译一次,然后注释another_function
的声明,再次编译。因为没有重新生成 swig 接口,所以尝试编译 examplePYTHON_wrap.cxx 时发生错误。
examplePYTHON_wrap.cxx:3220:17: error: use of undeclared identifier 'another_function'
result = (int)another_function();
取消注释 CMakeLists.txt 的 add manual dependencies 行,界面将正确重新生成。但是,我希望它使用从 swig -MM
生成的依赖项来工作,而不是需要手动指定依赖项。
$ swig -python -MM -c++ ../example.i
../example_wrap.cxx: \
../example.i \
../swig_example.h \
【问题讨论】:
我想你正在搜索这个:CMake: adding automatic handling of dependencies for swig-generated modules。我不认为SWIG_GET_WRAPPER_DEPENDENCIES()
重新回到了官方分支,但是可以在here 找到源代码。
您是否因为在第一次尝试时收到“找不到文件”错误而对swig_example.h
进行评论?如果是,您可以通过告诉 CMake 将生成 swig_example.h
文件来保持 SET(SWIG_MODULE_example_EXTRA_DEPS ...)
行不注释。在您的SWIG_ADD_MODULE()
调用之后添加以下内容:set_source_files_properties($CMAKE_SOURCE_DIR/swig_example.h PROPERTIES GENERATED 1)
@Florian 这些都是有用的注释。我已经在我的问题中提到了恢复的提交,它在技术上处理了上面的案例 a)。关于生成的属性,这是我不知道的,当然很有用。是否可以根据 CMake 生成的输入将现已失效的 SWIG_GET_WRAPPER_DEPENDENCIES 修改为自身?
当我查看0012307: regression in 2.8.5 rc2: UseSWIG.cmake broken 上的讨论时,我不相信SWIG_GET_WRAPPER_DEPENDENCIES()
实际上被破坏了,它只是引入了一个新限制:“这只是要求所有 swig 模块的标头都存在”在致电SWIG_ADD_MODULE()
之前。你可以试试SWIG_GET_WRAPPER_DEPENDENCIES()
代码吗?根据this 的补丁,你只需调用SWIG_ADD_MODULE()
,它就会为你调用SWIG_GET_WRAPPER_DEPENDENCIES()
。
并且 - 补充我的最后一条评论并与我 2 天前的评论相矛盾 - 将 SWIG_MODULE_example_EXTRA_DEPS
中的所有文件设置为 GENERATED
将不是是一个好主意.因为如果缺少依赖项,您会收到“找不到文件”错误消息。
【参考方案1】:
把我的 cmets 变成答案
我不认为 - 如果您想自动执行此操作,例如想要使用swig -MM
- 这可以在不更改UseSWIG.cmake
代码的情况下完成。
当我查看为什么您之前链接的尝试被恢复时 - 即在 "0012307: regression in 2.8.5 rc2: UseSWIG.cmake broken" 上的讨论 - 我不相信 SWIG_GET_WRAPPER_DEPENDENCIES()
实际上被打破了它只是引入了一个新的限制:“这只是要求所有在调用 SWIG_ADD_MODULE()
之前存在 swig 模块的标头。
所以我建议添加-ignoremissing
SWIG 选项,但这需要进一步测试。
更新(2017 年 4 月)
在 CMake 版本 3.8.0 中,有一个适用于 makefile
generators 的修复程序 "Automatically scan dependencies of SWIG files for Makefile generators"。
参考
关于如何解决这个问题的一般性讨论(包括我的建议)在"Issue #4147: [MODULES][UseSWIG] Use swig to compute dependencies" 进行了讨论。票仍然开放(已重新开放),因此请随时在此处添加您的支持、建议或测试结果。
【讨论】:
以上是关于CMake 有没有办法利用“swig -MM”生成的依赖项?的主要内容,如果未能解决你的问题,请参考以下文章
CMake 错误:找不到 SWIG(缺少:SWIG_DIR)