Qt 的cmake与qmake


构建工具

Qt 项目的构建工具有 QMake 和 CMake 两种。如果使用的是 Qt Creator 开发,在创建新项目时的步骤中,有一步需要选择"构建系统"(build system),这一步就是选择这两种构建方式任选其一。

这两种构建工具的项目树结构大概是下面这样的,上面的是cmake,下面的是qmake:

如果从新建项目到后期开发都是使用的Qt Creator,并且源文件也是通过Qt Creator的菜单新建的,也没有使用Qt之外的第三方库,那么无需过多考虑qmake和cmake的配置文件相关的东西,Qt Creator会自动帮我们生成更新构建工具的配置文件,直接点击左下角的绿色运行按钮即可编译运行。

Qt Creator会帮我们配置好一切,新手、没有协同开发需求、没用到其他第三方库等情况下,我们只需关注程序怎么写,而无需考虑qmake和cmake背后是怎样的,配置文件怎么修改的等等。这像是一种"一劳永逸"的配置,一切都在创建项目的时候交付好了。


如果需要添加第三方库、项目需要迁移、或者协同创作、或者更换IDE开发、或者更换构建工具等等,这些需要更改项目的情况,那么可能需要对qmake或者cmake有一定的了解。

如何判断项目是qmake还是cmake?

如果项目目录下有一个.pro文件,那么一般是qmake,如果目录中有一个CMakeLists.txt文件,那么一般是cmake。

QMake

QMake特点:

专为 Qt 设计:Qt 自带的构建工具

相对简单易用:语法相对简单,学习曲线平缓

与 Qt 紧密集成:自动处理 Qt 的 MOC、UIC、RCC 等特性

QMake 的配置文件为.pro文件。

形如这样:

c++ 复制代码
  
   QT
         += core gui

greaterThan(QT_MAJOR_VERSION, 4): 
  
   QT
   += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment 
  
   the
   following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all 
  
   the
   APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

CMake

CMake特点:

跨平台构建系统:不限于 Qt,可用于各种 C++ 项目

功能强大:支持复杂的构建需求

行业标准:被许多开源项目和大型工程采用

此外,Qt6 及以后更多的推崇使用cmake进行构建。

CMake的配置文件是CMakeLists.txt,形如这样:

bash 复制代码
cmake_minimum_required(VERSION 3.16)

project(cmakeDemo VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(
  
   QT
   NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(
  
   Qt
  ${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(cmakeDemo
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
# Define target properties for Android with 
   
    Qt
    6 as:
#    set_property(TARGET cmakeDemo APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.
   
    qt
   .io/
   
    qt
   -6/
   
    qt
   -add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(cmakeDemo SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with 
   
    Qt
    5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(cmakeDemo
            ${PROJECT_SOURCES}
        )
    endif()
endif()

target_link_libraries(cmakeDemo PRIVATE 
  
   Qt
  ${QT_VERSION_MAJOR}::Widgets)

# 
   
    Qt
    for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since 
   
    Qt
    6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER 
  
   com
  .example.cmakeDemo)
endif()
set_target_properties(cmakeDemo PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE 
  
   TRUE
  
    WIN32_EXECUTABLE 
  
   TRUE
  
)

include(GNUInstallDirs)
install(TARGETS cmakeDemo
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(cmakeDemo)
endif()

这些文件的语法不需要像心血一门编程语言一样去学习,我们只需在遇到需要的场景,使用搜索引擎或者AI即可。


qmake2cmake

项目可能会遇到需要从qmake迁移到cmake的情况,我们从以下角度入手:

  1. 可以按照配置文件内容手动转换,但这会比较麻烦,如果仅仅是小型教学的 demo ,那么可以尝试,如果项目比较复杂就不适用了。
  2. 写转换脚本,但这种方法门槛比较高。
  3. 最后一种方法就是使用Qt官方的转换工具qmake2cmake。它是一个将 Qt .pro 项目文件转换为 CMakeLists.txt 文件的工具。 在这里可以看到安装以及使用的官方介绍:qmake2cmake官方介绍

一般情况下在安装 Qt 6.2+ 后会自带此工具,使用evething 搜索 qmake2cmake 看有没有。

如果没有,需要手动安装。由于这个转换脚本是python写的,所以需要电脑先安装了 python。

假设电脑已经安装了python,执行以下命令安装:

bash 复制代码
python -m pip install qmake2cmake

如果想了解源码,可以克隆下来查看:

bash 复制代码
git clone git://code.
   
    qt
   .io/
   
    qt
   /qmake2cmake.git

也可以在线查看:https://code.qt.io/cgit/qt/qtbase.git/tree/util/cmake/pro2cmake.py?h=wip/cmake

关于这个工具的简单使用,可参照以下两个指令:

bash 复制代码
# 方式一,指定pro文件名,并转换
qmake2cmake ~/projects/myapp/myapp.pro

#方式二,自动寻找指定目录下的pro文件,并转换。后面的--min-
   
    qt
   -version 是必须选项,根据情况修改
qmake2cmake_all ~/projects/myapp --min-
  
   qt
  -version 6.3
相关推荐
用户805533698035 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner5 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz10 天前
QML Hello World 入门示例
qt
xcyxiner13 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner14 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript