wxWidgets 环境搭建
在wxWidgets 官网下载页面点击Download Windows Binaries
选择TDM-GCC 10.3
和MinGW-w64 8.1
下的头文件和开发包进行下载。这儿我们会用两种 gcc 编译器进行对比,所以下载 2 个种编译器对应的库文件。正常只需根据自己安装的编译器下载对应的 1 种库文件即可。
将下好的文件解压到 wxWidgets 的根目录(这儿以D:\wxWidgets
为例),解压后的目录结构如下:
bash
/d/wxWidgets
├── wxMSW-3.2.4_gcc1030TDM_Dev TDM-GCC 10.3 编译32位应用程序对应的库头文件的dll文件
│ ├── include
│ │ ├── msvc
│ │ └── wx
│ └── lib
│ └── gcc1030TDM_dll
│ ├── mswu
│ └── mswud
├── wxMSW-3.2.4_gcc1030TDM_x64_Dev TDM-GCC 10.3 编译64位应用程序对应的库头文件的dll文件
│ ├── include
│ │ ├── msvc
│ │ └── wx
│ └── lib
│ └── gcc1030TDM_x64_dll
│ ├── mswu
│ └── mswud
├── wxMSW-3.2.4_gcc810_Dev MinGW-w64 8.1.0 编译32位应用程序对应的库头文件的dll文件
│ ├── include
│ │ ├── msvc
│ │ └── wx
│ └── lib
│ └── gcc810_dll
│ ├── mswu
│ └── mswud
└── wxMSW-3.2.4_gcc810_x64_Dev MinGW-w64 8.1.0 编译64位应用程序对应的库头文件的dll文件
├── include
│ ├── msvc
│ └── wx
└── lib
└── gcc810_x64_dll
├── mswu
└── mswud
注:include 目录下的msvc 是给 VC 编译器使用的,现在我们使用 gcc 编译器。所以不应将 msvc 目录加入头文件搜索路径中去。
将所有 lib/*_dll 目录添加到环境变量 Path 中
GCC 环境搭建
MinGW-w64 8.1.0
从MinGW-w64 下载页选择下载以下文件:
i686-win32-sjlj
下载后的文件为:i686-8.1.0-release-win32-sjlj-rt_v6-rev0
32 位程序对应的编译器x86_64-win32-seh
下载后的文件为:x86_64-8.1.0-release-win32-seh-rt_v6-rev0
64 位程序对应的编译器x86_64-posix-sjlj
下载后的文件为:x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0
(仅为后面实验用)
将下载的文件解压到 MinGW-w64 安装目录(这儿以D:\MinGW-w64
为例),目录结构如下:
bash
/d/mingw-w64
├── i686-8.1.0-release-win32-sjlj-rt_v6-rev0
│ └── mingw32
│ ├── bin
│ ├── etc
│ ├── i686-w64-mingw32
│ ├── include
│ ├── lib
│ ├── libexec
│ ├── licenses
│ ├── opt
│ └── share
├── x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0
│ └── mingw64
│ ├── bin
│ ├── etc
│ ├── include
│ ├── lib
│ ├── libexec
│ ├── licenses
│ ├── opt
│ ├── share
│ └── x86_64-w64-mingw32
└── x86_64-8.1.0-release-win32-seh-rt_v6-rev0
└── mingw64
├── bin
├── etc
├── include
├── lib
├── libexec
├── licenses
├── opt
├── share
└── x86_64-w64-mingw32
将所有的 bin 目录添加到环境变量 path 中
TDM-GCC 10.3
- 从64 位 TDM-GCC 下载页面下载
tdm64-gcc-10.3.0-2.exe
作为 64 位程序的编译器 - 从32 位 TDM-GCC 下载页面下载
tdm-gcc-10.3.0.exe
作为 32 位程序的编译器
将下载的两个文件点击安装到 TDM-GCC 根目录(这儿以D:\TDM-GCC
为例)安装后目录结构如下:
bash
/d/Tdm-gcc
├── TDM-GCC-32
│ ├── __installer
│ ├── bin
│ ├── gdb32
│ ├── include
│ ├── lib
│ ├── libexec
│ ├── mingw32
│ ├── share
│ └── var
└── TDM-GCC-64
├── __installer
├── bin
├── gdb64
├── include
├── lib
├── libexec
├── share
└── x86_64-w64-mingw32
创建 HelloWorld 工程
源文件
创建一个工程目录,并在该目录下创建HelloWorld.cpp
文件
c++
// Start of wxWidgets "Hello World" Program
#include <wx/wx.h>
class MyApp : public wxApp
{
public:
bool OnInit() override;
};
wxIMPLEMENT_APP(MyApp);
class MyFrame : public wxFrame
{
public:
MyFrame();
private:
void OnHello(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
};
enum
{
ID_Hello = 1
};
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame();
frame->Show(true);
return true;
}
MyFrame::MyFrame()
: wxFrame(nullptr, 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!");
}
VsCode 配置文件
配置 wxWidgets 目录
在工程文件夹的.vscode
目录下的settings.json
文件中添以下配置:
json
{
"wxWidgets_gcc810": {
// MinGW-w64 编译32位程序时的库文件和头文件
"include_path": "D:\\wxWidgets\\wxMSW-3.2.4_gcc810_Dev\\include",
"setup_path": "D:\\wxWidgets\\wxMSW-3.2.4_gcc810_Dev\\lib\\gcc810_dll\\mswu",
"lib_path": "D:\\wxWidgets\\wxMSW-3.2.4_gcc810_Dev\\lib\\gcc810_dll"
},
"wxWidgets_gcc810_x64": {
// MinGW-w64 编译64位程序时的库文件和头文件
"include_path": "D:\\wxWidgets\\wxMSW-3.2.4_gcc810_x64_Dev\\include",
"setup_path": "D:\\wxWidgets\\wxMSW-3.2.4_gcc810_x64_Dev\\lib\\gcc810_x64_dll\\mswu",
"lib_path": "D:\\wxWidgets\\wxMSW-3.2.4_gcc810_x64_Dev\\lib\\gcc810_x64_dll"
},
"wxWidgets_tdmgcc": {
// TDM-GCC 编译32位程序时的库文件和头文件
"include_path": "D:/wxWidgets/wxMSW-3.2.4_gcc1030TDM_Dev/include",
"setup_path": "D:/wxWidgets/wxMSW-3.2.4_gcc1030TDM_Dev/lib/gcc1030TDM_dll/mswu",
"lib_path": "D:/wxWidgets/wxMSW-3.2.4_gcc1030TDM_Dev/lib/gcc1030TDM_dll"
},
"wxWidgets_tdmgcc_x64": {
// TDM-GCC 编译64位程序时的库文件和头文件
"include_path": "D:/wxWidgets/wxMSW-3.2.4_gcc1030TDM_x64_Dev/include",
"setup_path": "D:/wxWidgets/wxMSW-3.2.4_gcc1030TDM_x64_Dev/lib/gcc1030TDM_x64_dll/mswu",
"lib_path": "D:/wxWidgets/wxMSW-3.2.4_gcc1030TDM_x64_Dev/lib/gcc1030TDM_x64_dll"
}
}
配置 C/C++ 环境
在工程文件夹的.vscode
目录下的c_cpp_properties.json
文件中添以下配置:
json
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"${config:wxWidgets_gcc810.include_path}",
"${config:wxWidgets_gcc810.setup_path}"
],
"defines": ["_DEBUG", "UNICODE", "_UNICODE"],
"compilerPath": "D:/MinGW-W64/x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0/mingw64/bin/g++.exe",
"cStandard": "c17",
"cppStandard": "gnu++14",
"intelliSenseMode": "windows-gcc-x86"
}
],
"version": 4
}
主要添了头文件路 ${config:wxWidgets_gcc810.include_path}
对应 settings.json 文件下的 wxWidgets_gcc810 配置下的 include_path 对应的路径,
${config:wxWidgets_gcc810.setup_path}
对应 settings.json 文件下的 wxWidgets_gcc810 配置下的 setup_path 对应的路径
配置编译任务
在工程目录的.vscode
文件夹下添加task.json
文件:
json
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "MinGW-W64-W64 32位编译器生成32位应用程序",
"command": "D:/MinGW-W64/i686-8.1.0-release-win32-sjlj-rt_v6-rev0/mingw32/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"-s",
"-I${config:wxWidgets_gcc810.include_path}",
"-I${config:wxWidgets_gcc810.setup_path}",
"-mwindows",
"-L${config:wxWidgets_gcc810.lib_path}",
"-lwxbase32u",
"-lwxmsw32u_core"
],
"options": {
"cwd": "D:/MinGW-W64/i686-8.1.0-release-win32-sjlj-rt_v6-rev0/mingw32/bin/"
},
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "编译器: D:/MinGW-W64/i686-8.1.0-release-win32-sjlj-rt_v6-rev0/mingw32/bin/g++.exe"
},
{
"type": "cppbuild",
"label": "MinGW-W64-W64 64位编译器生成64位应用程序",
"command": "D:/MinGW-W64/x86_64-8.1.0-release-win32-seh-rt_v6-rev0/mingw64/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}_x64.exe",
"-s",
"-I${config:wxWidgets_gcc810_x64.include_path}",
"-I${config:wxWidgets_gcc810_x64.setup_path}",
"-mwindows",
"-L${config:wxWidgets_gcc810_x64.lib_path}",
"-lwxbase32u",
"-lwxmsw32u_core"
],
"options": {
"cwd": "D:/MinGW-W64/x86_64-8.1.0-release-win32-seh-rt_v6-rev0/mingw64/bin"
},
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "编译器: D:/MinGW-W64/x86_64-8.1.0-release-win32-seh-rt_v6-rev0/mingw64/bin/g++.exe"
},
{
"type": "cppbuild",
"label": "MinGW-W64-W64 64位编译器生成32位应用程序",
"command": "D:/MinGW-W64/x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0/mingw64/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}_x64_32.exe",
"-m32",
"-s",
"-I${config:wxWidgets_gcc810.include_path}",
"-I${config:wxWidgets_gcc810.setup_path}",
"-mwindows",
"-L${config:wxWidgets_gcc810.lib_path}",
"-lwxbase32u",
"-lwxmsw32u_core"
],
"options": {
"cwd": "D:/MinGW-W64/x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0/mingw64/bin"
},
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "编译器: D:/MinGW-W64/x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0/mingw64/bin/g++.exe"
},
{
"type": "cppbuild",
"label": "TDM-GCC 32位编译器生成32位应用程序",
"command": "D:/TDM-GCC/TDM-GCC-32/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}_tdm.exe",
"-s",
"-I${config:wxWidgets_tdmgcc.include_path}",
"-I${config:wxWidgets_tdmgcc.setup_path}",
"-mwindows",
"-L${config:wxWidgets_tdmgcc.lib_path}",
"-lwxbase32u",
"-lwxmsw32u_core"
],
"options": {
"cwd": "D:/TDM-GCC/TDM-GCC-32/bin/"
},
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "编译器: D:/TDM-GCC/TDM-GCC-32/bin/g++.exe"
},
{
"type": "cppbuild",
"label": "TDM-GCC 64位编译器生成64位应用程序",
"command": "D:/TDM-GCC/TDM-GCC-64/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}_tdm_x64.exe",
"-s",
"-I${config:wxWidgets_tdmgcc_x64.include_path}",
"-I${config:wxWidgets_tdmgcc_x64.setup_path}",
"-mwindows",
"-L${config:wxWidgets_tdmgcc_x64.lib_path}",
"-lwxbase32u",
"-lwxmsw32u_core"
],
"options": {
"cwd": "D:/TDM-GCC/TDM-GCC-64/bin"
},
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "编译器: D:/TDM-GCC/TDM-GCC-64/bin/g++.exe"
},
{
"type": "cppbuild",
"label": "TDM-GCC 64位编译器生成32位应用程序",
"command": "D:/TDM-GCC/TDM-GCC-64/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}_tdm_x64_32.exe",
"-m32",
"-s",
"-I${config:wxWidgets_tdmgcc.include_path}",
"-I${config:wxWidgets_tdmgcc.setup_path}",
"-mwindows",
"-L${config:wxWidgets_tdmgcc.lib_path}",
"-lwxbase32u",
"-lwxmsw32u_core"
],
"options": {
"cwd": "D:/TDM-GCC/TDM-GCC-64/bin"
},
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "编译器: D:/TDM-GCC/TDM-GCC-64/bin/g++.exe"
}
]
}
共添加了 6 个编译任务,分别对应 2 种编译器,每种编译器对应的生成 3 个可以行文件
- 带 x64 的表示 64 位应用程序
- 带 x64_32 表示由 64 位编译器生成的 32 位程序
- 带 tdm 的表示由 TDM-GCC 编译生成
VsCode 打开 HelloWorld.cpp 时按 F1 输入run task
选择对应的任务生成对应的应用程序
生成的应用程序对比
- tdm-gcc 生成的应用程序比 MinGW-w64 生成的应用程序略大
- MinGW-w64 比 tdm-gcc 生成的应用程序 多依赖
libgcc_s_sjlj-1.dll
和libstdc++-6.dll
仅对比 32 位程序 - tdm-gcc 可以用 64 位编译器加
-m32
参数和回wxWidgets 32位库文件
生成32位应用程序,
但因为wxWidgets gcc810库文件32位和64位使用了不同的异常处理,x86_64-8.1.0-release-win32-seh-rt_v6-rev0
是不能通过添加-m32
参数来生成32位应用的,
可以使用x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0
添加-m32
参数和32位库文件来生成32位应用程序
个人觉得使用TDM-GCC省事些,而且可以只下载64位的TDM-GCC编译器来生成32位或64位的程序