
从编译.cpp文件到CMake对于一个源文件main.cpp如何编译成可执行文件呢g -o main main.cpp以上只有一个源文件main.cpp然而一个实际的工程中其源文件一般有很多并且通常按照功能模块放在若干个目录中。此时如果每次都手动一条条执行编译命令很显然是不现实的因此就有了Makefile文件如下main: main.cpp g -o main main.cMakefile文件用于描述整个工程的编译、链接的规则。Makefile文件编写完毕之后编译整个工程你所要做的唯一的一件事就是执行make命令就可以将整个工程进行 “自动化编译”极大提高了效率。Make功能全面、程序员可直接编写Makefile文件。然而手写Makefile是比较困难而且容易出错尤其在进行跨平台开发时必须针对不同平台分别编写Makefile会增加跨平台开发难度。CMake会根据项目文件CMakeLists.txt文件内容自动生成Makefile或者build.ninja。CMake项目构建过程┌─────────────────┐ │ CMakeLists.txt │ (用户编写) └────────┬────────┘ ↓ ┌─────────────────┐ │ cmake │ (配置和生成) └────────┬────────┘ ↓ ┌─────────────────┐ │ Makefile │ (生成的构建文件) │ build.ninja │ │ .sln/.vcxproj │ └────────┬────────┘ ↓ ┌─────────────────┐ │ make/ninja/ │ (实际构建工具) │ msbuild │ └────────┬────────┘ ↓ ┌─────────────────┐ │ 可执行文件/库 │ (最终产物) └─────────────────┘常见CMake指令工程与版本声明新版必需cmake_minimum_required(VERSION 3.20) project(demo VERSION 1.0.0 LANGUAGES CXX)cmake_minimum_required指定最低 CMake 版本否则新版工程可能报版本过旧警告。project定义工程名、版本、使用语言C / CXX。变量与目录set(VAR value)定义变量${VAR}取值unset(VAR)删除变量add_subdirectory(subdir)引入子目录的 CMakeLists形成子作用域message(STATUS xxx)打印信息FATAL_ERROR则终止内置常用变量CMAKE_SOURCE_DIR工程根源码目录、CMAKE_CURRENT_SOURCE_DIR、CMAKE_BINARY_DIR构建根目录、CMAKE_CURRENT_BINARY_DIR、CMAKE_BUILD_TYPE。编译产物add_library(mylib STATIC a.cpp b.cpp) # 静态库SHARED 动态库 / INTERFACE 纯头文件库 add_executable(myapp main.cpp) # 可执行文件 target_sources(myapp PRIVATE extra.cpp) # 事后追加源文件add_library不写类型时默认STATIC取决于BUILD_SHARED_LIBS。INTERFACE库没有编译单元只用来传播头文件和链接依赖包含路径与链接target_include_directories(mylib PUBLIC include/) # 头文件搜索路径 target_link_libraries(myapp PRIVATE mylib fmt::fmt) # 链接库 target_compile_definitions(myapp PRIVATE -DDEBUG_MODE) # 编译宏 target_compile_options(mylib PRIVATE -Wall -Wextra) # 编译选项PUBLIC / PRIVATE / INTERFACE 三关键字是重点关键字自己用传给链接者PRIVATE✓✗INTERFACE✗✓PUBLIC✓✓即我需要的依赖是否也是我使用者的需要。Qt Creator中的CMake指令新建一个HellooQt 项目。配置# -S F:/qt_project/HelloQt # 指定源码目录Source # # -B F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug # 指定构建目录Build # # 作用CMake 读取 CMakeLists.txt并检测编译器MinGW g、查找 Qt6 库在构建目录中生成 build.ninja 等构建文件 cmake.exe -S F:/qt_project/HelloQt -B F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug构建# --build 进入编译阶段区别于 -S/-B 的配置阶段 # F:\qt_project\HelloQt\build\Desktop_Qt_6_10_2_MinGW_64_bit-Debug 指定构建目录 # --target all 指定构建目标为 all编译所有目标CMakeLists.txt 中定义的所有可执行文件和库 # # 这条命令是编译阶段CMake 本身并不直接编译而是作为统一入口自动调用底层构建工具 # cmake --build → 检测构建目录使用的构建系统 # ↓ # 发现 build.ninjaNinja 构建系统 # ↓ # 自动调用ninja.exe -f build.ninja all # 你无需关心底层是 Ninja 还是 Makecmake --build 统一封装了调用。 cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all点击【Build】-【Build Project “HelloQt”】在底部的 “Compile Output” 窗口显示的编译信息00:18:12: Starting: C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all [1/5 0.9/sec] Automatic MOC and UIC for target HelloQt [2/5 0.4/sec] Building CXX object CMakeFiles/HelloQt.dir/main.cpp.obj [3/5 0.7/sec] Building CXX object CMakeFiles/HelloQt.dir/HelloQt_autogen/mocs_compilation.cpp.obj [4/5 0.9/sec] Building CXX object CMakeFiles/HelloQt.dir/mywidget.cpp.obj [5/5 1.0/sec] Linking CXX executable HelloQt.exe 00:18:17: The command C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all finished successfully. 00:18:17: Elapsed time: 00:05.以上构建时的输出比较精简如果想查看完整的构建信息可以为CMake指定一个--verbose选项如下23:24:32: Running steps for project HelloQt... 23:24:32: Starting: C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all --verbose Change Dir: F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug Run Build Command(s): C:/msys64/ucrt64/bin/ninja.exe -v all [1/5 1.1/sec] C:\WINDOWS\system32\cmd.exe /C cd /D F:\qt_project\HelloQt\build\Desktop_Qt_6_10_2_MinGW_64_bit-Debug C:\Program Files\CMake\bin\cmake.exe -E cmake_autogen F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/CMakeFiles/HelloQt_autogen.dir/AutogenInfo.json Debug C:\Program Files\CMake\bin\cmake.exe -E touch F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/HelloQt_autogen/timestamp C:\Program Files\CMake\bin\cmake.exe -E cmake_transform_depfile Ninja gccdepfile F:/qt_project/HelloQt F:/qt_project/HelloQt F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/HelloQt_autogen/deps F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/CMakeFiles/d/16f2c0b2e7dc64d2f580d0d74891bb9b962b7f0d605002cb71edfbea8e0dc8ef.d [2/5 0.6/sec] C:\Qt\Tools\mingw1310_64\bin\g.exe -DMINGW_HAS_SECURE_API1 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NEEDS_QMAIN -DQT_WIDGETS_LIB -DUNICODE -DWIN32 -DWIN64 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_UNICODE -D_WIN64 -IF:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/HelloQt_autogen/include -isystem C:/Qt/6.10.2/mingw_64/include/QtCore -isystem C:/Qt/6.10.2/mingw_64/include -isystem C:/Qt/6.10.2/mingw_64/mkspecs/win32-g -isystem C:/Qt/6.10.2/mingw_64/include/QtWidgets -isystem C:/Qt/6.10.2/mingw_64/include/QtGui -DQT_QML_DEBUG -g -fdiagnostics-coloralways -MD -MT CMakeFiles/HelloQt.dir/HelloQt_autogen/mocs_compilation.cpp.obj -MF CMakeFiles\HelloQt.dir\HelloQt_autogen\mocs_compilation.cpp.obj.d -o CMakeFiles/HelloQt.dir/HelloQt_autogen/mocs_compilation.cpp.obj -c F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/HelloQt_autogen/mocs_compilation.cpp [3/5 0.9/sec] C:\Qt\Tools\mingw1310_64\bin\g.exe -DMINGW_HAS_SECURE_API1 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NEEDS_QMAIN -DQT_WIDGETS_LIB -DUNICODE -DWIN32 -DWIN64 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_UNICODE -D_WIN64 -IF:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/HelloQt_autogen/include -isystem C:/Qt/6.10.2/mingw_64/include/QtCore -isystem C:/Qt/6.10.2/mingw_64/include -isystem C:/Qt/6.10.2/mingw_64/mkspecs/win32-g -isystem C:/Qt/6.10.2/mingw_64/include/QtWidgets -isystem C:/Qt/6.10.2/mingw_64/include/QtGui -DQT_QML_DEBUG -g -fdiagnostics-coloralways -MD -MT CMakeFiles/HelloQt.dir/mywidget.cpp.obj -MF CMakeFiles\HelloQt.dir\mywidget.cpp.obj.d -o CMakeFiles/HelloQt.dir/mywidget.cpp.obj -c F:/qt_project/HelloQt/mywidget.cpp [4/5 1.2/sec] C:\Qt\Tools\mingw1310_64\bin\g.exe -DMINGW_HAS_SECURE_API1 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NEEDS_QMAIN -DQT_WIDGETS_LIB -DUNICODE -DWIN32 -DWIN64 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_UNICODE -D_WIN64 -IF:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug/HelloQt_autogen/include -isystem C:/Qt/6.10.2/mingw_64/include/QtCore -isystem C:/Qt/6.10.2/mingw_64/include -isystem C:/Qt/6.10.2/mingw_64/mkspecs/win32-g -isystem C:/Qt/6.10.2/mingw_64/include/QtWidgets -isystem C:/Qt/6.10.2/mingw_64/include/QtGui -DQT_QML_DEBUG -g -fdiagnostics-coloralways -MD -MT CMakeFiles/HelloQt.dir/main.cpp.obj -MF CMakeFiles\HelloQt.dir\main.cpp.obj.d -o CMakeFiles/HelloQt.dir/main.cpp.obj -c F:/qt_project/HelloQt/main.cpp [5/5 1.4/sec] C:\WINDOWS\system32\cmd.exe /C cd . C:\Qt\Tools\mingw1310_64\bin\g.exe -DQT_QML_DEBUG -g -mwindows CMakeFiles/HelloQt.dir/HelloQt_autogen/mocs_compilation.cpp.obj CMakeFiles/HelloQt.dir/main.cpp.obj CMakeFiles/HelloQt.dir/mywidget.cpp.obj -o HelloQt.exe -Wl,--out-implib,libHelloQt.dll.a -Wl,--major-image-version,0,--minor-image-version,0 C:/Qt/6.10.2/mingw_64/lib/libQt6Widgets.a C:/Qt/6.10.2/mingw_64/lib/libQt6Gui.a C:/Qt/6.10.2/mingw_64/lib/libQt6Core.a -lmpr -luserenv -lmingw32 C:/Qt/6.10.2/mingw_64/lib/libQt6EntryPoint.a -lshell32 -ld3d11 -ldxgi -ldxguid -ld3d12 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 cd . 23:24:36: The command C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all --verbose finished successfully. 23:24:36: Elapsed time: 00:04.清除# --build 进入编译阶段操作 # F:\qt_project\HelloQt\build\Desktop_Qt_6_10_2_MinGW_64_bit-Debug 指定构建目录 # --target clean 执行 清理目标删除编译产物 # # CMake 将此命令转交给底层 Ninja 执行 # cmake --build ... --target clean # ↓ # ninja.exe -f build.ninja clean # ↓ # 删除所有由编译产生的中间文件和输出文件 cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target cleanUIC在qt的bin文件夹下能找到uic.exeuic.exe可以将.ui文件(内部是xml文本)生成.h文件。uic工具会去解析.ui的xml格式文件依次读取其中的字段比如width、height、property等来生成对应的C代码。生成的.h文件可能为class Ui_MyWidget { public: QPushButton *btnStart; QPushButton *btnStop; void setupUi(QWidget *MyWidget) { if (MyWidget-objectName().isEmpty()) MyWidget-setObjectName(MyWidget); MyWidget-resize(800, 600); // 只有将 btnStart 的父窗口设置为传递过来的MyWidget才能在MyWidget show出来时才将 btnStart 也显示出来 btnStart new QPushButton(MyWidget); btnStart-setObjectName(btnStart); btnStart-setGeometry(QRect(230, 260, 131, 51)); // 只有将 btnStop 的父窗口设置为传递过来的MyWidget才能在MyWidget show出来时才将 btnStop 也显示出来 btnStop new QPushButton(MyWidget); btnStop-setObjectName(btnStop); btnStop-setGeometry(QRect(370, 260, 131, 51)); retranslateUi(MyWidget); QMetaObject::connectSlotsByName(MyWidget); } // setupUi void retranslateUi(QWidget *MyWidget) { MyWidget-setWindowTitle(QCoreApplication::translate(MyWidget, MyWidget, nullptr)); btnStart-setText(QCoreApplication::translate(MyWidget, START, nullptr)); btnStop-setText(QCoreApplication::translate(MyWidget, STOP, nullptr)); } // retranslateUi }; namespace Ui { // 这个Ui命名空间中的 MyWidget 类本身是空实现但是它继承自 Ui_MyWidget 类 // Ui_MyWidget 类就是和 mywidget.ui 这个xml文件一一对应的。 // 比如在ui设计界面拖放两个按钮可以在其xml文件中看到两个按钮的属性 // uic 工具就会根据xml文件中的属性在 ui_mywidget.h 文件中生成对应的代码 // 比如在ui设计界面设置两个按钮的文本为“START”和“STOP”调整坐标那么在生成的这个.h文件中就会生成对应的代码如上↑ class MyWidget: public Ui_MyWidget {}; } // namespace UiMOCMeta-Object Compiler元对象编译器简称moc是Qt 框架的核心工具之一负责处理 Qt 的元对象系统Meta-Object System。moc 是一个预处理器/代码生成器它读取 C 头文件通常是包含Q_OBJECT宏的类定义然后生成额外的 C 代码moc_*.cpp文件。这些生成的代码实现了 Qt 的元对象功能包括信号与槽Signals Slots实现对象间的松散耦合通信机制运行时类型信息RTTI提供QObject::metaObject()获取类的元数据动态属性系统支持运行时属性查询和修改国际化支持tr()函数的字符串翻译机制// widget.h #ifndef WIDGET_H #define WIDGET_H #include QWidget class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent nullptr); ~Widget(); }; #endif // WIDGET_H // widget.cpp #include widget.h Widget::Widget(QWidget *parent) : QWidget(parent) { } Widget::~Widget() { }经过moc可以将cpp文件生成 moc_.cpp文件其中包含信号的实现代码emit mySignal()实际调用的函数元对象表类名、方法、属性等元数据槽函数的调用分发逻辑#include memory #include ../../../../widget.h #include QtCore/qbytearray.h #include QtCore/qmetatype.h #if !defined(Q_MOC_OUTPUT_REVISION) #error The header file widget.h doesnt include QObject. #elif Q_MOC_OUTPUT_REVISION ! 67 #error This file was generated using the moc from 5.14.2. It #error cannot be used with the include files from this version of Qt. #error (The moc has changed too much.) #endif QT_BEGIN_MOC_NAMESPACE QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED struct qt_meta_stringdata_Widget_t { QByteArrayData data[1]; char stringdata0[7]; }; #define QT_MOC_LITERAL(idx, ofs, len) \ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ qptrdiff(offsetof(qt_meta_stringdata_Widget_t, stringdata0) ofs \ - idx * sizeof(QByteArrayData)) \ ) static const qt_meta_stringdata_Widget_t qt_meta_stringdata_Widget { { QT_MOC_LITERAL(0, 0, 6) // Widget }, Widget }; #undef QT_MOC_LITERAL static const uint qt_meta_data_Widget[] { // content: 8, // revision 0, // classname 0, 0, // classinfo 0, 0, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount 0 // eod }; void Widget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { Q_UNUSED(_o); Q_UNUSED(_id); Q_UNUSED(_c); Q_UNUSED(_a); } QT_INIT_METAOBJECT const QMetaObject Widget::staticMetaObject { { QMetaObject::SuperData::linkQWidget::staticMetaObject(), qt_meta_stringdata_Widget.data, qt_meta_data_Widget, qt_static_metacall, nullptr, nullptr } }; const QMetaObject *Widget::metaObject() const { return QObject::d_ptr-metaObject ? QObject::d_ptr-dynamicMetaObject() : staticMetaObject; } void *Widget::qt_metacast(const char *_clname) { if (!_clname) return nullptr; if (!strcmp(_clname, qt_meta_stringdata_Widget.stringdata0)) return static_castvoid*(this); return QWidget::qt_metacast(_clname); } int Widget::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id QWidget::qt_metacall(_c, _id, _a); return _id; } QT_WARNING_POP QT_END_MOC_NAMESPACE为什么需要 mocC 原生不支持反射和信号槽机制。moc 通过代码生成在编译期注入这些能力而不是依赖复杂的模板元编程或运行时开销较大的方案。这使得 Qt 能够在保持 C 性能的同时提供高级的动态特性。使用方式在现代 Qt 开发中moc 通常由构建系统自动调用qmake自动生成规则调用 mocCMake通过qt_wrap_cpp()或AUTOMOC选项自动处理将一些其他位置的接口文件添加到编译/构建手动qt5_wrap_cpp... set(ICONTROL_HEADER ${CMAKE_SOURCE_DIR}/src/App/IControl.h ) qt5_wrap_cpp(MOC_ICONTROL_SRCS ${ICONTROL_HEADER} ) # 添加到目标这才是真正使用 add_library(MyPlugin SHARED ${SOURCES} ${MOC_ICONTROL_SRCS} # 必须包含生成的 moc 文件 ) target_link_libraries(MyPlugin Qt5::Core)AUTOMOC# 并且项目启用了 AUTOMOC set(CMAKE_AUTOMOC ON) ... # 写法A file(GLOB HEADER ${CMAKE_SOURCE_DIR}/src/App/ITask.h ${CMAKE_SOURCE_DIR}/src/App/IProject.h ${CMAKE_SOURCE_DIR}/src/App/IMonitor.h ) # 这些 HEADER 被直接用在了 add_library 中 add_library(SomeTarget SHARED ${SOURCES} ${HEADER} # ← 头文件列在 target 的源文件里 ) # 写法B include_directories( ${CMAKE_SOURCE_DIR}/src/App/ ) add_library(SomeTarget SHARED ${SOURCES}) # 自动处理修改 CMake GeneratorCMake针对不同平台支持多种Generator生成器Ninja生成Ninja构建所需的所有文件Unix Makefiles生成Make构建所需的所有文件默认采用生成器为Ninja可以修改为其他比如Unix Makefiles修改为【Edit】-【Preferences…】-【Kits】默认ninja构建执行Cmake输出打印信息[cmake] Running C:\Program Files\CMake\bin\cmake.exe -S F:/qt_project/HelloQt -B F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug -DCMAKE_C_COMPILER:FILEPATHC:/Qt/Tools/mingw1310_64/bin/gcc.exe -DCMAKE_BUILD_TYPE:STRINGDebug -DQT_MAINTENANCE_TOOL:FILEPATHC:/Qt/MaintenanceTool.exe -DQT_QMAKE_EXECUTABLE:FILEPATHC:/Qt/6.10.2/mingw_64/bin/qmake.exe -DCMAKE_CXX_FLAGS_INIT:STRING-DQT_QML_DEBUG -DCMAKE_CXX_COMPILER:FILEPATHC:/Qt/Tools/mingw1310_64/bin/g.exe -DCMAKE_GENERATOR:STRINGNinja -DCMAKE_PREFIX_PATH:PATHC:/Qt/6.10.2/mingw_64 -DCMAKE_COLOR_DIAGNOSTICS:BOOLON -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATHF:\qt_project\HelloQt\build\Desktop_Qt_6_10_2_MinGW_64_bit-Debug/.qtc/package-manager/auto-setup.cmake in F:\qt_project\HelloQt\build\Desktop_Qt_6_10_2_MinGW_64_bit-Debug. [cmake] -- The CXX compiler identification is GNU 13.1.0 [cmake] -- Detecting CXX compiler ABI info [cmake] -- Detecting CXX compiler ABI info - done [cmake] -- Check for working CXX compiler: C:/Qt/Tools/mingw1310_64/bin/g.exe - skipped [cmake] -- Detecting CXX compile features [cmake] -- Detecting CXX compile features - done [cmake] -- Performing Test HAVE_STDATOMIC [cmake] -- Performing Test HAVE_STDATOMIC - Success [cmake] -- Configuring done (2.2s) [cmake] -- Generating done (0.1s) [cmake] -- Build files have been written to: F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug [cmake] [cmake] Elapsed time: 00:02.点击【构建】观察到编译构建信息00:18:12: Starting: C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all [1/5 0.9/sec] Automatic MOC and UIC for target HelloQt [2/5 0.4/sec] Building CXX object CMakeFiles/HelloQt.dir/main.cpp.obj [3/5 0.7/sec] Building CXX object CMakeFiles/HelloQt.dir/HelloQt_autogen/mocs_compilation.cpp.obj [4/5 0.9/sec] Building CXX object CMakeFiles/HelloQt.dir/mywidget.cpp.obj [5/5 1.0/sec] Linking CXX executable HelloQt.exe 00:18:17: The command C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all finished successfully. 00:18:17: Elapsed time: 00:05.改为make构建修改为Make构建也就是Generator指定为 “Unix Makefiles”。此时执行CMake配置输出打印信息如下[cmake] Running C:\Program Files\CMake\bin\cmake.exe -S F:/qt_project/HelloQt -B F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug -DCMAKE_BUILD_TYPE:STRINGDebug -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATHF:\qt_project\HelloQt\build\Desktop_Qt_6_10_2_MinGW_64_bit-Debug/.qtc/package-manager/auto-setup.cmake -DCMAKE_CXX_FLAGS_INIT:STRING-DQT_QML_DEBUG -DCMAKE_PREFIX_PATH:PATHC:/Qt/6.10.2/mingw_64 -DQT_MAINTENANCE_TOOL:FILEPATHC:/Qt/MaintenanceTool.exe -DCMAKE_COLOR_DIAGNOSTICS:BOOLON -DCMAKE_GENERATOR:STRINGUnix Makefiles -DQT_QMAKE_EXECUTABLE:FILEPATHC:/Qt/6.10.2/mingw_64/bin/qmake.exe -DCMAKE_C_COMPILER:FILEPATHC:/Qt/Tools/mingw1310_64/bin/gcc.exe -DCMAKE_CXX_COMPILER:FILEPATHC:/Qt/Tools/mingw1310_64/bin/g.exe in F:\qt_project\HelloQt\build\Desktop_Qt_6_10_2_MinGW_64_bit-Debug. [cmake] -- The CXX compiler identification is GNU 13.1.0 [cmake] -- Detecting CXX compiler ABI info [cmake] -- Detecting CXX compiler ABI info - done [cmake] -- Check for working CXX compiler: C:/Qt/Tools/mingw1310_64/bin/g.exe - skipped [cmake] -- Detecting CXX compile features [cmake] -- Detecting CXX compile features - done [cmake] -- Performing Test HAVE_STDATOMIC [cmake] -- Performing Test HAVE_STDATOMIC - Success [cmake] -- Configuring done (3.6s) [cmake] -- Generating done (0.1s) [cmake] -- Build files have been written to: F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug [cmake] [cmake] Elapsed time: 00:04.点击【构建】观察到编译构建信息00:36:03: Running steps for project HelloQt... 00:36:03: Starting: C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all [ 0%] Built target HelloQt_autogen_timestamp_deps [ 20%] Automatic MOC and UIC for target HelloQt [ 20%] Built target HelloQt_autogen [ 40%] Building CXX object CMakeFiles/HelloQt.dir/HelloQt_autogen/mocs_compilation.cpp.obj [ 60%] Building CXX object CMakeFiles/HelloQt.dir/main.cpp.obj [ 80%] Building CXX object CMakeFiles/HelloQt.dir/mywidget.cpp.obj [100%] Linking CXX executable HelloQt.exe [100%] Built target HelloQt 00:36:15: The command C:\Program Files\CMake\bin\cmake.exe --build F:/qt_project/HelloQt/build/Desktop_Qt_6_10_2_MinGW_64_bit-Debug --target all finished successfully. 00:36:15: Elapsed time: 00:12.运行设置点击左侧的【Projects】可以打开当前项目的运行设置界面如下如果指定了命令行参数可以在main.cpp中添加如下代码来打印命令行参数如下qDebug() 参数个数 argc; qDebug() 参1 argv[0]; qDebug() 参2 argv[1]; qDebug() 参3 argv[2];执行结果参数个数 3 参1 F:\qt_project\HelloQt\debug\HelloQt.exe 参2 123 参3 456