Swig 在 Windows 上的调试模式下使用连字符定义 SWIG_init,导致自动生成的 C++ 代码无效

问题描述 投票:0回答:0

在 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)

...似乎可以解决问题。我还不能确定,因为我的构建后来仍然失败,似乎是一个独立的、不相关的问题。

python c++ visual-studio swig
© www.soinside.com 2019 - 2024. All rights reserved.