无法编译wxWidgets Hello World

Cannot compile wxWidgets Hello World

本文关键字:Hello World wxWidgets 编译      更新时间:2023-10-16

所以,我试图编译wxWidgets提供的hello-world示例,但没有成功。我将一步一步地解释我所做的事情,直到我陷入困境。

编译wxWidgets

  1. 首先,我选择的编译器是MinGw-w64,由于wxWidgets建议从源代码(从wxWidget下载)构建他们的库,我决定使用CMake
  2. 我在wxWidgets的根目录中创建了一个名为cmake的目录(在本例中为:C:C++wxWidgets-3.1.3)。此外,我还创建了bin目录,用于存储编译后的二进制文件
  3. 然后,我导航到cmake目录,并运行以下CMake配置命令:
    $CMake-G"MinGW Makefiles"-D"wxBUILD_SHARED=OFF"-D"wxBUILD_MONOLITIC=OFF"-D"CMAKE_BUILD_TYPE=debug"-D"CMAKE_C_COMPILER=gcc.exe"-D"CMAKE_CX_COMPILER=g++.exe">
    然后我使用以下命令开始构建:
    $CMAKE--BUILD--目标所有
    生成的.a文件(静态库文件)被放置在bin目录中
  4. 我用-D "CMAKE_BUILD_TYPE=release"参数重复了步骤3
  5. 为方便起见,将生成的libgcc_x64_libmswulibgcc_x64_libmswud目录放入include目录中(因为它们包含setup.h头文件)

因此,我的C:C++wxWidgets-3.1.3bin目录包含以下文件:

libwxexpat.a libwxpngd.a libwxtiff.a wxbase31u_net.a wxmsw31u_adv.a wxmsw31u_media.a wXM sw31u_stc.a wxmsw31 ud_core.a wX sw31ud_qa.a wXsw31ud_xrc.alibwxexpatd.alibwxregexu.alibwxtiffd.a wxbase31u_xml.awxmsw31u_aui.awxmSW31u_progrid.awxmSw31u_webview.awxmswi31ud_gl.a wxmsw31 ud_ribbon.a wxrc.exe*libwxjpeg.a libwxregexud.a libwxzlib.a wxbase31ud.a wxmsw31u_core.a wxmsw31u_qa.a wXM sw31uxrc.a wxmsw31 ud_html.a wxmsw31ud_richtext.alibwxjpegd.a libwxscintilla.a libwxzlibd.a wxbase31ud_net.a wxmsw31u_gl.a wxmsw31u_ribbon.a wxmsw31 ud_adv.a wxmsw31ud_media.a wXM sw31ud_stc.alibwxpng.a libwxscintilad.a wxbase31u.wxbase 31ud_xml.a wxmsw31u_html.a wxmsw31u_richtext.a wXM sw31ud_aui.a wX sw31ud_progrid.a wXsw31ud_webview.a

创建Hello World项目

我创建了一个简单的wxWidgets hello世界项目,文件结构如下:

app|构建|收割台|来源||main.cpp|CMakeLists.txt

main.cpp:的内容

// wxWidgets "Hello World" Program
// For compilers that support precompilation, includes "wx/wx.h".
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
class MyApp : public wxApp {
public:
virtual bool OnInit();
};
class MyFrame : public wxFrame {
public:
MyFrame();
private:
void OnHello(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
};
enum {
ID_Hello = 1
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit() {
MyFrame *frame = new MyFrame();
frame->Show(true);
return true;
}
MyFrame::MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {
wxMenu *menuFile = new wxMenu;
menuFile->Append(ID_Hello, "&Hello...tCtrl-H", "Help string shown in status bar for this menu item");
menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT);
wxMenu *menuHelp = new wxMenu;
menuHelp->Append(wxID_ABOUT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, "&File");
menuBar->Append(menuHelp, "&Help");
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText("Welcome to wxWidgets!");
Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
}
void MyFrame::OnExit(wxCommandEvent& event) {
Close(true);
}
void MyFrame::OnAbout(wxCommandEvent& event) {
wxMessageBox("This is a wxWidgets Hello World example", "About Hello World", wxOK | wxICON_INFORMATION);
}
void MyFrame::OnHello(wxCommandEvent& event) {
wxLogMessage("Hello world from wxWidgets!");
}

CMakeLists.txt:的内容

cmake_minimum_required(VERSION 2.8)
project(hello_world)
if (MINGW)
add_compile_options(--static)
endif()
set(wx_libraries_path "C:\C++\wxWidgets-3.1.3\bin")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
include_directories("C:\C++\wxWidgets-3.1.3\include\mswud")
find_library(libwxexpat       NAMES libwxexpatd        PATH ${wx_libraries_path})
find_library(libwxjpeg        NAMES libwxjpegd         PATH ${wx_libraries_path})
find_library(libwxpng         NAMES libwxpngd          PATH ${wx_libraries_path})
find_library(libwxregexu      NAMES libwxregexud       PATH ${wx_libraries_path})
find_library(libwxscintilla   NAMES libwxscintillad    PATH ${wx_libraries_path})
find_library(libwxtiff        NAMES libwxtiffd         PATH ${wx_libraries_path})
find_library(libwxzlib        NAMES libwxzlibd         PATH ${wx_libraries_path})
find_library(wxbase31u        NAMES wxbase31ud         PATH ${wx_libraries_path})
find_library(wxbase31u_xml    NAMES wxbase31ud_net     PATH ${wx_libraries_path})
find_library(wxbase31u_net    NAMES wxbase31ud_xml     PATH ${wx_libraries_path})
find_library(wxmsw31u_adv     NAMES wxmsw31ud_adv      PATH ${wx_libraries_path})
find_library(wxmsw31u_aui     NAMES wxmsw31ud_aui      PATH ${wx_libraries_path})
find_library(wxmsw31u_core    NAMES wxmsw31ud_core     PATH ${wx_libraries_path})
find_library(wxmsw31u_gl      NAMES wxmsw31ud_gl       PATH ${wx_libraries_path})
find_library(wxmsw31u_html    NAMES wxmsw31ud_html     PATH ${wx_libraries_path})
find_library(wxmsw31u_media   NAMES wxmsw31ud_media    PATH ${wx_libraries_path})
find_library(wxmsw31u_propgri NAMES wxmsw31ud_propgrid PATH ${wx_libraries_path})
find_library(wxmsw31u_qa      NAMES wxmsw31ud_qa       PATH ${wx_libraries_path})
find_library(wxmsw31u_ribbon  NAMES wxmsw31ud_ribbon   PATH ${wx_libraries_path})
find_library(wxmsw31u_richtex NAMES wxmsw31ud_richtext PATH ${wx_libraries_path})
find_library(wxmsw31u_stc     NAMES wxmsw31ud_stc      PATH ${wx_libraries_path})
find_library(wxmsw31u_webview NAMES wxmsw31ud_webview  PATH ${wx_libraries_path})
find_library(wxmsw31u_xrc     NAMES wxmsw31ud_xrc      PATH ${wx_libraries_path})
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
include_directories("C:\C++\wxWidgets-3.1.3\include\mswu")
find_library(libwxexpat       NAMES libwxexpat       PATH ${wx_libraries_path})
find_library(libwxjpeg        NAMES libwxjpeg        PATH ${wx_libraries_path})
find_library(libwxpng         NAMES libwxpng         PATH ${wx_libraries_path})
find_library(libwxregexu      NAMES libwxregexu      PATH ${wx_libraries_path})
find_library(libwxscintilla   NAMES libwxscintilla   PATH ${wx_libraries_path})
find_library(libwxtiff        NAMES libwxtiff        PATH ${wx_libraries_path})
find_library(libwxzlib        NAMES libwxzlib        PATH ${wx_libraries_path})
find_library(wxbase31u        NAMES wxbase31u        PATH ${wx_libraries_path})
find_library(wxbase31u_xml    NAMES wxbase31u_xml    PATH ${wx_libraries_path})
find_library(wxbase31u_net    NAMES wxbase31u_net    PATH ${wx_libraries_path})
find_library(wxmsw31u_adv     NAMES wxmsw31u_adv     PATH ${wx_libraries_path})
find_library(wxmsw31u_aui     NAMES wxmsw31u_aui     PATH ${wx_libraries_path})
find_library(wxmsw31u_core    NAMES wxmsw31u_core    PATH ${wx_libraries_path})
find_library(wxmsw31u_gl      NAMES wxmsw31u_gl      PATH ${wx_libraries_path})
find_library(wxmsw31u_html    NAMES wxmsw31u_html    PATH ${wx_libraries_path})
find_library(wxmsw31u_media   NAMES wxmsw31u_media   PATH ${wx_libraries_path})
find_library(wxmsw31u_propgri NAMES wxmsw31u_propgri PATH ${wx_libraries_path})
find_library(wxmsw31u_qa      NAMES wxmsw31u_qa      PATH ${wx_libraries_path})
find_library(wxmsw31u_ribbon  NAMES wxmsw31u_ribbon  PATH ${wx_libraries_path})
find_library(wxmsw31u_richtex NAMES wxmsw31u_richtex PATH ${wx_libraries_path})
find_library(wxmsw31u_stc     NAMES wxmsw31u_stc     PATH ${wx_libraries_path})
find_library(wxmsw31u_webview NAMES wxmsw31u_webview PATH ${wx_libraries_path})
find_library(wxmsw31u_xrc     NAMES wxmsw31u_xrc     PATH ${wx_libraries_path})
endif()
include_directories("C:\C++\wxWidgets-3.1.3\include")
link_directories("C:\C++\wxWidgets-3.1.3\bin")
add_executable(app sources/main.cpp)
message(STATUS "${libwxexpat}")
target_link_libraries(app PRIVATE
${libwxexpat}
${libwxjpeg}
${libwxpng}
${libwxregexu}
${libwxscintilla}
${libwxtiff}
${libwxzlib}
${wxbase31u}
${wxbase31u_xml}
${wxbase31u_net}
${wxmsw31u_adv}
${wxmsw31u_aui}
${wxmsw31u_core}
${wxmsw31u_gl}
${wxmsw31u_html}
${wxmsw31u_media}
${wxmsw31u_propgrid}
${wxmsw31u_qa}
${wxmsw31u_ribbon}
${wxmsw31u_richtext}
${wxmsw31u_stc}
${wxmsw31u_webview}
${wxmsw31u_xrc}
)

创建项目文件后,我执行以下CMake命令来配置项目:

CMake-G"MinGW Makefiles"-D"CMAKE_C_COMPILER=gcc.exe"-D"CMAKE_CXX_COMPILER=g++.exe"-D"CMAKE_BUILD_TYPE=Debug"-D"CMPAKE_VERBOSE_MAKEFILE:BOOL=ON">
然后我尝试使用以下CMAKE命令构建项目,但失败了:
CMAKE--BUILD

编译错误

不幸的是,该程序无法编译,以下是输出:

"C:Program FilesCMakebincmake.exe" -E cmake_progress_start C:UsersOiltankerGitPepega-InjectinstallerbuildCMakeFiles C:UsersOiltankerGitPepega-InjectinstallerbuildCMakeFilesprogress.marks
C:/C++/MingGW-w64/mingw64/bin/mingw32-make.exe -f CMakeFilesMakefile2 all
mingw32-make.exe[1]: Entering directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build'
C:/C++/MingGW-w64/mingw64/bin/mingw32-make.exe -f CMakeFilesapp.dirbuild.make CMakeFiles/app.dir/depend
mingw32-make.exe[2]: Entering directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build'
"C:Program FilesCMakebincmake.exe" -E cmake_depends "MinGW Makefiles" C:UsersOiltankerGitPepega-Injectinstaller C:UsersOiltankerGitPepega-Injectinstaller C:UsersOiltankerGitPepega-Injectinstallerbuild C:UsersOiltankerGitPepega-Injectinstallerbuild C:UsersOiltankerGitPepega-InjectinstallerbuildCMakeFilesapp.dirDependInfo.cmake --color=
Dependee "C:UsersOiltankerGitPepega-InjectinstallerbuildCMakeFilesapp.dirDependInfo.cmake" is newer than depender "C:/Users/Oiltanker/Git/Pepega-Inject/installer/build/CMakeFiles/app.dir/depend.internal".
Dependee "C:/Users/Oiltanker/Git/Pepega-Inject/installer/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "C:/Users/Oiltanker/Git/Pepega-Inject/installer/build/CMakeFiles/app.dir/depend.internal".
Scanning dependencies of target app
mingw32-make.exe[2]: Leaving directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build'
C:/C++/MingGW-w64/mingw64/bin/mingw32-make.exe -f CMakeFilesapp.dirbuild.make CMakeFiles/app.dir/build
mingw32-make.exe[2]: Entering directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build'
[ 50%] Building CXX object CMakeFiles/app.dir/sources/main.cpp.obj
C:C++MingGW-w64mingw64bing++.exe   @CMakeFiles/app.dir/includes_CXX.rsp -g   --static -o CMakeFilesapp.dirsourcesmain.cpp.obj -c C:UsersOiltankerGitPepega-Injectinstallersourcesmain.cpp
[100%] Linking CXX executable app.exe
"C:Program FilesCMakebincmake.exe" -E cmake_link_script CMakeFilesapp.dirlink.txt --verbose=1
"C:Program FilesCMakebincmake.exe" -E remove -f CMakeFilesapp.dir/objects.a
C:C++MingGW-w64mingw64binar.exe cr CMakeFilesapp.dir/objects.a @CMakeFilesapp.dirobjects1.rsp
C:C++MingGW-w64mingw64bing++.exe -g   -Wl,--whole-archive CMakeFilesapp.dir/objects.a -Wl,--no-whole-archive  -o app.exe -Wl,--out-implib,libapp.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFilesapp.dirlinklibs.rsp
C:/C++/wxWidgets-3.1.3/bin/wxbase31ud.a(dlmsw.cpp.obj): In function `GetFileVersion':
C:/C++/wxWidgets-3.1.3/src/msw/dlmsw.cpp:67: undefined reference to `GetFileVersionInfoSizeW'
.......
C:/C++/wxWidgets-3.1.3/src/common/geometry.cpp:350: undefined reference to `wxDataInputStream::Read32()'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [CMakeFilesapp.dirbuild.make:110: app.exe] Error 1
mingw32-make.exe[2]: Leaving directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build'
mingw32-make.exe[1]: *** [CMakeFilesMakefile2:78: CMakeFiles/app.dir/all] Error 2
mingw32-make.exe[1]: Leaving directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build'
mingw32-make.exe: *** [Makefile:86: all] Error 2```

GetFileVersionInfoSizeW()生活在version.dll中,因此您需要链接到version.lib才能获得它。

wxDataInputStream::Read32()更令人惊讶,它确实应该出现在您链接的wxbase库中。尝试使用nmobjdump检查它是否真的存在。

我设法解决了我的问题。在我开始在互联网上搜索答案后,我发现wxWidgets项目CMakeLists.txt的例子不起作用,因为它需要设置一些变量。在我正确设置它们之后,我设法编译了helloworld示例。

以下是CMakeLists.txt文件的内容:

project(hello_world)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(src SRC_LIST)
set(wxWidgets_ROOT_DIR "C:/C++/wxWidgets")
set(wxWidgets_LIB_DIR "C:/C++/wxWidgets/lib/gcc_x64_lib")
set(wxWidgets_LIBRARIES "C:/C++/wxWidgets/lib")
set(wxWidgets_INCLUDE_DIRS "C:/C++/wxWidgets/include/wx")
set(wxWidgets_CONFIGURATION mswud)
find_package(wxWidgets COMPONENTS core base REQUIRED)
include(${wxWidgets_USE_FILE})
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})

详细流程

我删除了wxWidgets并重新编译了它们。

  1. 这次wxWidgets源代码位于C:C++wxWidgets-source目录中
  2. 我使用以下命令将install目标构建到C:C++wxWidgets目录:
    $cmake--build--target install
    您可以通过更改setup.h文件中的wxINSTALL_PREFIX定义并提醒cmake_install.cmakeCMAKE_INSTALL_PREFIX定义来指定安装的目的地。
    • 调试配置的情况下,setup.h文件将位于<cmake_building_directory>libgcc_x64_libmswudwx
    • 版本配置的情况下,setup.h文件将位于<cmake_building_directory>libgcc_x64_libmswuwx

我还被告知wxWidgets可能有一个特定的链接顺序,并且find_package函数会自动求解,无论它是真是假,我都无法判断。

最重要的是,Vadim说了什么——你和CMake和朋友们一起玩编译wxWidgets的所有游戏都是不必要的。

wxWidgets已经提供了Makefile来编译库。存储在wxWidgets\build\msw中。

所以你所能做的就是:

cd C:C++wxWidgets-3.1.3buidmsw
mingw64-make -f makefile.gcc BUILD="debug"

既然wxWidgets已经为人们提供了最小的样本,那么你所要做的就是:

cd C:C++wxWidgetssamplesminimal
mingw64-make -f makefile.gcc BUILD="debug"
./minimal.exe

这很简单,会为你节省很多时间。

除此之外——只是一个小小的建议——看起来你正在链接很多你并不真正需要的库。对于像这样的最小样本,您真正需要的只是wxbase和wxcore。所有其他都是不必要的。

谢谢。