在 Windows 上,我使用 cmake、swig 和 visual studio 为我的库构建一个 python 包装器。在发布模式下一切正常。在调试中,生成的代码包含这一行:
#define SWIG_init PyInit__myproject-gd
所以 Debug 附加了 Release 中没有的
-gd
。构建继续使用该符号作为函数名称,这是无效的 C++,因为标识符中不允许使用连字符。所以这条线......
SWIG_init(void) {
...导致构建失败并显示此错误消息:
C:\xxx\myprojectPYTHON_wrap.cxx(807935,1): error C2143: syntax error: missing ';' before '-'
C:\xxx\myprojectPYTHON_wrap.cxx(807935,1): error C2059: syntax error: '-'
C:\xxx\myprojectPYTHON_wrap.cxx(807935,17): error C2143: syntax error: missing ';' before '{'
C:\xxx\myprojectPYTHON_wrap.cxx(807935,17): error C2447: '{': missing function header (old-style formal list?)
我该如何解决这个问题?
编辑:
在release中,cmake发出的swig命令包括:
-interface _myproject
对于调试它说:
-interface _myproject-gd
所以在由 swig 自动生成的 C++ 代码中,我在发布时得到了一个名为
_myproject
的函数,但在调试中得到了_myproject-gd
。
在此文件中:
C:\Program Files\CMake\share\cmake-3.26\Modules\UseSWIG.cmake
我明白了:
# This makes sure that the name used in the proxy code
# matches the library name created by CMake
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-interface" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
我已经调试了那个 cmake 生成器表达式,当然它在发布时评估为
_myproject
,在调试中评估为 _myproject-gd
。
在此文件中:
C:\repos\myproject\cmake\commonSettings.cmake
我明白了:
if("${MSVC_RUNTIME}" STREQUAL "static")
set(CMAKE_DEBUG_POSTFIX "gd")
else()
set(CMAKE_DEBUG_POSTFIX "-gd")
endif()
删除连字符可以修复编译错误,但会破坏其他内容。我不确定,但在我看来,swig 的 cmake 配置滥用了一个 cmake 变量,该变量旨在用于文件 (lib) 名称,而是将其合并到 C++ 函数的名称中。因此,您向该 cmake 变量添加了一个连字符,认为您的 lib 名称将包含一个连字符,然后您的自动生成的 swig 代码中断了。我可能是错的,我还在挖掘。
编辑#2:
我注意到 UseSWIG.cmake 仅在尚未设置
-interface
标志的情况下设置它。所以,在调用swig_add_library
之前,如果我做这样的事情......
list (APPEND SWIG_MODULE_myproject_EXTRA_FLAGS "-interface" _myproject)
...似乎可以解决问题。我还不能确定,因为我的构建后来仍然失败,似乎是一个独立的、不相关的问题。