【发布时间】: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 时生成的源不存在的问题。目前,问题似乎仍未解决。
所以我把这个问题提交给了出色的 StackOverflow 社区:当前的 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将不是是一个好主意.因为如果缺少依赖项,您会收到“找不到文件”错误消息。
标签: python c++ cmake dependencies swig