简体   繁体   中英

Cannot compile wxWidgets Hello World

So, I was trying to compile hello world example provided by wxWidgets but was unsuccessful in doing so. I will explain what I have done step by step to the current point where I am stuck.

Compiling 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.
  2. I created a directory called cmake inside the root directory of wxWidgets (in my case: C:\\C++\\wxWidgets-3.1.3 ). Also I created bin directory for storing the compiled binaries.
  3. I then navigated to the cmake directory and run the following CMake configuration command:
     $ 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 .  --target all 
    The resulting .a files ( static library files ) were placed in the bin directory.
  4. I repeated the step 3 with the -D "CMAKE_BUILD_TYPE=release" parameter.
  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).

As the result my C:\\C++\\wxWidgets-3.1.3\\bin directory contains following files:

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

I created simple wxWidgets hello world project with the following file structure:

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

The contents of 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 :

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 -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 --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.

wxDataInputStream::Read32() is more surprising, it really should be present in wxbase library that you're linking with. Try checking if it's really there using nm or objdump .

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. After I set them correctly, I managed to compile hello world example.

Here is the contents of CMakeLists.txt file:

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.

  1. This time the wxWidgets source code was located in C:\\C++\\wxWidgets-source directory
  2. I built install target to the C:\\C++\\wxWidgets directory with the following command:
     $ 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.
    • In case of debug configuration, the setup.h file will be located in <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

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.

On top what Vadim said - all you play with CMake and friends to compile wxWidgets are unnecessary.

wxWidgets already provide Makefile to compile the library. The are stored in 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:

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. All other are unnecessary.

Thank you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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