如何使用 VS Code 和 MSVC 正确编译 wxWidgets?

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

我目前正在使用 wxWidgets 为基于控制台的 C++ 应用程序开发 GUI 前端(我决定不与 Qt 的许可条件共舞)。到目前为止,我一直在 VS Code 中完成此应用程序的所有工作,因此我尝试调整提供的 docs/msw/install.md 文件中详细说明的说明,但没有成功。作为一种参考点,我正在尝试在 wxWidget 网站here 上编译“Hello World”示例代码(复制粘贴到我自己的文件中)。每当我尝试编译时,都会收到大量 LNK2019 和 LNK2001 错误(实际上有数百个)。这是前 3 个供参考:

main.obj : error LNK2019: unresolved external symbol "void __cdecl wxOnAssert(char const *,int,char const *,char const *,char const *)" (?wxOnAssert@@YAXPBDH000@Z) referenced in function "public: __thiscall wxEventFunctorMethod<class wxEventTypeTag<class wxCommandEvent>,class MyFrame,class wxCommandEvent,class MyFrame>::wxEventFunctorMethod<class wxEventTypeTag<class wxCommandEvent>,class MyFrame,class wxCommandEvent,class MyFrame>(void (__thiscall MyFrame::*)(class wxCommandEvent &),class MyFrame *)" (??0?$wxEventFunctorMethod@V?$wxEventTypeTag@VwxCommandEvent@@@@VMyFrame@@VwxCommandEvent@@V2@@@QAE@P8MyFrame@@AEXAAVwxCommandEvent@@@ZPAV1@@Z)
main.obj : error LNK2019: unresolved external symbol "struct wxPrivate::UntypedBufferData * __cdecl wxPrivate::GetUntypedNullData(void)" (?GetUntypedNullData@wxPrivate@@YAPAUUntypedBufferData@1@XZ) referenced in function "protected: static struct wxScopedCharTypeBuffer<char>::Data * __cdecl wxScopedCharTypeBuffer<char>::GetNullData(void)" (?GetNullData@?$wxScopedCharTypeBuffer@D@@KAPAUData@1@XZ)
main.obj : error LNK2019: unresolved external symbol "class wxMBConv * __cdecl wxGet_wxConvLibcPtr(void)" (?wxGet_wxConvLibcPtr@@YAPAVwxMBConv@@XZ) referenced in function "class wxMBConv & __cdecl wxGet_wxConvLibc(void)" (?wxGet_wxConvLibc@@YAAAVwxMBConv@@XZ)

以(目录审查)结尾:

...\main.exe : fatal error LNK1120: 339 unresolved externals

我尝试寻找任何关于我应该如何执行此操作的线索,但我找到的任何资源似乎要么适用于 GCC 或 Visual Studio,要么根本不是我遇到的问题。所以,我的问题是,在 VS Code 和 MSVC (cl.exe) 编译器中编译 wxWidgets 应用程序的“正确”方法是什么?我应该如何在编译器标志中设置包含路径和链接器路径?是否有任何我直接丢失的预处理器指令?

这就是我目前设置编译器选项的方式:

tasks.json

{
    "tasks": [
        {
            "type": "shell",
            "label": "C/C++: cl.exe build active file",
            "command": "cl.exe",
            "args": [
                "/Zi",
                "/EHsc",
                "/nologo",
                "/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",
                "/IC:\\wxWidgets-3.2.2.1\\lib\\vc_lib\\mswu",
                "/IC:\\wxWidgets-3.2.2.1\\include",
                "${file}",
                "/link",
                "/LIBPATH:C:\\wxWidgets-3.2.2.1\\lib\\vc_lib"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$msCompile"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0",
    "windows": {
        "options": {
            "shell": {
                "executable": "cmd.exe",
                "args": [
                    "/C",
                    "\"C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/Tools/VsDevCmd.bat\"",
                    "&&"
                ]
            }
        }
    }
}

c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:/wxWidgets-3.2.2.1/include",
                "C:/wxWidgets-3.2.2.1/lib/vc_lib/mswu"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE",
                "NDEBUG"
            ],
            "windowsSdkVersion": "10.0.19041.0",
            "compilerPath": "cl.exe",
            "cStandard": "c17",
            "intelliSenseMode": "windows-msvc-x64"
        }
    ],
    "version": 4
}

不可否认,这些文件放在一起有点草率。它们只是旧的一次性项目的改造遗迹,但到目前为止,它们已经很好地实现了它们的目的。据我所知,tasks.json中的包含路径和库路径应该是正确的,但这是我第一次使用wxWidgets(要温柔),而且我直接使用MSVC标志的经验非常有限。我尝试对路径进行的任何调整都会产生不同的错误(显然),例如无法找到wxbase32u.lib,但我的印象是可以通过......好吧......实际上使用正确的路径来修复。从这里开始,我就陷入困境了。

我确实按照说明编译了自己的二进制文件,包括调试和发布(旁注:我实际上尝试在这里使用发布二进制文件),并且我确实成功编译并运行了 wxWidgets 源提供的“最小”示例代码,所以我很确定二进制文件本身没有问题。我尝试剖析用于示例的 Makefile 以获取提示,但格式确实让我感到困惑,并且在尝试将其重构到 VS Code 的配置中时我会更加不知所措。

现在,我确实意识到我可以相当轻松地,只需一点时间,将我的应用程序开发迁移到 Visual Studio 或弄清楚如何将所有内容放入 Makefile 或使用 GCC,但我将尝试使这是一个了解链接器的机会。因此,如果说有人无法使用 VS Code 和 cl.exe 之外的任何编辑器/编译器组合,或者太顽固而无法切换到其他东西,他们怎么可能去做呢?

c++ visual-studio-code visual-c++ wxwidgets
1个回答
0
投票

早上以全新的心态回到这个问题后,我发现了我的问题。好吧,我实际上遇到了几个问题。为了供其他人参考,我保留原始帖子不变。

首先,也是最重要的,实际上开始这篇文章的问题是:我在 tasks.json 中有一个重大拼写错误。通向

C:\\wxWidgets-3.2.2.1\\lib\\vc_lib\\mswu
的包含路径应该是
C:\\wxWidgets-3.2.2.1\\include\\msvc
。这并不是我误解了 wxWidgets 的设置说明,而是我太累了,手动输入了该路径几十次,而不是仅仅复制粘贴。

但是,这在 LNK2019/2001 错误之上生成了一组新的错误,即 LNK4286、LNK4217 和(最重要的)一堆 LNK2038 错误:

error LNK2038: mismatch detected for 'RuntimeLibrary' : value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease' in main.obj

我花了 5 秒钟将

/MD
添加到 tasks.json 中的标志,现在它编译得很好。

现在,为什么链接器期望动态发布而不是静态发布,即使我使用静态库,我也不知道。我在计算机上移动了最终的 .exe,并混淆了库路径,没有运行时问题,据我所知,它的行为就像静态链接库。因此,如果有人知道链接器为何会出现这样的行为,请随时发表评论。与此同时,由于我能够解决我的问题,我接受这个答案。

© www.soinside.com 2019 - 2024. All rights reserved.