CMake+QT使用教程

2023-05-16

一、CMake入门

下面是使用 Qt 用 C++ 编写的控制台应用程序的典型文件:CMakeLists.txt

1.构建一个控制台应用程序

# 指定应用程序所需的CMake最低版本(Qt本身至少需要CMake版本3.16)
cmake_minimum_required(VERSION 3.16)

# 设置项目名称和默认项目版本,同时告诉CMake该程序是用C++编写的
project(helloworld VERSION 1.0.0 LANGUAGES CXX)

# 设置变量CMAKE_CXX_STANDARD,指定C++版本(QT6需要支持c++ 17或更新版本的编译器)
# 设置变量CMAKE_CXX_STANDARD_REQUIRED,如果编译器太旧,让CMake打印一个错误
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 设置CMake查找Qt6,并导入模块Core
# 如果CMake找不到模块,设置标志REQUIRED让CMake终止
# 如果成功,CMake将设置一些变量,这些变量记录在模块变量中(见变量参考Module variables)
# 为了能找到依赖包,CMake可以设置变量CMAKE_PREFIX_PATH包含Qt6安装前缀
find_package(Qt6 REQUIRED COMPONENTS Core)

# qt_standard_project_setup命令为一般的QT应用程序设置项目范围的默认值
# 除此之外,该命令将CMAKE_AUTOMOC变量设置为ON,指示CMake自动设置规则,以便在需要时透明地调用Qt的元对象编译器(moc)。
qt_standard_project_setup()

# add_executable命令告诉CMake从指定源文件构建一个可执行文件(而不是库)
# 注意,这里通常不列出头文件。这与qmake不同,qmake需要显式列出头文件,以便元对象编译器(moc)处理它们。
# 对于比较复杂的项目需要改为调用qt_add_executable(),它是内置add_executable()命令的包装器,提供了额外的逻辑来自动处理诸如在静态Qt构建中链接Qt插件、特定于平台的库名定制等。
# 要创建库,使用qt_add_library。
add_executable(helloworld
    main.cpp
)

# 最后告诉CMake, helloworld可执行文件通过引用由上面的find_package()调用导入的Qt6::Core目标来使用Qt的Core模块。这不仅可以为链接器添加正确的参数,还可以确保将正确的include目录、编译器定义传递给c++编译器。PRIVATE关键字对于可执行目标并不是严格必要的,但是指定它是一种良好的实践。
# 如果helloworld是一个库而不是可执行文件,则应该指定PRIVATE或PUBLIC(如果库在头文件中提到了来自Qt6::Core的内容,则为PUBLIC,否则为PRIVATE)
target_link_libraries(helloworld PRIVATE Qt6::Core)

2.构建一个界面应用程序

cmake_minimum_required(VERSION 3.16)

project(helloworld VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()

add_executable(helloworld
    mainwindow.ui
    mainwindow.cpp
    main.cpp
)

target_link_libraries(helloworld PRIVATE Qt6::Widgets)

# 最后,我们在应用程序目标上设置属性,效果如下:
# 防止在Windows上创建控制台窗口。
# 在macOS上创建应用程序包。
set_target_properties(helloworld PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)

3.构建子目录项目

  • 项目目录结构
<project root>
├── CMakeLists.txt
└── src
    └── app
        ├── CMakeLists.txt
        ├── main.cpp
        ├── mainwindow.cpp
        ├── mainwindow.h
        └── mainwindow.ui
  • 顶层CMakeLists.txt,包含整个项目的设置并调用add_subdirectory,顶层CMakeLists.txt设置的变量在子目录项目中可见
cmake_minimum_required(VERSION 3.16)

project(helloworld VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()

add_subdirectory(src/app)
  • 子目录项目CMakeLists.txt
add_executable(helloworld
    mainwindow.ui
    mainwindow.cpp
    main.cpp
)

target_link_libraries(helloworld PRIVATE Qt6::Widgets)

set_target_properties(helloworld PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)

4.构建库和使用库

  • 项目目录结构
<project root>
├── CMakeLists.txt
└── src
    ├── app
    │   ├── ...
    │   └── main.cpp
    └── businesslogic
        ├── CMakeLists.txt
        ├── businesslogic.cpp
        └── businesslogic.h
  • 库项目文件(src/businesslogic/CMakeLists.txt)
# add_library命令创建businesslogic库,STATIC表示静态库,SHARED表示动态库
add_library(businesslogic STATIC
    businesslogic.cpp
)

target_link_libraries(businesslogic PRIVATE Qt6::Core)

# 通过调用target_include_directories,确保businesslogic目录的绝对路径被自动添加为使用我们的库的所有目标的包含路径。
# 这使我们在main.cpp中不用使用相对路径来定位businesslogic.h。相反,我们可以直接写#include <businesslogic.h>
target_include_directories(businesslogic INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

最后,我们必须将库的子目录添加到顶级项目文件中:

add_subdirectory(src/app)
add_subdirectory(src/businesslogic)
  • 使用库
target_link_libraries(helloworld PRIVATE
    businesslogic
    Qt6::Widgets)

5.添加资源

qt_add_resources(helloworld imageresources
    PREFIX "/images"
    FILES logo.png splashscreen.png
)

用法:

logoLabel->setPixmap(QPixmap(":/images/logo.png"));

6.添加翻译

qt_add_translations(helloworld
    TS_FILES helloworld_de.ts helloworld_fr.ts)

要更新.ts文件中的条目,构建update_translations目标:

$ cmake --build . --target update_translations

要手动触发.qm文件的生成,构建release_translations目标:

$ cmake --build . --target release_translations

二、CMake命令参考(CMake Command Reference)

  • Qt6::Core

    CMake命令描述
    qt_add_big_resources将大型二进制资源编译为目标代码
    qt_add_binary_resources从 Qt 资源文件列表创建 RCC 文件
    qt_add_executable创建并最终确定指定平台类型的应用程序目标
    qt_add_library创建并完成库
    qt_add_plugin创建 Qt 插件目标
    qt_add_resources将二进制资源编译为源代码
    qt_allow_non_utf8_sources防止强制将源文件视为适用于 Windows 的 UTF-8
    qt_android_add_apk_target定义运行安卓部署qt以生成APK的构建目标
    qt_android_apply_arch_suffix将目标二进制文件的名称配置为包含特定于体系结构的后缀
    qt_android_generate_deployment_settings生成 androiddeployqt 所需的部署设置文件
    qt_deploy_qt_conf在部署时编写 qt.conf 文件
    qt_deploy_runtime_dependencies部署可执行文件所需的Qt插件,Qt和非Qt库
    qt_disable_unicode_defines防止在目标上自动设置某些与 Unicode 相关的编译器定义
    qt_extract_metatypes防止在目标上自动设置某些与 Unicode 相关的编译器定义
    qt_finalize_project处理与Qt项目相关的各种常见平台特定任务
    qt_finalize_target处理与Qt目标相关的各种常见平台特定任务
    qt_generate_deploy_app_script为应用程序生成部署脚本
    qt_generate_moc对输入文件调用 moc
    qt_import_plugins指定要为静态Qt构建导入的自定义插件集
    qt_set_finalizer_mode自定义目标最终确定的各个方面
    qt_standard_project_setup将项目范围的默认设置设置为标准排列
    qt_wrap_cpp从源文件创建.moc文件
  • Qt6::DBus

    CMake命令描述
    qt_add_dbus_adaptor将项目范围的默认设置设置为标准排列
    qt_add_dbus_interface生成实现 D-Bus 接口描述文件接口的C++源
    qt_add_dbus_interfaces生成实现 D-Bus 接口描述文件接口的C++源
    qt_generate_dbus_interface从头文件生成 D-Bus 接口
  • Qt6::InterfaceFramework

    CMake命令描述
    qt_ifcodegen_extend_target使用从 qface IDL 文件生成的文件扩展目标
    qt_ifcodegen_generate从 qface IDL 文件生成文件
    qt_ifcodegen_import_variables从 qface IDL 文件生成文件,并提供变量以在 CMake 中使用
    qt_set_ifcodegen_variable将变量设置为 ifcodegen 模板中的给定 c 值
  • Qt6::LinguistTools

    CMake命令描述
    qt_add_lrelease添加目标以将Qt语言学家.ts文件转换为.qm文件
    qt_add_lupdate添加目标以生成或更新Qt语言学家.ts文件
    qt_add_translation添加目标以生成或更新Qt语言学家.ts文件
    qt_add_translations添加目标以更新Qt Linguist .ts文件并将其转换为.qm文件
    qt_create_translation设置Qt语言学家翻译工具链
  • Qt6::Qml

    CMake命令描述
    qt_add_qml_module设置Qt语言学家翻译工具链
    qt_add_qml_plugin定义与 QML 模块关联的插件
    qt_deploy_qml_imports部署可执行文件所需的 QML 模块的运行时组件
    qt_generate_deploy_qml_app_script为 QML 应用程序生成部署脚本
    qt_generate_foreign_qml_types在 QML 模块中注册来自一个目标的类型
    qt_import_qml_plugins确保为静态构建导入目标所需的 QML 插件
    qt_query_qml_module检索有关 QML 模块的信息
    qt_target_compile_qml_to_cpp
    qt_target_qml_sources检索有关 QML 模块的信息
  • Qt6::RemoteObjects

    CMake命令描述
    qt_add_repc_merged从 Qt 远程对象 .rep 文件为源和副本类型创建C++头文件
    qt_add_repc_replicas从 Qt 远程对象 .rep 文件为副本类型创建C++头文件
    qt_add_repc_sources从 Qt 远程对象 .rep 文件为源类型创建C++头文件
    qt_reps_from_headers从 QObject 头文件创建 .rep 文件
  • Qt6::Scxml

    CMake命令描述
    qt_add_statecharts
  • Qt6::ShaderTools

    CMake命令描述
    Qt Shader Tools Build System Integration编译着色器并将其添加到Qt资源
  • Qt6::Widgets

    CMake命令描述
    qt_wrap_ui编译着色器并将其添加到Qt资源
  • Qt6::WebEngineCore

    CMake命令描述
    qt_add_webengine_dictionary将 hunspell 字典格式转换为 bdict 二进制格式

三、CMake变量参考(CMake Variable Reference)

1.模块变量(Module variables)

变量描述
Qt6Widgets_COMPILE_DEFINITIONS针对库构建时使用的编译定义列表。
Qt6Widgets_DEFINITIONS针对库进行构建时使用的定义列表。
Qt6Widgets_EXECUTABLE_COMPILE_FLAGS针对库构建可执行文件时使用的标志字符串。
Qt6Widgets_FOUND描述是否成功找到模块的布尔值。
Qt6Widgets_INCLUDE_DIRS针对库构建时使用的包含目录列表。
Qt6Widgets_LIBRARIES模块导入的目标的名称:Qt5::Widgets
Qt6Widgets_PRIVATE_INCLUDE_DIRS在构建库和使用私有Qt API时使用的私有包含目录列表。
Qt6Widgets_VERSION_STRING包含模块版本的字符串。

2.安装变量(Installation variables)

变量描述
QT_DEFAULT_MAJOR_VERSION在混合Qt 5和Qt 6项目的情况下,在调用相应的find_package()之前,需要将其设置为5或6。如果未设置,第一次find_package调用将定义默认版本。
QT_LIBINFIX当Qt配置了-libinfix时,保存库名称中使用的中缀的字符串。
QT_NO_CREATE_VERSIONLESS_FUNCTIONS隐藏以qt_开头的命令,只保留以qt6_开头的版本化命令。
QT_NO_CREATE_VERSIONLESS_TARGETS隐藏导入的以Qt::开头的目标。相反,您需要使用以Qt6::开头的目标。
QT_VISIBILITY_AVAILABLE在Unix上,一个布尔值,用于描述Qt库和插件是否使用-fvisibility=hidden进行编译。这意味着只导出选定的符号。

3.项目变量(Project variables)

  • Qt6::Core

变量描述
ANDROID_NDK_HOST_SYSTEM_NAME特定于android的主机系统架构
ANDROID_SDK_ROOTAndroid SDK的位置
QT_ANDROID_ABIS为其构建项目包的abi列表
QT_ANDROID_APPLICATION_ARGUMENTS要传递给Android应用程序的参数列表
QT_ANDROID_BUILD_ALL_ABIS允许使用自动检测的Qt for Android SDK列表构建多abi包
QT_ANDROID_MULTI_ABI_FORWARD_VARS允许在多个abi构建中共享CMake变量
QT_ANDROID_SIGN_AAB使用指定的密钥库、别名和存储密码对.aab包进行签名
QT_ANDROID_SIGN_APK使用指定的密钥库、别名和存储密码对包进行签名
QT_DEPLOY_BIN_DIR前缀-相对子目录,用于在某些目标平台上部署运行时二进制文件
QT_DEPLOY_LIB_DIR前缀相对子目录,用于在某些目标平台上部署库
QT_DEPLOY_PLUGINS_DIR前缀-相对子目录,用于在一些目标平台上部署Qt插件
QT_DEPLOY_PREFIX部署的基本位置
QT_DEPLOY_QML_DIR前缀-相对子目录,用于在一些目标平台上部署QML插件
QT_DEPLOY_SUPPORT要包括用于设置部署支持的文件的名称
QT_ENABLE_VERBOSE_DEPLOYMENT启用部署工具的详细模式
QT_HOST_PATH交叉编译时主机Qt安装的位置
QT_IOS_LAUNCH_SCREEN所有目标使用的iOS启动屏幕故事板的路径
QT_NO_COLLECT_BUILD_TREE_APK_DEPS防止在Android部署期间收集项目构建的共享库目标
QT_NO_SET_XCODE_BUNDLE_IDENTIFIER在iOS上禁用在目标终结期间提供备用应用程序包ID
QT_NO_SET_XCODE_DEVELOPMENT_TEAM_ID在iOS上禁用在目标完成过程中提供备用团队ID
QT_NO_STANDARD_PROJECT_SETUP防止后续对qt_standard_project_setup()的调用进行任何更改
QT_PATH_ANDROID_ABI_为相应的ABI指定Qt for Android路径的变量集
  • Qt6::Qml

变量描述
QT_QML_OUTPUT_DIRECTORY默认情况下将在其下面创建QML模块的基本输出目录
  • Qt6::InterfaceFramework

变量描述
IFCODEGEN_VERBOSE为所有ifcodegen函数启用详细日志记录
QT_IFCODEGEN_TEMPLATE_SEARCH_PATHifcodegen模板的搜索路径

四、CMake属性参考(CMake Property Reference)

  • Qt6::Core

    目标属性

属性描述
QT_ANDROID_ABIS为单个目标的包构建的abi列表
QT_ANDROID_DEPLOYMENT_DEPENDENCIES覆盖添加到目标部署中的Qt依赖项
QT_ANDROID_DEPLOYMENT_SETTINGS_FILE指定目标生成的部署设置文件的位置
QT_ANDROID_EXTRA_LIBS要与目标一起部署的额外库
QT_ANDROID_EXTRA_PLUGINS额外的Qt插件与目标一起部署
QT_ANDROID_MIN_SDK_VERSIONAndroid SDK最低版本
QT_ANDROID_NO_DEPLOY_QT_LIBSQt共享库是否打包在Android的APK中
QT_ANDROID_PACKAGE_SOURCE_DIR自定义Android包模板的路径
QT_ANDROID_SDK_BUILD_TOOLS_REVISIONAndroid构建工具的修订使用
QT_ANDROID_SYSTEM_LIBS_PREFIX指定Qt库在目标设备上的位置
QT_ANDROID_TARGET_SDK_VERSIONAndroid目标SDK版本
QT_ANDROID_VERSION_CODEAndroid内部应用版本
QT_ANDROID_VERSION_NAME可读的安卓应用版本
QT_IOS_LAUNCH_SCREENiOS启动屏幕故事板的路径
QT_QML_IMPORT_PATH指定要搜索QML导入的目录列表
QT_QML_ROOT_PATH覆盖应用程序qml目录的位置
QT_RESOURCE_PREFIX指定默认的Qt资源前缀
QT_WASM_INITIAL_MEMORY内部WebAssembly初始内存
QT_WASM_PTHREAD_POOL_SIZE内部WebAssembly线程池大小
qt_no_entrypoint指定禁止链接到Qt的入口点库

源文件属性

属性描述
QT_RESOURCE_ALIAS为资源中的文件指定Qt资源别名
  • Qt6::DBus

源文件属性

属性描述
CLASSNAME覆盖默认的接口类名
INCLUDE添加一个包含路径
NO_NAMESPACE禁止生成名称空间名称
  • Qt6::Qml

源文件属性

属性描述
QT_QMLTC_FILE_BASENAME指定非默认的.h和.cpp文件名
QT_QML_INTERNAL_TYPE将QML文件标记为提供内部类型
QT_QML_SINGLETON_TYPE将QML文件标记为提供单例类型
QT_QML_SKIP_CACHEGEN不允许将文件编译为字节代码
QT_QML_SKIP_QMLDIR_ENTRY排除一个文件作为类型添加到QML模块的typeinfo文件
QT_QML_SKIP_QMLLINT防止一个文件被自动qmllint处理
QT_QML_SKIP_TYPE_COMPILER不允许使用qmltc将文件编译为c++
QT_QML_SOURCE_TYPENAME重写文件提供的类型名称
QT_QML_SOURCE_VERSIONS指定类型的自定义版本集
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake+QT使用教程 的相关文章

随机推荐

  • 【工作遇到的问题——已解决】pip3 install numpy失败

    问题描述 需求 xff1a 求出列表中90 的响应时间 xff1a import numpy as np span class token keyword for span i in finalvalues span class token
  • 7、CAS

    目录 1 CAS是什么 1 1 CAS基本知识 1 2 CAS基本思想 2 对原子类中使用的CAS进行分析 2 1 CAS demo 代码 2 2 源码分析 3 原子类 3 1 有那些属性 用AtomicInteger分析 3 2 Unsa
  • ubuntu设置网络代理在内网中使用 apt代理、docker代理

    ubuntu设置apt 代理 编辑apt 配置文件 span class token function sudo span span class token function vim span etc apt apt conf 添加以下内容
  • 通过VNC远程连接ubuntu桌面(多种客户端连接方式)

    背景 有些时候一些设备不带显示器和键盘鼠标 xff0c 我们来维护他 xff0c 是通过ssh远程连接进行操作 但可能有些维护需要有图形显示来操作 xff0c 这时候再用ssh就不是很合适了 我所遇的设备情况是 xff0c 经常要自己接入显
  • 选择悖论:开源网络操作系统(NOS)重启指南

    我们拥有的选择越多 xff0c 就越不满足 然而 xff0c 只有手握选择权 xff0c 才能在决策之时享受自由和自主 这就是众所周知的选择悖论 当你打算从亨氏旗下的57种薯片 xff08 我的美国朋友们把它叫做chips xff09 中挑
  • Bottom-Up and Top-Down Attention for Image Captioning and Visual Question Answering

    一 摘要 自下而上的机制 基于 Faster R CNN xff1a 提取出图像区域 xff0c 每个区域都有一个相关的特征向量 自上而下的机制 xff1a 确定特征权重 提出了一种自下而上和自上而下的结合注意力机制 xff0c 使注意力能
  • 在keras环境下将numpy数据形式转换为tensor

    目录 前期尝试试错最终的解决方法 前期尝试 因为刚刚开始学习 xff0c 想要记录一下自己学习的全过程 xff0c 所以想知道具体方法的可以直接在目录跳到最后 xff1a 最终的解决方法 最近开始接触神经网络的学习 xff0c 在看过一个比
  • SSH测试远程服务器端口的连通性

    ssh是linux的标准配置并且最常用 xff0c 可以用来判断端口是否打开 用法 ssh v p port username 64 ip v 详细模式 会打印日志 xff0c 显示登录的细节 p 指定端口 username 可以随意 ip
  • hadoop单表关联

    1 单表关联 实例描述 实例中给出child parent xff08 孩子 父母 xff09 表 xff0c 要求输出grandchild grandparent xff08 孙子 爷奶 xff09 表 样例输入 如下所示 file xf
  • 调试带有源码的dll

    环境 windows 7 Visual Studio 2010 将dll项目debug目录下的 dll lib pdb文件拷贝到exe项目程序的debug目录下 xff08 是exe所在的文件夹 xff09 在调用dll里面的函数前面增加断
  • 遍地开花的 Attention ,你真的懂吗?

    阿里妹导读 xff1a 曾被 paper 中各种各样的 Attentioin 搞得晕晕乎乎 xff0c 尽管零零散散地整理过一些关于Attention 的笔记 xff0c 重点和线索依然比较凌乱 今天 xff0c 阿里巴巴工程师楠易 xff
  • Javaweb期末复习大纲

    20 21 2022 学年第 1 学期考试复习纲要 题型 xff1a 一 单项选择题 二 多选题 三 判断题 四 填空题 五 简答题 六 补充程序 重点复习章节及知识点 xff1a 第3章重点记忆归纳 xff1a xff08 题目分布 xf
  • Python 装饰器的三种用法及使用示例

    文章目录 前言装饰器三种用法包括 xff1a 不带参数的装饰器 带参数的装饰器 创建装饰器类 总结 前言 装饰器的作用主要是在不影响函数逻辑的情况下 xff0c 扩展其某个常用功能 xff0c 常用于为函数添加事件记录 例如当需要给创建的所
  • pip3在Ubuntu下的安装、升级、卸载

    参考资料 pip 常用命令 pip 官方文档 一 常用命令 1 在线安装 gt gt sudo apt get install python3 pip 1 1 离线安装 下载get pip py脚本 wget https bootstrap
  • 光立方原理图理解

    原文链接 xff08 点击原文链接获取更多学习干货 xff09 xff1a http blog bools cn archives 850 光立方原理图理解 一 淘宝提供的原理图版本1版本2我AD画的原理图一点点小技巧 xff1a 我不知道
  • 三种常用的LED驱动电源电路图详解

    时间 xff1a 2017 07 10 15 30 43 关键字 xff1a LED电路 led驱动电源 led电源电路图 LED电源有很多种类 xff0c 各类电源的质量 价格差异非常大 xff0c 这也是影响产品质量及价格的重要因素之一
  • haar+adaboost结合讲解(偏重实际)

    这是一篇之前总结的文档 xff0c 大部分来源于csdn和文献 xff0c 如有未标明引用 xff0c 请联系我加上 目录 1 Haar特征和积分图 1 1 Haar特征的生成 1 2 计算Haar特征值 1 3 Haar特征值归一化 1
  • 【ROS】在 Ubuntu 20.04 安装 ROS 的详细教程

    ROS安装指南 目录 ROS安装指南 前言 一 配置Linux清华镜像源1 1 介绍1 2 开始配置 二 安装ROS2 1 ROS的介绍2 1 开始安装 xff1a 配置公钥2 2 系统更新2 3 安装ROS 三 配置ROS3 1 初始化r
  • Python2.7安装教程

    Python安装教程 1 下载安装包 链接 xff1a https www python org downloads release python 2712 根据自己的系统选择对应的版本 注意 必须在全英文路径下安装 2 双击下载的安装程序
  • CMake+QT使用教程

    一 CMake入门 下面是使用 Qt 用 C 43 43 编写的控制台应用程序的典型文件 xff1a CMakeLists txt 1 构建一个控制台应用程序 span class token comment 指定应用程序所需的CMake最