简体   繁体   English

无法编译 wxWidgets Hello World

[英]Cannot compile wxWidgets Hello World

So, I was trying to compile hello world example provided by wxWidgets but was unsuccessful in doing so.所以,我试图编译 wxWidgets 提供的 hello world 示例,但没有成功。 I will explain what I have done step by step to the current point where I am stuck.我将一步一步解释我所做的事情,直到我陷入困境。

Compiling wxWidgets编译 wxWidgets

  1. First of all, my compiler of choice is MinGw-w64, and since wxWidgets advise to build their library from source (downloaded from wxWidgets download ), I decided to do so using CMake.首先,我选择的编译器是 MinGw-w64,并且由于 wxWidgets 建议从源代码(从wxWidgets 下载)构建他们的库,我决定使用 CMake 这样做。
  2. I created a directory called cmake inside the root directory of wxWidgets (in my case: C:\\C++\\wxWidgets-3.1.3 ).我在 wxWidgets 的根目录中创建了一个名为cmake的目录(在我的例子中: C:\\C++\\wxWidgets-3.1.3 )。 Also I created bin directory for storing the compiled binaries.我还创建了bin目录来存储编译后的二进制文件。
  3. I then navigated to the cmake directory and run the following CMake configuration command:然后我导航到cmake目录并运行以下 CMake 配置命令:
     $ cmake -G "MinGW Makefiles" .. -D "wxBUILD_SHARED=OFF" -D "wxBUILD_MONOLITHIC=OFF" -D "CMAKE_BUILD_TYPE=debug" -D "CMAKE_C_COMPILER=gcc.exe" -D "CMAKE_CXX_COMPILER=g++.exe" $ cmake -G "MinGW Makefiles" .. -D "wxBUILD_SHARED=OFF" -D "wxBUILD_MONOLITHIC=OFF" -D "CMAKE_BUILD_TYPE=debug" -D "CMAKE_C_COMPILER=gcc.exe" -D "CMAKE_CXX_COMPILER=g++exe"。
    then I started the build by using the following command:然后我使用以下命令开始构建:
     $ cmake --build . $ cmake --build 。 --target all --所有目标
    The resulting .a files ( static library files ) were placed in the bin directory.生成的.a文件(静态库文件)放置在bin目录中。
  4. I repeated the step 3 with the -D "CMAKE_BUILD_TYPE=release" parameter.我用-D "CMAKE_BUILD_TYPE=release"参数重复了第 3 步。
  5. The generated lib\\gcc_x64_lib\\mswu and lib\\gcc_x64_lib\\mswud directories into the include directory for the convenience (as they contain setup.h header file).为方便起见,将生成的lib\\gcc_x64_lib\\mswulib\\gcc_x64_lib\\mswud目录放到include目录中(因为它们包含setup.h头文件)。

As the result my C:\\C++\\wxWidgets-3.1.3\\bin directory contains following files:结果我的C:\\C++\\wxWidgets-3.1.3\\bin目录包含以下文件:

libwxexpat.a   libwxpngd.a        libwxtiff.a   wxbase31u_net.a   wxmsw31u_adv.a   wxmsw31u_media.a     wxmsw31u_stc.a      wxmsw31ud_core.a      wxmsw31ud_qa.a        wxmsw31ud_xrc.a
libwxexpatd.a  libwxregexu.a      libwxtiffd.a  wxbase31u_xml.a   wxmsw31u_aui.a   wxmsw31u_propgrid.a  wxmsw31u_webview.a  wxmsw31ud_gl.a        wxmsw31ud_ribbon.a    wxrc.exe*
libwxjpeg.a    libwxregexud.a     libwxzlib.a   wxbase31ud.a      wxmsw31u_core.a  wxmsw31u_qa.a        wxmsw31u_xrc.a      wxmsw31ud_html.a      wxmsw31ud_richtext.a
libwxjpegd.a   libwxscintilla.a   libwxzlibd.a  wxbase31ud_net.a  wxmsw31u_gl.a    wxmsw31u_ribbon.a    wxmsw31ud_adv.a     wxmsw31ud_media.a     wxmsw31ud_stc.a
libwxpng.a     libwxscintillad.a  wxbase31u.a   wxbase31ud_xml.a  wxmsw31u_html.a  wxmsw31u_richtext.a  wxmsw31ud_aui.a     wxmsw31ud_propgrid.a  wxmsw31ud_webview.a

Creating Hello World project创建 Hello World 项目

I created simple wxWidgets hello world project with the following file structure:我使用以下文件结构创建了简单的 wxWidgets hello world 项目:

app
|   build
|   headers
|   sources
|   |    main.cpp
|   CMakeLists.txt

The contents of main.cpp : 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!");
}

The contents of CMakeLists.txt : 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}
)

After I created project files I executed following CMake command to configure the project:创建项目文件后,我执行以下 CMake 命令来配置项目:

cmake -G "MinGW Makefiles" .. -D "CMAKE_C_COMPILER=gcc.exe" -D "CMAKE_CXX_COMPILER=g++.exe" -D "CMAKE_BUILD_TYPE=Debug" -D "CMAKE_VERBOSE_MAKEFILE:BOOL=ON"
Then I tried and failed to build the project with the following CMake command: 然后我尝试使用以下 CMake 命令构建项目失败:
 cmake --build . cmake --build 。

Compilation errors编译错误

Unfortunately, the program fails to compile with, here is the output:不幸的是,程序无法编译,输出如下:

 "C:\\Program Files\\CMake\\bin\\cmake.exe" -E cmake_progress_start C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer\\build\\CMakeFiles C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer\\build\\CMakeFiles\\progress.marks C:/C++/MingGW-w64/mingw64/bin/mingw32-make.exe -f CMakeFiles\\Makefile2 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 CMakeFiles\\app.dir\\build.make CMakeFiles/app.dir/depend mingw32-make.exe[2]: Entering directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build' "C:\\Program Files\\CMake\\bin\\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer\\build C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer\\build C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer\\build\\CMakeFiles\\app.dir\\DependInfo.cmake --color= Dependee "C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer\\build\\CMakeFiles\\app.dir\\DependInfo.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 CMakeFiles\\app.dir\\build.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-w64\\mingw64\\bin\\g++.exe @CMakeFiles/app.dir/includes_CXX.rsp -g --static -o CMakeFiles\\app.dir\\sources\\main.cpp.obj -c C:\\Users\\Oiltanker\\Git\\Pepega-Inject\\installer\\sources\\main.cpp [100%] Linking CXX executable app.exe "C:\\Program Files\\CMake\\bin\\cmake.exe" -E cmake_link_script CMakeFiles\\app.dir\\link.txt --verbose=1 "C:\\Program Files\\CMake\\bin\\cmake.exe" -E remove -f CMakeFiles\\app.dir/objects.a C:\\C++\\MingGW-w64\\mingw64\\bin\\ar.exe cr CMakeFiles\\app.dir/objects.a @CMakeFiles\\app.dir\\objects1.rsp C:\\C++\\MingGW-w64\\mingw64\\bin\\g++.exe -g -Wl,--whole-archive CMakeFiles\\app.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 @CMakeFiles\\app.dir\\linklibs.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]: *** [CMakeFiles\\app.dir\\build.make:110: app.exe] Error 1 mingw32-make.exe[2]: Leaving directory 'C:/Users/Oiltanker/Git/Pepega-Inject/installer/build' mingw32-make.exe[1]: *** [CMakeFiles\\Makefile2: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() lives in version.dll , so you need to link with version.lib to get it. GetFileVersionInfoSizeW()位于version.dll ,因此您需要与version.lib链接以获取它。

wxDataInputStream::Read32() is more surprising, it really should be present in wxbase library that you're linking with. wxDataInputStream::Read32()更令人惊讶,它确实应该存在于您正在链接的wxbase库中。 Try checking if it's really there using nm or objdump .尝试使用nmobjdump检查它是否真的存在。

I managed to solve my problem.我设法解决了我的问题。 After I started searching on internet for answers and I found wxWidgets project CMakeLists.txt example that didn't work because it needed some variables set.在我开始在互联网上搜索答案后,我发现 wxWidgets 项目 CMakeLists.txt 示例不起作用,因为它需要设置一些变量。 After I set them correctly, I managed to compile hello world example.正确设置它们后,我设法编译了 hello world 示例。

Here is the contents of CMakeLists.txt file:这是 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})

Process in detail详细流程

I deleted wxWidgets and recompiled them.我删除了 wxWidgets 并重新编译它们。

  1. This time the wxWidgets source code was located in C:\\C++\\wxWidgets-source directory这次wxWidgets源码位于C:\\C++\\wxWidgets-source目录下
  2. I built install target to the C:\\C++\\wxWidgets directory with the following command:我使用以下命令install目标构建到C:\\C++\\wxWidgets目录:
     $ cmake --build . $ cmake --build 。 --target install --目标安装
    You can specify the destination where your installation will go to by altering wxINSTALL_PREFIX definition in setup.h file and alerting CMAKE_INSTALL_PREFIX definition in cmake_install.cmake file.您可以指定目的地,您的安装会去通过改变wxINSTALL_PREFIX定义setup.h文件和警报CMAKE_INSTALL_PREFIX在定义cmake_install.cmake文件。
    • In case of debug configuration, the setup.h file will be located in <cmake_building_directory>\\lib\\gcc_x64_lib\\mswud\\wx调试配置的情况下, setup.h文件将位于<cmake_building_directory>\\lib\\gcc_x64_lib\\mswud\\wx
    • In case of release configuration, the setup.h file will be located in <cmake_building_directory>\\lib\\gcc_x64_lib\\mswu\\wx发布配置的情况下, setup.h文件将位于<cmake_building_directory>\\lib\\gcc_x64_lib\\mswu\\wx

I was also told that wxWidgets might have a specific linking order and that find_package function solves automatically, whether it is true or not I cannot tell.我还被告知 wxWidgets 可能有一个特定的链接顺序,并且find_package函数会自动解决,我不知道是不是真的。

On top what Vadim said - all you play with CMake and friends to compile wxWidgets are unnecessary.最重要的是 Vadim 所说的 - 所有你和 CMake 和朋友一起玩来编译 wxWidgets 都是不必要的。

wxWidgets already provide Makefile to compile the library. wxWidgets 已经提供了 Makefile 来编译库。 The are stored in wxWidgets\\build\\msw.存储在 wxWidgets\\build\\msw 中。

So all you could've done is:所以你所能做的就是:

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

Then since wxWidgets already provides the minimal sample for the people to try all you woud be doing is:然后因为 wxWidgets 已经为人们提供了最少的样本来尝试你要做的所有事情是:

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

This is much simper and would save you a lot of time.这很简单,可以为您节省大量时间。

On top of that - just a little suggestion - it looks like you are linking with a lot of libraries that you don't really need.最重要的是 - 只是一个小建议 - 看起来您正在链接许多您并不真正需要的库。 For the minimal sample like this all you really need is wxbase and wxcore.对于像这样的最小样本,您真正需要的是 wxbase 和 wxcore。 All other are unnecessary.所有其他都是不必要的。

Thank you.谢谢你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM