C++编程环境:win64,msys2,UCRT64

安装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%。

正文完
 0
评论(没有评论)