wxWidgets 未使用来自 VSCode (MSVC) 的 Cmake 进行链接

wxWidgets not linking using Cmake from VSCode (MSVC)

问题

我在构建我的项目时遇到 linker 错误。该项目可以轻松找到 wxWidgets headers。我查看了 wxWidgets 最小示例并重新创建它以验证我的源代码中的 build 是否正常工作。我在 VSCode 中使用 cmake 使用 cmake 扩展来执行 build。

wxWidgets cmake 生成正常,wxwidgets 的 build 似乎运行良好。我正在使用 Visual Studio 2022 amd64 工具集进行编译。 (我只为编译器安装了VS2022社区版)。

它看起来像是在为库创建 uilding DLL。我更喜欢静态库,但对于最初的 运行 我认为这并不重要。我link我的申请是wx::netwx::corewx::base推荐的。我认为这会在我去 build 时处理 linking。

当我使用 wxWidgets 库构建ui我的整个应用程序时,我得到了这些 linker 错误。 我在这里做错了什么?我显然没有正确配置一些东西来找到库,但我在这里有点难过。

链接器错误

[build] ProjectName.obj : error LNK2001: unresolved external symbol "protected: static class wxAppConsole * (__cdecl* wxAppConsoleBase::ms_appInitFn)(void)" -snipped-
[build] ProjectName.obj : error LNK2001: unresolved external symbol "protected: static class wxAppConsole * wxAppConsoleBase::ms_appInstance" -snipped-
[build] MainWindow.obj : error LNK2001: unresolved external symbol "void (__cdecl* wxTheAssertHandler)(class wxString const &,int,class wxString const &,class wxString const &,class wxString const &)"-snipped-
[build] MainWindow.obj : error LNK2001: unresolved external symbol "bool wxTrapInAssert" (?wxTrapInAssert@@3_NA) -snipped-
[build] MainWindow.obj : error LNK2001: unresolved external symbol "class wxMBConv * wxConvLibcPtr" (?wxConvLibcPtr@@3PEAVwxMBConv@@EA) -snipped-
[build] MainWindow.obj : error LNK2001: unresolved external symbol "public: static unsigned __int64 const wxString::npos" (?npos@wxString@@2_KB)-snipped-
[build] MainWindow.obj : error LNK2001: unresolved external symbol "class wxSize const wxDefaultSize" (?wxDefaultSize@@3VwxSize@@B)-snipped-
[build] MainWindow.obj : error LNK2001: unresolved external symbol "class wxPoint const wxDefaultPosition" (?wxDefaultPosition@@3VwxPoint@@B)-snipped-
[build] MainWindow.obj : error LNK2001: unresolved external symbol "char const * const wxFrameNameStr" (?wxFrameNameStr@@3QBDB)-snipped-
[build] C:\path\to\executable\ProjectName.exe : fatal error LNK1120: 9 unresolved externals -snipped-
[build] Build finished with exit code 1 

项目布局

非常基本的项目布局。我正在构建一个 GUI 应用程序,并且我在逻辑上分离出 ui 源代码。

这基本上是对最小 wxWidgets 示例的重新创建,其中您有一个入口点(Projectname.hpp 和 ProjectName.cpp 提供了这个)和一个主要的 window/frame(MainWindow.hpp MainWindow.cpp 提供这个)。 ProjectName 应用程序将执行 wxIMPLEMENT_APP(ProjectName) 并将保存指向 MainWindow 的指针。使用 OnInit 函数显示 MainWindow。

ProjectName/
    build/
    external/
        wxWidgets-3.1.6/
        -CMakeLists.txt
    source/
        ui/
            -MainWindow.hpp
            -MainWindow.cpp
        -ProjectName.hpp
        -ProjectName.cpp
    -CMakeLists.txt

我已经使用他们的 cmake instructions 编译了 wxWidgets 库,以便在 cmake 中使用子目录,这样我就可以将它添加到我的项目中。这是CMakeLists.txt的

的内容

项目名称CMakeLists.txt

cmake_minimum_required(VERSION 3.23)

set(MAJOR 0)
set(MINOR 0)
set(PATCH 1)

#Setup Project
project(ProjectNameProject VERSION ${MAJOR}.${MINOR}.${PATCH}
                           DESCRIPTION "ProjectName Descrip"
                           LANGUAGES CXX)

add_executable(ProjectName WIN32 ${PROJECT_SOURCE_DIR}/source/ProjectName.cpp 
                             ${PROJECT_SOURCE_DIR}/source/ui/MainWindow.cpp)

target_include_directories(ProjectName PRIVATE ${PROJECT_SOURCE_DIR}/source)
target_include_directories(ProjectName PRIVATE ${PROJECT_SOURCE_DIR}/source/ui)

target_link_libraries(ProjectName PRIVATE wx::net wx::core wx::base)

add_subdirectory(${CMAKE_SOURCE_DIR}/external)

ProjectName/externals CMakeLists.txt

cmake_minimum_required(VERSION 3.23)
add_subdirectory(${CMAKE_SOURCE_DIR}/external/wxWidgets-3.1.6)

更新

我更改了用于加载共享库 (DLL) 的 Cmake 选项,并将其设置为关闭。完成后,它会生成一个静态库 (LIB)uilds。这似乎解决了我的 linking 问题。

根据 Igor 的建议,我再次查看了最小样本 CMakeLists.txt 并注意到他们将以下行用于 linking

target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES}) 

也许我的行(下面)是静态 link 的方法,并且不适用于 DLL?

target_link_libraries(ProjectName PRIVATE wx::net wx::core wx::base)

如果有人能帮助我理解为什么要静态修复它,我会 100% 接受这个答案。

我更改了用于构建共享库 (DLL) 的 Cmake 选项并将其设置为关闭。完成后,它会构建一个静态库 (LIB)。这似乎解决了我的链接问题。

不幸的是,我没有看到任何人能够插话来帮助理解为什么这是解决方案,但我将 select 这是对未来其他人的答案。

如果我看到任何更新回答了“为什么”这个问题,我会接受他们的回答。