📚 博主的专栏

🐧 Linux   |   🖥️ C++   |   📊 数据结构  | 💡C++ 算法 | 🅒 C 语言  | 🌐 计算机网络 |🗃️ mysql

本文摘要:本文详细介绍了使用CMake构建Qt项目的配置方法,涵盖MSVC和MinGW两种编译器环境。主要内容包括:1)创建构建目录与CMake配置命令,重点说明生成器选择(-G参数)和Qt路径设置;2)提供完整的CMakeLists.txt示例,展示Qt项目的基础配置、文件收集和库链接;3)针对MinGW环境特别说明资源文件处理配置;4)给出两种环境下的构建命令(MSVC需指定工具链版本,MinGW需设置编译器路径)和运行方式。文章还包含环境变量设置建议和编译器检测代码,帮助开发者解决Qt版本与编译器兼容性问题。通过对比MSVC/MinGW的特性差异,为不同开发场景提供配置参考。

这是我的源代码文件目录:

可以在命令行先创建好一个目录build:mkdir build

MSVC

确保在 CMake 中指定使用 MSVC 的生成器。

例如,你可以使用以下命令来生成构建文件:

(1) 生成构建系统

cmake ..
 cmake .. -G "Visual Studio 15 2017" -A x64 -DCMAKE_PREFIX_PATH="E:\qt\Qt5.14.2\5.14.2\msvc2017_64\lib\cmake\Qt5"
cmake .. -G "Visual Studio 17 2022" -DCMAKE_PREFIX_PATH="E:\qt\Qt5.14.2\5.14.2\msvc2017_64\lib\cmake\Qt5"

cmake ..,运行 CMake,告诉它 CMakeLists.txt 文件在上一级目录 (..) 中。

  • 这个命令依赖于 CMake 的默认生成器

  • 在 Windows 上,CMake 很可能会自动选择最新安装的 Visual Studio(例如 Visual Studio 17 2022)作为默认生成器。

-G "Visual Studio 17 2022": 指定生成器 (Generator)。这是最关键的一步。

  • 生成器决定了 CMake 要生成哪种构建系统(Makefile, Visual Studio Solution, Ninja 等)。

  • "Visual Studio 17 2022" 告诉 CMake:“请生成一个可以用 Visual Studio 2022 打开和编译的 .sln 解决方案文件”。

  • msvc2017_64)是使用 Visual Studio 2017 的编译器(MSVC v141) 编译的二进制文件(.lib.dll)。

  • 使用 `-G "Visual Studio 17 2022"` 却能够成功构建, 系统上安装了 Visual Studio 2022,而您的 Qt 库恰好与它有某种兼容性,就能成功 或者并且该安装中包含了 VS2017 的构建工具(v141 工具集)

步骤 指定正确生成器 (-G "VS15 2017") 不指定生成器 (默认 VS17 2022)
CMake 生成什么 一个要求使用 VS2017 工具链的项目文件 一个要求使用 VS2022 工具链的项目文件
谁编译你的代码 VS2017 的 cl.exe (v141) VS2022 的 cl.exe (v143)
谁进行链接 VS2017 的 link.exe (v141) VS2022 的 link.exe (v143)
代码的二进制格式 v141 v143
Qt库的二进制格式 v141 (匹配!) v141 (不匹配!)
最终结果 成功:格式匹配,可以链接 失败:格式不匹配,链接器报错
cmake .. -G "Visual Studio 17 2022" -T "v141" -DCMAKE_PREFIX_PATH="E:\qt\Qt5.14.2\5.14.2\msvc2017_64\lib\cmake\Qt5"

这里的 -T "v141" 明确告诉 CMake:"虽然生成的是 VS2022 解决方案,但请使用 VS2017 的编译器工具集(v141)"。

这样,生成的解决方案文件会指定使用 VS2017 的编译器来构建,即使它是在 VS2022 环境中打开的。

没有但系统上安装了 Visual Studio 2022、使用的是 VS2022 默认的工具集(v143),而您的 Qt 库恰好与它有某种兼容性,就能成功

cmake .. -G "Visual Studio 17 2022" -DCMAKE_PREFIX_PATH="E:\qt\Qt5.14.2\5.14.2\msvc2017_64\lib\cmake\Qt5"

还是不行的话就需要安装 VS2017 构建工具

如果您确实需要 v141 工具集,可以通过 Visual Studio 安装程序添加:

  1. 打开 "Visual Studio Installer"

  2. 点击 Visual Studio 2022 的"修改"

  3. 选择"单个组件"选项卡

  4. 搜索并勾选 "MSVC v141 - VS 2017 C++ x64/x86 生成工具"

  5. 点击"修改"完成安装

接下来在命令行中:执行构建 (Build) 命令

cmake --build .
cmake --build . -j
cmake --build . --config Release
  • --build . : 在当前目录(build/)编译

  • 生成位置:build/Release/MyCMakeProject.exe

  • cmake --build .: 执行构建 (Build) 命令。告诉 CMake 开始编译当前目录 (.) 下由之前 cmake 命令生成的项目文件。

  • -j: 一个常见的参数,代表 “jobs”。它告诉构建工具(在这里是 MSBuild)使用多核并行编译,以加快编译速度。-j 后面甚至可以跟数字指定核心数,如 -j8

  • --config Release : 构建Release版本(VS多配置需显式指定),上面的构建的就是默认的debug版本

最后可以通过在文件目录中输入标红处:运行项目

在命令行:

E:\code\qt-learning-and-practice\TestCMakeQt\build\Release\MyCMakeProject.exe

 在build文件中Release中点击 .exe文件运行:就可以执行

在vs2022中从.sin文件打开项目,运行目标项目也可以成功

注意:在配置环境变量的时候:要将他们至顶

我的CMakeLists.txt文件:

# 基础配置
cmake_minimum_required(VERSION 3.5)
project(MyCMakeProject VERSION 1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)

# Qt5 配置(你的命令行覆盖了此处)
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_AUTOMOC ON)  # 自动处理Qt元对象编译
set(CMAKE_AUTOUIC ON)  # 自动处理UI文件
set(CMAKE_AUTORCC ON)  # 自动编译资源文件(.qrc)

# 收集文件
file(GLOB SOURCES "*.cpp")  # 包含所有.cpp
file(GLOB HEADERS "*.h")    # 包含所有.h
set(RESOURCES resource.qrc) # 资源文件

# 生成可执行文件
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${RESOURCES})
target_link_libraries(${PROJECT_NAME} 
Qt5::Core 
Qt5::Gui 
Qt5::Widgets)

MINGW

注意有时候需要添加上后两个,看是用的c还是c++、显式指定 C 和 C++ 编译器

cmake .. -G "MinGW Makefiles" `
  -DCMAKE_PREFIX_PATH="E:/qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5" `
  -DCMAKE_MAKE_PROGRAM="E:/qt/Qt5.14.2/Tools/mingw730_64/bin/mingw32-make.exe" `
  -DCMAKE_C_COMPILER="E:/qt/Qt5.14.2/Tools/mingw730_64/bin/gcc.exe" `
  -DCMAKE_CXX_COMPILER="E:/qt/Qt5.14.2/Tools/mingw730_64/bin/g++.exe"
  1. cmake ..:

    • 这部分表示运行 CMake 命令,并且 .. 表示 CMakeLists.txt 文件位于当前目录的上级目录。也就是说,你在构建目录中运行这个命令,而 CMakeLists.txt 文件位于构建目录的上一级。

  2. -G "MinGW Makefiles":

    • -G 选项用于指定 CMake 的生成器。这里的 "MinGW Makefiles" 表示使用 MinGW 的 makefile 生成器。这意味着 CMake 将生成适合 MinGW 的 makefile 文件,以便后续使用 mingw32-make 进行构建。

  3. -DCMAKE_PREFIX_PATH="E:/qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5":

    • -D 用于设置 CMake 的缓存变量。CMAKE_PREFIX_PATH 是一个变量,用于指定查找库、头文件等的前缀路径。这里设置为 Qt5 的安装路径,帮助 CMake 找到 Qt5 的库和相关文件。

  4. -DCMAKE_MAKE_PROGRAM="E:/qt/Qt5.14.2/Tools/mingw730_64/bin/mingw32-make.exe":

    • 这个选项明确指定了 CMAKE_MAKE_PROGRAM 变量,即用于构建项目的 make 程序路径。这里指向了 MinGW 的 mingw32-make.exe 可执行文件,确保 CMake 能够找到并使用正确的构建工具。

这里对我的CMakeLists.txt做了修改:

cmake_minimum_required(VERSION 3.10)
project(TestMinGw VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# === 主要修改点 1:移除 MSVC 特定的 Qt 路径 ===
set(Qt5_DIR "E:/qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5")

# 使用通用方式查找 Qt
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)

# 启用自动处理
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

# === 主要修改点 2:修复文件收集方式 ===
# 避免使用 GLOB(可能导致新文件不被检测)
set(SOURCES
    chatwidget.cpp
    friendlistwidget.cpp
    friendlistwidgetdelegate.cpp
    main.cpp
)

set(HEADERS
    chatwidget.h
    friendlistwidget.h
    friendlistwidgetdelegate.h
)

set(RESOURCES resource.qrc)

# 添加可执行文件
add_executable(${PROJECT_NAME}
    ${SOURCES}
    ${HEADERS}
    ${RESOURCES}
)

# 链接 Qt 库
target_link_libraries(${PROJECT_NAME}
    Qt5::Core
    Qt5::Gui
    Qt5::Widgets
)

# === 新增:MinGW 特定设置 ===
if(MINGW)
    # 解决 MinGW 资源文件路径问题
    set(CMAKE_RC_COMPILER_INIT windres)
    enable_language(RC)
    set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
endif()

用途

  • 这段代码用于检测当前的构建环境是否是 MinGW 环境。

  • 如果是,它会进行一些特定的配置,以确保 MinGW 正确处理资源文件(.rc 文件)。

具体配置解释

  • set(CMAKE_RC_COMPILER_INIT windres):设置资源编译器为 windres,这是 MinGW 用于处理 Windows 资源文件的工具。

  • enable_language(RC):启用资源语言(Resource Compiler),以便在构建过程中处理 .rc 文件。

  • set(CMAKE_RC_COMPILE_OBJECT ... ):定义资源文件的编译命令格式,确保资源文件被正确编译为对象文件。

场景

  • 这段代码通常用于处理 Windows 系统下的资源文件(如图标、菜单等),这些文件通常以 .rc 格式存在。

  • 当使用 MinGW 构建包含资源文件的项目时,这段代码确保资源文件被正确处理并链接到最终的可执行文件中。

不行的时候使用这个语句:

if (CMAKE_COMPILER_IS_GNUCXX)
    message(STATUS "Using MinGW compiler: ${CMAKE_CXX_COMPILER}")
else()
    message(FATAL_ERROR "MinGW compiler not found")
endif()

用途

  • 这段代码用于检查当前使用的 C++ 编译器是否是 GNU C++ 编译器(即 MinGW 的 g++ 编译器)。

  • 如果是,它会输出一条状态消息,显示当前使用的 C++ 编译器路径。

  • 如果不是,它会输出一条致命错误消息,指出没有找到 MinGW 编译器。

场景

  • 这段代码通常用于确保项目使用的是 MinGW 编译器,而不是其他编译器(如 MSVC)。

  • 如果你希望项目只能使用 MinGW 编译器进行构建,这段代码可以帮助你在构建过程中提前检测并避免使用错误的编译器。

注意此时环境变量的顺序

运行程序

在命令行直接输入可执行程序的路径(注意当前路径)

.\TestMinGw.exe

或者直接在文件中打开这个.exe文件

比较维度 MSVC (Microsoft Visual C++) MinGW (Minimalist GNU for Windows)
出品方 微软 GNU 社区、开源项目
血缘关系 微软原生编译器,Windows SDK 的一部分 GNU Compiler Collection (GCC) 的 Windows 端口
许可证 专有(但免费使用) 开源 (GPL)
开发环境 深度集成于 Visual Studio IDE 通常配合 Code::Blocks, CLion, VSCode 或命令行使用
运行时库 微软专属的 MSVCRT GNU 的 libstdc++ 和 MinGW 自实现的运行时
代码生成 针对 Windows 平台高度优化 通用性强,更接近 GCC 的行为
链接器 link.exe (微软) ld.exe (GNU Binutils)
调试器 集成在 VS 中的强大调试器 通常使用 GDB
二进制兼容性 不兼容 GCC,不同 VS 版本间的库也可能不兼容 兼容其他 GCC 编译的库(在相同架构下)
跨平台性 几乎为零,生成的程序严重依赖 Windows 的 VC++ 可再发行组件包 较好,依赖较少的额外 DLL

结语:

       随着这篇博客接近尾声,我衷心希望我所分享的内容能为你带来一些启发和帮助。学习和理解的过程往往充满挑战,但正是这些挑战让我们不断成长和进步。我在准备这篇文章时,也深刻体会到了学习与分享的乐趣。    

         在此,我要特别感谢每一位阅读到这里的你。是你的关注和支持,给予了我持续写作和分享的动力。我深知,无论我在某个领域有多少见解,都离不开大家的鼓励与指正。因此,如果你在阅读过程中有任何疑问、建议或是发现了文章中的不足之处,都欢迎你慷慨赐教。

        你的每一条反馈都是我前进路上的宝贵财富。同时,我也非常期待能够得到你的点赞、收藏,关注这将是对我莫大的支持和鼓励。当然,我更期待的是能够持续为你带来有价值的内容。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐