Qt5 CMake 使用指南
Qt5 CMake 使用指南
CMAKE_PREFIX_PATH的使用说明
CMAKE_PREFIX_PATH是CMake中一个重要的环境变量,它用于帮助CMake在配置项目时找到各种依赖项的位置。这个变量尤其在处理那些不在标准位置安装的库时显得非常有用。
作用
CMAKE_PREFIX_PATH指定了一系列的路径,CMake会在这些路径中搜索需要的包、库、工具等。当使用find_package、find_library、find_file等命令时,CMake会优先在CMAKE_PREFIX_PATH指定的路径中查找。
设置方法
CMAKE_PREFIX_PATH可以通过多种方式设置,包括在命令行中直接设置,或者在CMakeLists.txt文件中设置。
在命令行中设置
在命令行中设置CMAKE_PREFIX_PATH,可以在调用cmake命令时使用-D选项:
这种方法适用于临时指定某个依赖项的路径。
在CMakeLists.txt中设置
也可以在CMakeLists.txt文件中通过set命令设置CMAKE_PREFIX_PATH:
这种方法适用于项目中有固定依赖路径的情况,可以确保所有人在构建项目时使用相同的路径。
注意事项
CMAKE_PREFIX_PATH可以包含多个路径,路径之间使用分号(;)分隔。
CMake中使用find_package查找Qt5
find_package命令在CMake中用于查找并加载指定的包(在这里是Qt5)。这个命令会检查系统中是否安装了指定的包,并提供必要的变量和目标,以便在项目中使用这些包。
使用find_package查找Qt5
当你需要在你的CMake项目中使用Qt5时,可以通过find_package命令来查找Qt5及其组件。以下是一个示例,展示了如何查找Qt5的核心组件,包括Core、Gui、Widgets和Multimedia:
find_package(Qt5 REQUIRED COMPONENTS
        Core
        Gui
        Widgets
        Multimedia
)
参数解释
REQUIRED:这个参数指示如果找不到Qt5或指定的组件,CMake应该终止配置过程。
COMPONENTS:后面跟随的是你希望在项目中使用的Qt5组件列表。在这个例子中,我们指定了Core、Gui、Widgets和Multimedia。
配置项目使用Qt5
在使用find_package成功找到Qt5之后,你可以通过链接目标库的方式,将Qt5组件添加到你的目标(例如可执行文件或库)中:
# 假设你的项目是一个可执行文件
add_executable(my_app
    main.cpp
    # 其他源文件
)
# 链接Qt5库
target_link_libraries(my_app
    Qt5::Core
    Qt5::Gui
    Qt5::Widgets
    Qt5::Multimedia
)
注意事项
确保在调用find_package之前,你的系统已经正确安装了Qt5,并且CMAKE_PREFIX_PATH环境变量已经设置为Qt5的安装路径。这样CMake才能正确找到Qt5。
如果你的项目中使用了Qt特有的代码(如MOC、UI文件等),还需要在CMakeLists.txt中相应配置,例如启用AUTOMOC或使用qt5_wrap_ui处理UI文件。
在CMake中设置WIN32_EXECUTABLE选项构建非控制台程序
在使用CMake构建Windows应用程序时,WIN32_EXECUTABLE选项用于指定生成的是一个Windows应用程序,而不是控制台应用程序。这个选项通常在调用add_executable函数时使用,以确保应用程序在没有控制台窗口的情况下运行。
使用WIN32_EXECUTABLE选项
当你希望你的应用程序作为一个GUI应用程序运行,而不是在命令行窗口中运行时,可以在add_executable命令中使用WIN32标志。对于CMake版本3.14及以上,可以使用WIN32_EXECUTABLE目标属性来更明确地控制这一行为。
cmake_minimum_required(VERSION 3.14)
project(MyApp)
# 设置源文件
set(SOURCE_FILES main.cpp)
# 添加一个可执行文件
add_executable(${PROJECT_NAME} WIN32 ${SOURCE_FILES})
# 对于CMake 3.14及以上版本,可以使用WIN32_EXECUTABLE目标属性
set_target_properties(${PROJECT_NAME} PROPERTIES
    WIN32_EXECUTABLE ON
)
qt5 设置Windows应用程序图标
在CMake项目中,你可以通过指定资源文件来设置Windows应用程序的图标。这通常通过在项目的CMakeLists.txt文件中设置一个变量来实现,该变量指向包含图标资源的.rc文件。
以下是如何在CMake项目中设置Windows应用程序图标的示例:
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/icon.rc")
参数解释
- APP_ICON_RESOURCE_WINDOWS:这是一个自定义变量名,用于存储图标资源文件的路径。
- ${CMAKE_CURRENT_SOURCE_DIR}:这是一个CMake变量,指向当前处理的- CMakeLists.txt文件所在的目录。
- /icon.rc:这是图标资源文件的相对路径和文件名。假设这个文件位于与当前- CMakeLists.txt文件同一目录下。
使用资源文件
在设置了包含图标资源的.rc文件路径后,你需要将这个资源文件包含到你的应用程序中。这通常在添加可执行文件的命令中完成:
add_executable(${PROJECT_NAME}
        ${SOURCE_FILES}
        ${APP_ICON_RESOURCE_WINDOWS} # 包含图标资源文件
)
在这个示例中,${APP_ICON_RESOURCE_WINDOWS}变量被用于add_executable命令中,这样就将图标资源文件包含到了最终的应用程序中。
注意事项
- 确保.rc文件正确指向了你的应用程序图标文件。.rc文件是一个资源脚本文件,通常包含了图标、菜单、对话框定义等资源的引用。
CMake中生成Qt UI头文件的两种方式
在使用CMake进行Qt项目的构建时,有两种主要方式来处理.ui文件,从而生成相应的UI头文件。这些方法分别是启用CMAKE_AUTOUIC选项和使用qt5_wrap_ui()命令。
- 方法一:启用 - CMAKE_AUTOUIC选项- 通过设置 - CMAKE_AUTOUIC变量为- ON,CMake会自动处理- .ui文件,生成对应的UI头文件。这种方法简单且自动化,适用于大多数情况。- set(CMAKE_AUTOUIC ON)
 - 当 - CMAKE_AUTOUIC设置为- ON时,CMake会自动寻找与当前项目中的- .cpp文件同名的- .ui文件,并将它们转换为UI头文件。这意味着不需要手动指定- .ui文件,CMake会自动处理。
- 方法二:使用 - qt5_wrap_ui()命令- 如果出于某种原因需要禁用 - CMAKE_AUTOUIC变量,还可以手动处理- .ui文件。这可以通过使用- qt5_wrap_ui()命令来实现,该命令将- .ui文件转换为UI头文件,并将输出文件列表存储在指定的变量中。- # 禁用CMAKE_AUTOUIC
 set(CMAKE_AUTOUIC OFF) # 手动处理.ui文件
 qt5_wrap_ui(UI_HEADERS ${FORM_FILES}) # 在add_executable或add_library中包含生成的UI头文件
 add_executable(${PROJECT_NAME}
 ${SOURCE_FILES}
 ${HEADER_FILES}
 ${UI_HEADERS} # 包含生成的UI头文件
 ${QT_RESOURCES}
 ${APP_ICON_RESOURCE_WINDOWS}
 ) # 添加 target_include_directories() 命令,生成的UI头文件所在的目录通常是当前构建目录
 # 即CMAKE_CURRENT_BINARY_DIR,因此需要将该目录添加到包含目录中。
 target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
 - 在这种方法中,需要明确指定 - .ui文件,并通过- qt5_wrap_ui()命令生成UI头文件。然后,在- add_executable或- add_library命令中包含这些生成的头文件。
Qt5 UI 生成的头文件找不到自定义类所在的头文件的处理方法
在使用 Qt5 进行项目开发时,有时会遇到一个问题:通过 uic 工具自动生成的 UI 头文件无法找到项目中自定义类的头文件。这种情况通常发生在项目结构比较复杂,或者自定义类与 UI 类不在同一个目录下时。以下是解决这个问题的两种方法:
- 方法一:使用 target_include_directories 
 这种方法是通过在 CMakeLists.txt 文件中为目标项目添加包含目录来解决的。具体操作如下:- 在 CMakeLists.txt 文件中找到 target_include_directories 命令。 
 在该命令中添加包含自定义类头文件的目录路径。确保路径是相对于项目根目录的相对路径或者是一个绝对路径。
 例如,如果自定义类的头文件位于项目的 include 目录下,可以这样写:- 这样,当 uic 工具生成 UI 头文件时,编译器就能够找到自定义类的头文件了。 
- 方法二:取消勾选全局包含 
 在某些情况下,如果项目设置中勾选了全局包含(在 Qt Creator 中),可能会导致编译器在整个项目范围内搜索头文件,这可能会引起一些不必要的编译问题。取消这个选项可以让我们更精确地控制包含目录,避免潜在的冲突。- 打开 Qt Creator,导航到项目设置。 
 在构建设置中找到“全局包含”选项,并取消勾选。
 明确指定需要包含的目录,如方法一所述。
qt5 部署 Windows 程序
在 Windows 平台上部署 Qt5 程序时,需要将 Qt5 运行时库(DLL 文件)一同打包到程序目录中,以确保程序能够在没有安装 Qt5 的计算机上正常运行。以下是部署 Qt5 程序到 Windows 的一般步骤:
自动部署依赖项
如果系统中安装了Qt,并且windeployqt.exe工具可用,脚本会利用这个工具自动部署应用程序的依赖项。
检查windeployqt.exe
脚本首先检查windeployqt.exe是否存在:
if (EXISTS "${CMAKE_PREFIX_PATH}/bin/windeployqt.exe")
    message("windeployqt exists")
如果存在,使用windeployqt.exe自动处理依赖项:
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
        COMMAND "${CMAKE_PREFIX_PATH}/bin/windeployqt.exe" "--compiler-runtime"
        "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.exe"
)
手动部署依赖项
如果windeployqt.exe不存在,手动部署依赖项:
- 设置调试后缀:根据构建类型(Debug/Release),设置相应的后缀。
- 确定Qt安装路径:尝试定位Qt的安装路径。
- 复制Qt插件:将必要的Qt插件复制到构建目录。
- 复制Qt库:将需要的Qt库(如Qt5Core.dll、Qt5Gui.dll等)复制到构建目录。
- 处理MinGW依赖(如果使用MinGW):复制MinGW运行时库到构建目录。
MinGW部署
对于使用MinGW的项目,从指定路径复制MinGW运行时库:
if (MINGW)
    set(MINGW_PATH "D:/Scoop/apps/msys2/current/ucrt64")
    message("MINGW ENV: ${MINGW_PATH}")
    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy "${MINGW_PATH}/bin/libgcc_s_seh-1.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
            COMMAND ${CMAKE_COMMAND} -E copy "${MINGW_PATH}/bin/libstdc++-6.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
            COMMAND ${CMAKE_COMMAND} -E copy "${MINGW_PATH}/bin/libwinpthread-1.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
            COMMENT "Deploying mingw runtime libraries from ${MINGW_PATH}/bin"
    )
endif ()
附:完整 CMakeLists.txt 示例
cmake_minimum_required(VERSION 3.24)
project(Qt5CMakeDemo)
message("PROJECT_NAME: ${PROJECT_NAME}")
find_package(Qt5 REQUIRED COMPONENTS
        Core
        Gui
        Widgets
        Multimedia
)
# ==================== set build options ====================
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if (WIN32)
    if (MINGW)
        message("GNU")
        set(CMAKE_PREFIX_PATH "C:/Qt/5.15.2/mingw81_64")
    elseif (MSVC)
        message("MSVC")
        set(CMAKE_PREFIX_PATH "C:/Qt/5.15.2/msvc2019_64")
        add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
    endif ()
elseif (APPLE)
    # Add Apple specific settings here
else ()
endif ()
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
    message("Build Type not set, defaulting to Release...")
    set(CMAKE_BUILD_TYPE Release)
endif ()
message(${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE})
message("CMAKE_PREFIX_PATH: " ${CMAKE_PREFIX_PATH})
message("CXX Compiler: " ${CMAKE_CXX_COMPILER})
message("CXX Standard: " ${CMAKE_CXX_STANDARD})
# ==================== set Project Source Files ====================
set(SOURCE_FILES
        main.cpp
        mainwidget.cpp
)
set(HEADER_FILES
        mainwidget.h
)
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/icon.rc")
# 如果禁用 CMAKE_AUTOUIC 变量,还可以使用 qt_wrap_ui() 该命令手动处理 .ui 文件。
# qt5_wrap_ui(UI_HEADERS mainwidget.ui)
# 如果禁用 CMAKE_AUTORCC 变量,还可以使用 qt5_add_resources() 命令手动处理 .qrc 文件。
# 同时可以 使用 AUTORCC_EXECUTABLE 变量指定 rcc 可执行文件的路径。
# qt5_add_resources(QT_RESOURCES pic.qrc)
# ==================== set Project Target ====================
add_executable(${PROJECT_NAME}
        ${SOURCE_FILES}
        ${HEADER_FILES}
        ${APP_ICON_RESOURCE_WINDOWS}
        # ${UI_HEADERS}
        # ${QT_RESOURCES}
)
# target_include_directories(${PROJECT_NAME} PRIVATE
#         ${CMAKE_CURRENT_SOURCE_DIR}
#         # ${CMAKE_CURRENT_BINARY_DIR}
# )
target_link_libraries(${PROJECT_NAME}
        Qt5::Core
        Qt5::Gui
        Qt5::Multimedia
        Qt5::Widgets
)
# create a GUI application
if (CMAKE_BUILD_TYPE MATCHES "Release" OR CMAKE_CONFIGURATION_TYPES MATCHES "Release")
    set_target_properties(${PROJECT_NAME} PROPERTIES
            WIN32_EXECUTABLE ON
            MACOSX_BUNDLE ON
    )
endif ()
# ==================== Deployment ====================
# Handle Windows deployment
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
    message("WIN32 DEPLOYMENT")
    # 如果存在 windeployqt.exe 工具,则自动部署依赖项
    if (EXISTS "${CMAKE_PREFIX_PATH}/bin/windeployqt.exe")
        message("windeployqt exists")
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND "${CMAKE_PREFIX_PATH}/bin/windeployqt.exe" "--compiler-runtime"
                "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.exe"
        )
    else ()
        message(FATAL_ERROR "windeployqt.exe not found!")
        # Set the debug suffix to copy the correct Qt libraries
        set(DEBUG_SUFFIX)
        if (CMAKE_BUILD_TYPE MATCHES "Debug" OR CMAKE_CONFIGURATION_TYPES MATCHES "Debug")
            set(DEBUG_SUFFIX "d")
        endif ()
        # Set the path to the Qt installation
        set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}")
        if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
            set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
            if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
                set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
            endif ()
        endif ()
        message("QT_INSTALL_PATH: ${QT_INSTALL_PATH}")
        # Copy the required Qt plugins to the build directory
        if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll")
            add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                    COMMAND ${CMAKE_COMMAND} -E make_directory
                    "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
            add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                    COMMAND ${CMAKE_COMMAND} -E copy
                    "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll"
                    "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
        endif ()
        # Copy the required Qt libraries to the build directory
        foreach (QT_LIB Core Gui Widgets Multimedia Network Svg)
            add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                    COMMAND ${CMAKE_COMMAND} -E copy
                    "${QT_INSTALL_PATH}/bin/Qt5${QT_LIB}${DEBUG_SUFFIX}.dll"
                    "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
        endforeach ()
        # MINGW deployment, copy the required MinGW libraries
        if (MINGW)
            if (NOT DEFINED ENV{UCRT64})
                # message(FATAL_ERROR "UCRT64 environment variable not set!")
                set(MINGW_PATH "D:/Scoop/apps/msys2/current/ucrt64")
                message("MINGW ENV: ${MINGW_PATH}")
            else ()
                set(MINGW_PATH "$ENV{UCRT64}")
                message("MINGW UCRT64 ENV: ${MINGW_PATH}")
            endif ()
            add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                    COMMAND ${CMAKE_COMMAND} -E copy "${MINGW_PATH}/bin/libgcc_s_seh-1.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
                    COMMAND ${CMAKE_COMMAND} -E copy "${MINGW_PATH}/bin/libstdc++-6.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
                    COMMAND ${CMAKE_COMMAND} -E copy "${MINGW_PATH}/bin/libwinpthread-1.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
                    COMMENT "Deploying mingw runtime libraries from ${MINGW_PATH}/bin"
            )
        endif ()
    endif () # End of windeployqt.exe check
endif ()
Qt5 CMake 使用指南的更多相关文章
- ROS1 Qt5 CMake基本配置
		############################################################################## # CMake ############# ... 
- CMake入门指南-编译教程
		CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目.通过编写CMakeLists.txt,可以控制生成的Makefile, ... 
- CMake入门指南
		原文地址:http://www.cnblogs.com/sinojelly/archive/2010/05/22/1741337.html CMake是一个比make更高级的编译配置工具,它可以根据不 ... 
- Qt5 Cmake
		project(my) cmake_minimum_required(VERSION ) set (CMAKE_PREFIX_PATH "C:\\Qt\\Qt5.3.0\\5.3\\msvc ... 
- Qt5 CMake cross compile
		cmake_minimum_required(VERSION 2.8) if (${ARM}) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCES ... 
- 使用Qt5+CMake实现图片的区域选择(附源码)
		近期研发涉及到了图片的区域选择,找来一些资料一直不能很满意,所以自己实现了一个. 实现步骤如下.源码可以点击ImageAOI获取. 如下资料来自源码的README. ImageAOI (XLabel) ... 
- Android:cmake开发指南
		一.静态库与动态库构建 (.so)共享库,shared object:节省空间,在运行时去连接,如果执行机器上没有这些库文件就不能执行. (.a)静态库,archive:静态库和程序化为一体,不会分开 ... 
- Qt5 CMake项目简单模板
		cmake_minimum_required(VERSION 3.5) project(test VERSION 0.1 LANGUAGES CXX) set(CMAKE_INCLUDE_CURREN ... 
- CMake安装(linux)
		环境:CentOS6.5 1.下载网址: http://www.cmake.org/download/ (选择linux版本,编译安装) 2.安装 # tar zxvf cmake-.tar.gz # ... 
- [C] c99int(让VC等编译器自动兼容C99的整数类型)V1.02。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释
		新版本—— http://www.cnblogs.com/zyl910/p/zlstdint_v100.html[C] zlstdint(让VC.TC等编译器自动兼容C99的整数类型)V1.0.支持T ... 
随机推荐
- 解密华为问界M7 Pro:智能出行的全新里程碑与技术亮点
			解读华为问界M7 Pro的智能里程碑 引言 2024年8月,智能出行领域迎来了一个激动人心的时刻--问界M7 Pro的重磅发布.这款智能SUV,不仅是华为在汽车领域的又一次大胆尝试,更是鸿蒙智行系统的 ... 
- 用描述程序的方式emo,扎心了...
			用描述程序的方式emo,扎心了... 众所周知写程序是个枯燥无聊的过程,再加上生活的不顺与坎坷,当程序语言与emo结合起来,看谁还说程序员不懂感情! 首当其冲的就是循环语句了 世界上最寂寞的感觉,是我 ... 
- 【YashanDB知识库】filter or改写问题
			问题现象 当filter中出现or的时候,会导致filter无法走索引或者走hash join,就需要进行改写,例如: create table test_tab1(col1 int, col2 in ... 
- angular 知识
			看完以下内容应该就可以上手Angular了 https://angular.io/start Udemy - Complete Angular 14 Course - Learn Frontend D ... 
- 如何使用hugo搭建个人博客
			整体架构 在 github 托管两个仓库,仓库 1 保存博客内容源文件,仓库 2 保存 Hugo 生成的网站文件,博客内容仓库通过 git submodule 的方式在仓库 2 管理.使用 Obsid ... 
- mysql 批量有则修改,无则新增
			需要为表添加唯一索引 alter table tb_*** add unique index(aa,bb); -- 此条为联合唯一索引INSERT INTO<include refid=&quo ... 
- Springboot 项目配置 HTTPS
			生成证书 输入命令 keytool -genkeypair -alias "boot" -keyalg "RSA" -keystore "boot.k ... 
- 《Vue.js 设计与实现》读书笔记 - 第6章、原始值的响应式方案 & 响应式总结
			第6章.原始值的响应式方案 6.1 引入 ref 的概念 既然原始值无法使用 Proxy 我们就只能把原始值包裹起来. function ref(val) { const wrapper = { va ... 
- 全网最适合入门的面向对象编程教程:55 Python字符串与序列化-字节序列类型和可变字节字符串
			全网最适合入门的面向对象编程教程:55 Python 字符串与序列化-字节序列类型和可变字节字符串 摘要: 在 Python 中,字符编码是将字符映射为字节的过程,而字节序列(bytes)则是存储这些 ... 
- 三维医学图像深度学习,数据增强方法(monai):RandHistogramShiftD, Flipd, Rotate90d
			#coding:utf-8 import torch from monai.transforms import Compose, RandHistogramShiftD, Flipd, Rotate9 ... 
