安装MSYS2、更新系统(clang64)
MSYS2 是 Minimal SYStem 2 的缩写,参考:https://www.msys2.org/wiki/History/
安装:https://www.msys2.org/ , 默认目录 C:\msys64, 默认环境: UCRT64, 具体参考: https://www.msys2.org/docs/environments/
目标环境:UCRT64
- Toolchain:gcc
- Architecture:x86_64
- C Library:ucrt
- C++ Library:libstdc++
打开 msys2 clang64终端, 设置msys2国内仓库,参考: https://mirrors.tuna.tsinghua.edu.cn/help/msys2/
sed -i "s#https\?://mirror.msys2.org/#https://mirrors.tuna.tsinghua.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*
更新环境:
pacman -Syu
更新后关闭终端,再次打开执行:
pacman -Su
- MSYS2使用Arch Linux的包管理器pacman进行包管理。但MSYS2不是一个虚拟机,它只是用了Linux的包管理器。MSYS2是用来编译,使用native Windows程序的。
- pacman -Syu分两部分看。-Sy是更新软件库,u是升级所以已经安装的包
- pacman -S 是安装
安装C++工具链
pacman -S mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-ninja
:: There are 13 members in group mingw-w64-ucrt-x86_64-toolchain:
:: Repository ucrt64
1) mingw-w64-ucrt-x86_64-binutils 2) mingw-w64-ucrt-x86_64-crt 3) mingw-w64-ucrt-x86_64-gcc
4) mingw-w64-ucrt-x86_64-gdb 5) mingw-w64-ucrt-x86_64-gdb-multiarch
6) mingw-w64-ucrt-x86_64-headers 7) mingw-w64-ucrt-x86_64-libmangle
8) mingw-w64-ucrt-x86_64-libwinpthread 9) mingw-w64-ucrt-x86_64-make
10) mingw-w64-ucrt-x86_64-pkgconf 11) mingw-w64-ucrt-x86_64-tools
12) mingw-w64-ucrt-x86_64-winpthreads 13) mingw-w64-ucrt-x86_64-winstorecompat
检查版本:
gcc --version
g++ --version
cmake --version
ninja --version
输出:
gcc.exe (Rev5, Built by MSYS2 project) 16.1.0
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
g++.exe (Rev5, Built by MSYS2 project) 16.1.0
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
cmake version 4.3.3
CMake suite maintained and supported by Kitware (kitware.com/cmake).
1.13.2
clion 设置
Settings → Build, Execution, Deployment → Toolchains
- 工具集:C:\msys64\ucrt64
- cmake:C:\msys64\ucrt64\bin\cmake.exe
- 构建工具:C:\msys64\ucrt64\bin\ninja.exe
- c编译器:C:\msys64\ucrt64\bin\gcc.exe
- c++编译器:C:\msys64\ucrt64\bin\g++.exe
- 调试器: C:\msys64\ucrt64\bin\gdb.exe
安装库:
pacman -S mingw-w64-ucrt-x86_64-boost mingw-w64-ucrt-x86_64-fmt
在CLion中生成单一独立可执行文件(不依赖外部动态库)需要结合编译器/链接器配置和打包工具,cmake配置文件通用版本:
# 静态链接配置
if(MSVC)
# MSVC静态链接
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
elseif(CMAKE_COMPILER_IS_GNUCXX)
# GCC静态链接
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Clang静态链接(需安装静态库)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif()
项目路径尽量避免中文:C++ 编译器对中文、空格、加号(+)以及长路径的支持有时会出现诡异的 Bug(特别是在涉及 C++20 新特性时)。
中文乱码:
- 在 CLion 中连续按下两次 Shift 键(打开全局搜索随处定位 Search Everywhere)
- 在搜索框中直接输入:Registry,打开注册表
- 取消run.processes.with.pty
菜单常显:视图,外观,主菜单,显示在主工具栏上方
qt6
1、安装 Qt6 和相关开发组件
pacman -S mingw-w64-ucrt-x86_64-qt6 mingw-w64-ucrt-x86_64-qt6-base mingw-w64-ucrt-x86_64-qt6-tools
:: There are 39 members in group mingw-w64-ucrt-x86_64-qt6:
:: Repository ucrt64
1) mingw-w64-ucrt-x86_64-qt6-3d 2) mingw-w64-ucrt-x86_64-qt6-5compat
3) mingw-w64-ucrt-x86_64-qt6-activeqt 4) mingw-w64-ucrt-x86_64-qt6-base
5) mingw-w64-ucrt-x86_64-qt6-charts 6) mingw-w64-ucrt-x86_64-qt6-connectivity
7) mingw-w64-ucrt-x86_64-qt6-datavis3d 8) mingw-w64-ucrt-x86_64-qt6-declarative
9) mingw-w64-ucrt-x86_64-qt6-doc 10) mingw-w64-ucrt-x86_64-qt6-graphs
11) mingw-w64-ucrt-x86_64-qt6-grpc 12) mingw-w64-ucrt-x86_64-qt6-httpserver
13) mingw-w64-ucrt-x86_64-qt6-imageformats 14) mingw-w64-ucrt-x86_64-qt6-languageserver
15) mingw-w64-ucrt-x86_64-qt6-location 16) mingw-w64-ucrt-x86_64-qt6-lottie
17) mingw-w64-ucrt-x86_64-qt6-mqtt 18) mingw-w64-ucrt-x86_64-qt6-multimedia
19) mingw-w64-ucrt-x86_64-qt6-networkauth 20) mingw-w64-ucrt-x86_64-qt6-pdf
21) mingw-w64-ucrt-x86_64-qt6-positioning 22) mingw-w64-ucrt-x86_64-qt6-quick3d
23) mingw-w64-ucrt-x86_64-qt6-quick3dphysics 24) mingw-w64-ucrt-x86_64-qt6-quickeffectmaker
25) mingw-w64-ucrt-x86_64-qt6-quicktimeline 26) mingw-w64-ucrt-x86_64-qt6-remoteobjects
27) mingw-w64-ucrt-x86_64-qt6-scxml 28) mingw-w64-ucrt-x86_64-qt6-sensors
29) mingw-w64-ucrt-x86_64-qt6-serialbus 30) mingw-w64-ucrt-x86_64-qt6-serialport
31) mingw-w64-ucrt-x86_64-qt6-shadertools 32) mingw-w64-ucrt-x86_64-qt6-speech
33) mingw-w64-ucrt-x86_64-qt6-svg 34) mingw-w64-ucrt-x86_64-qt6-tools
35) mingw-w64-ucrt-x86_64-qt6-translations 36) mingw-w64-ucrt-x86_64-qt6-virtualkeyboard
37) mingw-w64-ucrt-x86_64-qt6-webchannel 38) mingw-w64-ucrt-x86_64-qt6-websockets
39) mingw-w64-ucrt-x86_64-qt6-webview
将 C:\msys64\ucrt64\bin ,C:\msys64\ucrt64\share\qt6\bin 加入系统path
新建环境变量 CMAKE_PREFIX_PATH,值为: C:\msys64\ucrt64\bin
2、 qt.qpa.plugin: Could not find the Qt platform plugin "windows" in "" 报错的解决方式:
设置环境变量 QT_QPA_PLATFORM_PLUGIN_PATH , 值为:C:\msys64\ucrt64\share\qt6\plugins\platforms
重启clion
3、新建项目
新建Qt 微件可执行项目,Qt CMake前缀: C:\msys64\ucrt64\bin, 对应cmake文件钟的下面语句
set(CMAKE_PREFIX_PATH "C:/msys64/ucrt64/bin")
4、外部工具:
设置,工具,外部工具
- 名称:UI_Designer
- 程序
C:\msys64\ucrt64\bin\designer.exe - 实参:
$FileName$ - 工作目录:
$FileDir$
设置,工具,外部工具
- 名称:UIC,用户界面编译器
- 程序:C:\msys64\ucrt64\share\qt6\bin\uic.exe
- 实参:
$FileName$ -o ui_$FileNameWithoutExtension$.h - 工作目录:
$FileDir$
项目,新建,Qt UI 类,如 MainWindow,就可以在项目中的ui上右键,ExternalTool,UI_Designer来打开图形界面(双击也是OK的)。
项目路径中不建议含有中文
生成头文件: mainwindow.h
需要修改 main.cpp 使用自己创建的Widget组件
main.cpp 原始代码:
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QPushButton button("Hello world!", nullptr);
button.resize(200, 100);
button.show();
return QApplication::exec();
}
修改后代码:
#include "mainwindow.h"
#include "ui_MainWindow.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow m;
m.show();
return QApplication::exec();
}
打包qt6程序:
- 新建目录,如
打包, 将生成的exe拷贝到该目录下 - 在该目录下运行
windeployqt xxx.exe --force
--force, 通过添加强制覆盖参数–force强制覆盖已存在的文件
打包时去掉命令行黑框:使用 CMake(Qt6 默认推荐)在你的 CMakeLists.txt 文件中,找到 add_executable 这一行,在目标名称后面加上 WIN32 关键字:
add_executable(你的项目名称 WIN32 main.cpp mainwindow.cpp)
警告提示: Warning: Cannot find any version of the dxcompiler.dll and dxil.dll., 处理方案:
- 忽略警告
- 将包含这两个dll 的
C:\JetBrains\CLion\jbr\bin加入系统path, 不过这样打包多两个dll 会多出近30 MB左右
高精度浮点数测试
#include <iostream>
#include <iomanip>
#include <chrono>
#include <boost/multiprecision/float128.hpp>
#include <quadmath.h>
// Boost 128位浮点数别名
using boost_f128 = boost::multiprecision::float128;
// 测试循环次数(由于纯软件模拟较慢,设为 5000 万次)
constexpr size_t ITERATIONS = 50'000'000;
int main() {
std::cout << "=== GCC 原生 __float128 vs Boost float128 ===" << std::endl;
std::cout << "测试循环次数: " << ITERATIONS << " 次\n\n";
// ====================================================
// 测试一:GCC 原生 __float128
// ====================================================
{
__float128 a = 1.1234567890123456789q;
__float128 b = 2.9876543210987654321q;
__float128 c = 0.5q;
__float128 result = 0.0q;
auto start = std::chrono::high_resolution_clock::now();
for (size_t i = 0; i < ITERATIONS; ++i) {
// 复杂的长混合表达式,测试寄存器与内存的转换
result = result + (a * b) - (a / (b + c));
a += 0.0000000000000000001q; // 步进,防止编译器强行将循环优化删除
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
// 转换为字符串输出
char buf[128];
quadmath_snprintf(buf, sizeof(buf), "%.20Qg", result);
std::cout << "[1] GCC 原生 __float128\n"
<< " 耗时: " << elapsed.count() << " ms\n"
<< " 结果: " << buf << "\n\n";
}
// ====================================================
// 测试二:Boost float128 方案
// ====================================================
{
// 注意:使用 q 后缀直接初始化 Boost 类型,避免运行期字符串解析开销
boost_f128 a = 1.1234567890123456789q;
boost_f128 b = 2.9876543210987654321q;
boost_f128 c = 0.5;
boost_f128 result = 0.0;
auto start = std::chrono::high_resolution_clock::now();
for (size_t i = 0; i < ITERATIONS; ++i) {
// 相同的长混合表达式,触发 Boost 运算符重载和临时对象
result = result + (a * b) - (a / (b + c));
a += 0.0000000000000000001;
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "[2] Boost float128 方案\n"
<< " 耗时: " << elapsed.count() << " ms\n"
<< " 结果: " << std::setprecision(20) << result << "\n\n";
}
return 0;
}
输出:
=== GCC 原生 __float128 vs Boost float128 ===
测试循环次数: 50000000 次
[1] GCC 原生 __float128
耗时: 4726.35 ms
结果: 151718831.83953837985
[2] Boost float128 方案
耗时: 6191.62 ms
结果: 151718831.83953837985
Boost float128 大概慢30%。