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_executableadd_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不存在,手动部署依赖项:

  1. 设置调试后缀:根据构建类型(Debug/Release),设置相应的后缀。
  2. 确定Qt安装路径:尝试定位Qt的安装路径。
  3. 复制Qt插件:将必要的Qt插件复制到构建目录。
  4. 复制Qt库:将需要的Qt库(如Qt5Core.dllQt5Gui.dll等)复制到构建目录。
  5. 处理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 使用指南的更多相关文章

  1. ROS1 Qt5 CMake基本配置

    ############################################################################## # CMake ############# ...

  2. CMake入门指南-编译教程

    CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目.通过编写CMakeLists.txt,可以控制生成的Makefile, ...

  3. CMake入门指南

    原文地址:http://www.cnblogs.com/sinojelly/archive/2010/05/22/1741337.html CMake是一个比make更高级的编译配置工具,它可以根据不 ...

  4. Qt5 Cmake

    project(my) cmake_minimum_required(VERSION ) set (CMAKE_PREFIX_PATH "C:\\Qt\\Qt5.3.0\\5.3\\msvc ...

  5. Qt5 CMake cross compile

    cmake_minimum_required(VERSION 2.8) if (${ARM}) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCES ...

  6. 使用Qt5+CMake实现图片的区域选择(附源码)

    近期研发涉及到了图片的区域选择,找来一些资料一直不能很满意,所以自己实现了一个. 实现步骤如下.源码可以点击ImageAOI获取. 如下资料来自源码的README. ImageAOI (XLabel) ...

  7. Android:cmake开发指南

    一.静态库与动态库构建 (.so)共享库,shared object:节省空间,在运行时去连接,如果执行机器上没有这些库文件就不能执行. (.a)静态库,archive:静态库和程序化为一体,不会分开 ...

  8. Qt5 CMake项目简单模板

    cmake_minimum_required(VERSION 3.5) project(test VERSION 0.1 LANGUAGES CXX) set(CMAKE_INCLUDE_CURREN ...

  9. CMake安装(linux)

    环境:CentOS6.5 1.下载网址: http://www.cmake.org/download/ (选择linux版本,编译安装) 2.安装 # tar zxvf cmake-.tar.gz # ...

  10. [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 ...

随机推荐

  1. 解密华为问界M7 Pro:智能出行的全新里程碑与技术亮点

    解读华为问界M7 Pro的智能里程碑 引言 2024年8月,智能出行领域迎来了一个激动人心的时刻--问界M7 Pro的重磅发布.这款智能SUV,不仅是华为在汽车领域的又一次大胆尝试,更是鸿蒙智行系统的 ...

  2. 用描述程序的方式emo,扎心了...

    用描述程序的方式emo,扎心了... 众所周知写程序是个枯燥无聊的过程,再加上生活的不顺与坎坷,当程序语言与emo结合起来,看谁还说程序员不懂感情! 首当其冲的就是循环语句了 世界上最寂寞的感觉,是我 ...

  3. 【YashanDB知识库】filter or改写问题

    问题现象 当filter中出现or的时候,会导致filter无法走索引或者走hash join,就需要进行改写,例如: create table test_tab1(col1 int, col2 in ...

  4. angular 知识

    看完以下内容应该就可以上手Angular了 https://angular.io/start Udemy - Complete Angular 14 Course - Learn Frontend D ...

  5. 如何使用hugo搭建个人博客

    整体架构 在 github 托管两个仓库,仓库 1 保存博客内容源文件,仓库 2 保存 Hugo 生成的网站文件,博客内容仓库通过 git submodule 的方式在仓库 2 管理.使用 Obsid ...

  6. mysql 批量有则修改,无则新增

    需要为表添加唯一索引 alter table tb_*** add unique index(aa,bb); -- 此条为联合唯一索引INSERT INTO<include refid=&quo ...

  7. Springboot 项目配置 HTTPS

    生成证书 输入命令 keytool -genkeypair -alias "boot" -keyalg "RSA" -keystore "boot.k ...

  8. 《Vue.js 设计与实现》读书笔记 - 第6章、原始值的响应式方案 & 响应式总结

    第6章.原始值的响应式方案 6.1 引入 ref 的概念 既然原始值无法使用 Proxy 我们就只能把原始值包裹起来. function ref(val) { const wrapper = { va ...

  9. 全网最适合入门的面向对象编程教程:55 Python字符串与序列化-字节序列类型和可变字节字符串

    全网最适合入门的面向对象编程教程:55 Python 字符串与序列化-字节序列类型和可变字节字符串 摘要: 在 Python 中,字符编码是将字符映射为字节的过程,而字节序列(bytes)则是存储这些 ...

  10. 三维医学图像深度学习,数据增强方法(monai):RandHistogramShiftD, Flipd, Rotate90d

    #coding:utf-8 import torch from monai.transforms import Compose, RandHistogramShiftD, Flipd, Rotate9 ...