[英]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.
我将一步一步解释我所做的事情,直到我陷入困境。
cmake
inside the root directory of wxWidgets (in my case: C:\\C++\\wxWidgets-3.1.3
).cmake
的目录(在我的例子中: C:\\C++\\wxWidgets-3.1.3
)。 Also I created bin
directory for storing the compiled binaries.bin
目录来存储编译后的二进制文件。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"then I started the build by using the following 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"。
$ cmake --build .The resulting$ cmake --build 。 --target all
--所有目标
.a
files ( static library files ) were placed in the bin
directory..a
文件(静态库文件)放置在bin
目录中。-D "CMAKE_BUILD_TYPE=release"
parameter.-D "CMAKE_BUILD_TYPE=release"
参数重复了第 3 步。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\\mswu
和lib\\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
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 --build .cmake --build 。
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
.尝试使用
nm
或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.
在我开始在互联网上搜索答案后,我发现 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})
I deleted wxWidgets and recompiled them.我删除了 wxWidgets 并重新编译它们。
C:\\C++\\wxWidgets-source
directoryC:\\C++\\wxWidgets-source
目录下install
target to the C:\\C++\\wxWidgets
directory with the following command:install
目标构建到C:\\C++\\wxWidgets
目录:$ cmake --build .You can specify the destination where your installation will go to by altering$ cmake --build 。 --target install
--目标安装
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
文件。
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
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.