【问题标题】:Is there a way for CMake to utilize dependencies generated by `swig -MM`?CMake 有没有办法利用“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 -MMit 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


【解决方案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" 进行了讨论。票仍然开放(已重新开放),因此请随时在此处添加您的支持、建议或测试结果。

【讨论】:

    猜你喜欢
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 2023-04-10
    • 2011-06-10
    • 2012-06-24
    相关资源
    最近更新 更多