CMake 有没有办法利用 `swig -MM` 生成的依赖项?
Is there a way for CMake to utilize dependencies generated by `swig -MM`?
SWIG 使用指定的接口 (.i) 文件以所需的目标语言(Python、Java、C# 等)从您的 C/C++ 生成包装代码要按照 SWIG tutorial. CMake can be used to call swig in order to generate target code from the .i interface, as described in the SWIG documentation.
中所述进行包装的输入代码
但是,使用此方法CMake 只会为接口文件本身生成依赖项,而不会为其包含的源文件生成依赖项。一个可以 manually add dependencies,但是 SWIG 可以使用 -MM 选项自动生成依赖项,我希望这些可以被 CMake 使用。
由于调用 swig 时不存在的生成源存在问题,因此出现 commit to CMake that utilized dependencies generated by swig -MM
but it was later reverted。这个时候问题好像还没有解决
所以我把这个问题提交给出色的 Whosebug 社区:当前的 CMake 是否有办法利用 swig -MM
[ 生成的依赖项=42=] 当接口文件 (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 \
将我的评论变成答案
我不认为 - 如果您想自动执行此操作,例如想利用 swig -MM
- 这可以在不更改 UseSWIG.cmake
代码的情况下完成。
当我查看为什么您之前链接的尝试被还原时 - 即关于 "0012307: regression in 2.8.5 rc2: UseSWIG.cmake broken" 的讨论 - 我不相信 SWIG_GET_WRAPPER_DEPENDENCIES()
实际上被打破了它只是引入了一个新的限制: "this simply require all headers for swig module to be present" 在调用 SWIG_ADD_MODULE()
之前。
所以我建议添加 -ignoremissing
SWIG 选项,但这需要进一步测试。
更新(2017 年 4 月)
CMake 版本 3.8.0 有一个修复 "Automatically scan dependencies of SWIG files for Makefile generators" that works for makefile
generators。
参考
有关如何解决此问题(包括我的建议)的一般性讨论在 "Issue #4147: [MODULES][UseSWIG] Use swig to compute dependencies" 中进行了讨论。工单仍然开放(已重新开放),所以请随时在那里添加您的支持、建议或测试结果。
SWIG 使用指定的接口 (.i) 文件以所需的目标语言(Python、Java、C# 等)从您的 C/C++ 生成包装代码要按照 SWIG tutorial. CMake can be used to call swig in order to generate target code from the .i interface, as described in the SWIG documentation.
中所述进行包装的输入代码但是,使用此方法CMake 只会为接口文件本身生成依赖项,而不会为其包含的源文件生成依赖项。一个可以 manually add dependencies,但是 SWIG 可以使用 -MM 选项自动生成依赖项,我希望这些可以被 CMake 使用。
由于调用 swig 时不存在的生成源存在问题,因此出现 commit to CMake that utilized dependencies generated by swig -MM
but it was later reverted。这个时候问题好像还没有解决
所以我把这个问题提交给出色的 Whosebug 社区:当前的 CMake 是否有办法利用 swig -MM
[ 生成的依赖项=42=] 当接口文件 (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 \
将我的评论变成答案
我不认为 - 如果您想自动执行此操作,例如想利用 swig -MM
- 这可以在不更改 UseSWIG.cmake
代码的情况下完成。
当我查看为什么您之前链接的尝试被还原时 - 即关于 "0012307: regression in 2.8.5 rc2: UseSWIG.cmake broken" 的讨论 - 我不相信 SWIG_GET_WRAPPER_DEPENDENCIES()
实际上被打破了它只是引入了一个新的限制: "this simply require all headers for swig module to be present" 在调用 SWIG_ADD_MODULE()
之前。
所以我建议添加 -ignoremissing
SWIG 选项,但这需要进一步测试。
更新(2017 年 4 月)
CMake 版本 3.8.0 有一个修复 "Automatically scan dependencies of SWIG files for Makefile generators" that works for makefile
generators。
参考
有关如何解决此问题(包括我的建议)的一般性讨论在 "Issue #4147: [MODULES][UseSWIG] Use swig to compute dependencies" 中进行了讨论。工单仍然开放(已重新开放),所以请随时在那里添加您的支持、建议或测试结果。