Qt QMake指南(如何写pro文件)

QMake相关介绍

QMake是一个通过编译Pro文件自动生成Makefile文件的工具。

扩展知识

这里是关于make、makefile、cmake、CMakeLists.txt、qmake等工具和文件之间关系的详细解释:

  1. 起始:当我们开始学习基础的helloworld项目时,一般使用gcc命令进行编译。gcc代表GNU Compiler Collection(GNU编译器套件),它是一种编译器。
  2. 项目增大时的需求:随着项目变得复杂,涉及多个需要编译的文件时,使用gcc命令逐个编译变得不切实际。这时候,就需要使用makefile文件和make工具。
  3. makefile:makefile是一个定义项目编译和链接规则的文件,它指定了哪些文件需要编译,哪些不需要,以及编译的先后顺序等。文件的编译过程仍然依赖于调用gcc或其他编译器。
  4. make工具:make工具的功能是读取makefile中定义的规则来编译和链接项目。
  5. CMake的引入:由于makefile可以变得非常复杂,尤其是在大型或跨平台项目中,CMake工具被用来生成makefile。CMake支持跨平台编译,不仅限于生成makefile,还能生成适用于不同平台和开发环境的构建文件。
  6. CMakeLists.txt:CMakeLists.txt是CMake使用的配置文件,包含了项目文件路径、环境设置和编译配置等。尽管某些IDE可以帮助生成基本的CMakeLists.txt框架,但这个文件通常需要开发者根据项目的具体需求手动编写和调整。
  7. qmake:qmake是一个类似于CMake的工具,主要用于Qt框架的项目。它专门处理Qt特定的构建需求,比如MOC(元对象编译器)和UIC(用户界面编译器)。qmake通过解析Qt项目的.pro文件来生成makefile。
  8. pro文件:qmake工具通过读取.pro文件——这是一个包含了项目相关配置和规则的文件——来生成makefile。.pro文件的语法和结构设计用来支持Qt项目的特定需求。

内置变量

qmake的基本行为受到变量声明的影响,这些声明定义了每个项目的构建过程。其中一些声明资源,例如HEADERS和SOURCES是每个平台所共有的。其他的则是用来定制特定平台上的编译器和链接器的行为。

Qt模块

QT变量主要包含项目所需的Qt模块,Qt基础模块有以下:

基础模块 描述
core (默认包含该模块)核心模块
gui (默认包含该模块)图形用户界面模块
multimedia 音频、视频、广播和相机功能模块
multimedia widgets 用于实现多媒体功能的widget模块
network 网络编程模块
qml 支持QML和JavaScript语言的模块
quick 构建具有自定义用户动态界面的应用程序模块
quick controls 提供轻量级QML控件类型的模块
quick dialogs 为quick应用程序提供对话框的模块
quick layouts 基于Qt Quick 2项目的用户界面布局模块
quick test QML单元测试模块
sql 数据库模块
test Qt应用程序和库的单元测试模块
widgets 扩展GUI窗口类的模块

默认Qt项目将包含core和gui两个模块,如果项目不需要界面显示,则需要添加以下代码:

QT -= gui

Qt还扩展了很多附加模块:

附加模块 开发平台 应用平台 描述
Active Qt Windows Windows 支持ActiveX和COM模块
Qt 3D All All 实时仿真系统,支持2D和3D渲染
Qt Android Extras All Android 为Android提供特定于平台的API
Qt Bluetooth All Android,ios,Linux,MacOS,UWP 提供对蓝牙的访问
Qt Concurrent All All 在不使用低级线程语法下编写多线程程序
Qt D-Bus All All 通过D-Bus协议进行进程间通信
Qt Gamepad All Android,ios,macOS,tvOS,Linux,Windows,QNX 支持游戏手柄硬件的应用程序
Qt Graphical Effects All All 用于Qt Quick 2的图形效果
Qt Help All All 像Qt助手一样将文档集成到应用程序中
Qt Image Formats All All 支持其他图形格式:TIFF、MNG、TGA、WBMP
Qt Location All All 在QML应用程序中显示地图、导航和地点内容
Qt Mac Extras All macOS 为macOS提供特定于平台的API
Qt NFC All Android,Linux 支持NFC硬件访问
Qt Positioning All Android,ios,macOS,Linux,UWP 提供对位置、卫星和区域监控类的访问
Qt Print Support All All 提供更便捷的打印类
Qt Quick Extras All All 提供一组专门的Quick控件
Qt Quick Timeline All All 启用基于关键帧的动画和参数化
Qt Quick Widgets All All 提供用于显示Quick用户界面的小部件类
Qt Remote Objects All All 提供一种用于在进程或设备之间共享QObject的API
Qt SCXML All All 提供从SCXML文件中创建状态机并将其嵌入到应用程序中
Qt Serial Port All Windows,Linux,macOS,QNX 提供对硬件和虚拟串口的访问
Qt Speech All All except QNX 提供对语音方面的支持
Qt SVG All All 用于显示SVG文件内容的类
Qt UI Tools All All 运行时动态加载基于QWidget的表单类
Qt WebChannel All All 提供从HTML客户端对QObject或QML对象的访问,用来实现应用程序和HTML/JavaScript客户端的联系
Qt WebEngine All Windows,Linux,macOS 将Chromium浏览器引擎嵌入应用程序中
Qt WebSockets All All 提供符合RFC6455的Websocket通信
Qt WebView All All 支持原生API显示Web浏览器视图
Qt Windows Extras All Windows 为Windows提供特定于平台的API
以下在商业许可证或GNU通用公共许可证V3下可以用的附加模块:
Qt Charts All All 图表模块
Qt Data Visualization All All 3D数据可视化组件
Qt Lottie Animation All All 以JSON格式渲染图形和动画的QML API
Qt Virtual Keyboard All Linux,Windows desktop,Boot to Qt targets 支持本地的虚拟键盘
Qt Quick 3D All All 提供Quick 3D相关API
Qt Quick WebGL All WebGL-enabled web browsers 支持WebGL插件

HEADERS

项目包含头文件列表:

HEADERS += widget.h

SOURCES

项目包含源文件列表:

SOURCES += main.cpp \
          widget.cpp

FORMS

项目包含UI文件列表:

FORMS += widget.ui

RESOURCES

指定目标的资源文件(qrc)的名称。

RESOURCES += src.qrc

INCLUDEPATH

指定编译项目时要包含当前目录。例如:

INCLUDEPATH = c:/msdev/include d:/stl/include

LIBS

该变量包含链接到工程的库列表。可以使用Unix平台-L(库路径)和-l(库名称)的标识,qmake会正确处理Windows和symbian平台上的这些库。例如:

LIBS += -L./lib -ltest   # 链接到./bin目录下的test.lib
LIBS += -ltest           # 链接到当前目录下的test.lib

CONFIG

通用配置,主要包含编译器选项和属性以及链接库标志。

选项 描述
release 该项目以发布模式构建。如果同时定义了debug,则将忽略release
debug 该项目以调试模式构建。
debug_and_release 该项目以调试和发布模式构建。
debug_and_release_target 该项目使用debug和release两种模式构建,目标会被构建到debug和release两个目录下
build_all 如果指定了debug_and_release,项目默认以调试和发布模式构建。
autogen_precompile_source 自动生成一个.cpp文件,包含.pro文件中指定的预编译头文件。
ordered 当使用subdirs模板时,该选项指定按照列出的目录顺序构建。
precompile_header 项目支持预编译头文件
precompile_header_c 项目支持对C的预编译头文件
warn_on 编译器警告信息输出打开
warn_off 编译器警告信息输出关闭
exceptions 默认启用异常
exceptions_off 关闭异常
ltcg 启用链接时间代码生成,默认是关闭的
rtti 启用对RTTI的支持,默认情况下使用编译器的默认值
rtti_off 关闭对RTTI的支持,默认情况下使用编译器的默认值
stl 启用对STL的支持,默认情况下使用编译器的默认值
stl_off 关闭对STL的支持,默认情况下使用编译器的默认值
thread 启用对线程的支持,当CONFIG包含了qt模块时,这将被启用,这是默认的。
c99 启用对C99的支持。如果编译器不支持C99,或者不能选择C标准,这个选项就没有作用。默认情况下使用编译器的默认值
c11 启用对C11的支持。如果编译器不支持C11,或者不能选择C标准,这个选项就没有作用。默认情况下使用编译器的默认值
strict_c 禁用对C编译器扩展的支持。默认情况下被启用。
c++11 启用对C11标准的支持。如果编译器不支持C11,或者不能选择C++标准,这个选项就没有作用。默认情况下是启用的。
c++14 启用对C14标准的支持。如果编译器不支持C14,或者不能选择C++标准,这个选项就没有作用。默认情况下使用编译器的默认值。
c1z / c17 启用对C17标准的支持。如果编译器不支持C17,或者不能选择C++标准,这个选项就没有作用。默认情况下是禁用的。
c++2a 启用对C2a标准的支持。如果编译器不支持C2a,或者不能选择C++标准,这个选项就没有作用。默认情况下是禁用的。
c++latest 启用编译器所支持的最新C++标准的支持,默认情况下是禁用的。
strict_c++ 禁用对C++编译器扩展的支持。默认情况下是被启用的。
depend_includepath 启用将INCLUDEPATH的值追加到DEPENDPATH。默认启用
lrelease 对 TRANSLATIONS 和 EXTRA_TRANSLATIONS 中列出的所有文件运行 lrelease。如果 embed_translations 没有被设置,请将生成的 .qm 文件安装到 QM_FILES_INSTALL_PATH。使用 QMAKE_LRELEASE_FLAGS 来为 lrelease 调用添加选项。默认情况下不设置。
embed_translations 在QM_FILES_RESOURCE_PREFIX下的可执行文件中嵌入从lrelease生成的翻译。需要lrelease也被设置。默认情况下不设置。
create_libtool 为当前构建的库创建一个libtool.la文件
create_pc 为当前构建的库创建一个pkg-config .pc 文件。
no_batch 仅限NMake。关闭NMake批处理规则或推理规则的生成。
skip_target_version_ext 在Windows下,禁止自动附加在DLL文件名上的版本号。
suppress_vcproj_warnings 禁止VS项目生成警告信息。
windeployqt 在链接后自动调用windeployqt,并将输出添加为部署项。
dont_recurse 禁止qmake递归当前子项目
no_include_pwd 不要将当前目录添加到INCLUDEPATHS中
compile_include_sources 默认情况下,qmake不编译包含在其他源文件中的源文件

当您使用该debug_and_release选项(Windows 下的默认设置)时,项目将被处理三次:一次生成“元”Makefile,另外两次生成 Makefile.Debug 和 Makefile.Release。
在后者构建时,debugorrelease选项被附加到CONFIG. 这使得执行特定于构建的任务成为可能。

以下选项定义应用程序或库的类型:

选项 描述
qt 默认定义。该项目依赖Qt库
x11 该项目是一个X11应用程序或库
testcase 该项目是自动化测试。检查并添加到生成的Makefile中以运行测试
insignificant_test 自动测试的退出代码将被忽略。
windows 该项目是一个win32窗口应用程序
console 该项目是一个win32控制台应用
shared 该项目是一个共享项目
dll 该项目是一个动态库项目,构建后自动生成dll文件
dylib 该项目是一个Mac OS的动态库项目,构建后自动生成dylib文件
static 该项目是一个静态库项目
staticlib 该项目是一个静态库项目
plugin 该项目是一个插件项目
designer 该项目是一个Qt designer插件项目
uic3
no_Iflags_merge 配置该项使LIBS的库列表不会被简化为唯一名称的列表
resources 配置rcc资源模块

DESTDIR

指定目标(可执行文件)放置的路径

SUBDIRS

该变量和subdirs模板类型一起使用时,指定项目需要构建的所有子项目(子目录)名称。包含的子目录必须包含自己的pro文件。例如:

SUBDIRS = kernel \
          tools \
          myapp

注意:当CONFIG 配置添加了 ordered,则SUBDIRS包含子目录的顺序决定了构建的顺序。

TARGET

指定目标文件的名称。默认包含项目文件的基本名称。例如:

TARGET = myapp

TEMPLATE

指定生成项目时要使用的模板名称。模板选项包含以下:

选项 描述
app (默认)。构建为应用程序
lib 构建为库
subdirs 构建子目录
aux 不构建任何东西
vcapp 构建为Windows系统下的VS应用程序项目
vclib 构建为Windows系统下的库项目

DEPENDPATH

指定qmake要扫描的目录列表,用来解决项目中的依赖关系。该变量在qmake抓取你的源代码中#include的头文件时使用。

DEFINES

qmake将该变量的值作为C编译器的预处理宏。

VERSION

如果模板类型为app,则表示应用程序的版本号;如果模板类型为lib,则表示库的版本号。

win32:VERSION = 1.2.3.4 # major.minor.patch.build
else:VERSION = 1.2.3    # major.minor.patch

DLLDESTDIR

指定复制目标dll的目录。注意:该变量只适用于Windows平台。

RCC_DIR

指定Qt资源编译器输出文件的目录。例如:

unix:RCC_DIR = ../myproject/resources
win32:RCC_DIR = c:/myproject/resources

PRO_FILE

pro文件的绝对路径,包含pro文件名称,例如:

message(_PRO_FILE_)
# out:
# Project MESSAGE: E:/Test/ProTest/ProTest.pro

PRO_FILE_PWD

pro文件的目录路径,不包含pro文件名称,例如:

message(_PRO_FILE_PWD_)
# out:
# Project MESSAGE: E:/Test/ProTest

函数

CONFIG(config)

这个函数是用来测试放在CONFIG变量中的变量的,功能类似于条件作用域。函数的第二个参数是用来指定互斥条件的,例如:

# test1:
  CONFIG += debug
  CONFIG(debug) : message(debug build!)
  CONFIG(release) : message(release build!)
  # out: 因为没有指定互斥量,所以两种输出都将执行
  # Project MESSAGE: debug build!
  # Project MESSAGE: release build!
  # Project MESSAGE: debug build!
  # Project MESSAGE: release build!
  # Project MESSAGE: debug build!
  # Project MESSAGE: release build!

# test2:
  CONFIG += debug
  CONFIG(debug, debug|release) : message(debug build!)
  CONFIG(release, debug|release) : message(release build!)
  # out: 当前指定debug模式,所以只会输出debug build!
  # Project MESSAGE: debug build!
  # Project MESSAGE: debug build!
  # Project MESSAGE: debug build!

# test3:
  CONFIG += release
  CONFIG(debug, debug|release) : message(debug build!)
  CONFIG(release, debug|release) : message(release build!)
  # out:当前指定release模式,所以只会输出release build!
  # Project MESSAGE: release build!
  # Project MESSAGE: release build!
  # Project MESSAGE: release build!
  
# test4:
  CONFIG(debug, debug|release) : message(debug build!)
  CONFIG(release, debug|release) : message(release build!)
  # release构建 out:
  # Project MESSAGE: release build!
  # Project MESSAGE: release build!
  # Project MESSAGE: debug build!
  
  # debug构建 out:
  # Project MESSAGE: debug build!
  # Project MESSAGE: debug build!
  # Project MESSAGE: release build!

注意上面测试示例输出的内容为什么会有三次呢?因为在缺省情况下,qmake将创建三个makefile文件,分别为Makefile,Makefile.debug以及Makefile.release三个。所以当测试示例4中没有指定固定的构建配置,IDE选择release模式时Makefile和Makefile.release两个文件对应输出release build!,而Makefile.debug会输出debug build!

contains(variablename, value)

如果变量variablename包含value值,则成功,否则失败。

# 如果QT添加了network模块,则把对应的头文件和源文件添加到项目中
contains( QT, network ) {
    message( "Configuring for network build..." )
    HEADERS += network.h
    SOURCES += network.cpp
}

上面示例代码是contains的主要应用场景,通过判断是否添加某些模块来自动添加对应模块的代码文件。

count(variablename,number)

如果variablename比哪里中包含指定数量number的值列表则成功,反之失败。
该函数主要用于确保作用域内的声明仅在变量包含正确数值的情况下才会被处理。例如:

options = $$find(CONFIG, "debug") $$find(CONFIG, "release")
count(options, 2) { message(Both release and debug specified.)}

include(filename)

意义和C++中的include是一样的,将指定的文件名包含到当前项目中,返回true表示包含成功,反之包含失败。你可以通过使用这个函数作为条件来检查是否被包含。示例如下:

!include(test.pri) {
  message("test.pri加载失败")
}

一般我们用于包含pri文件。

if(condition)

条件判断,和C++的if语句一样。

for(iterate, list)

循环变量list中的所有值。示例如下:

LIST = 1 2 3
for(a, LIST):message(I see a file.$${a}!)
# out:
# Project MESSAGE: I see a file.1!
# Project MESSAGE: I see a file.2!
# Project MESSAGE: I see a file.3!

message(string)

将字符串以一般信息输出给用户。

message( "This is a message" )  # 引号是可选的,建议使用

注意:默认情况下,qmake为特定项目生成的每个makefile都会输出信息。如果你想确保每个项目只输出一次信息,请参考下面的示例:

!build_pass:message( "This is a message" )

mkpath(dirPath)

创建目录路径dirPath,这个函数是QDir::mkpath函数的一个封装器。
该函数在Qt5.0中被引入。

system(command)

执行shell命令。执行命令返回0表示成功,否则失败。示例如下:

system("ls /bin"): HAS_BIN = TRUE

unset(variablename)

将变量名从当前上下文中移除。

NARF = zort
unset(NARF)
!defined(NARF, var) {
    message("NARF is not defined.")
}
# out:
# Project MESSAGE: NARF is not defined.

versionAtLeast(variablename, versionNumber)

比较variablename的版本好是否大于等于versionNumber。一般用于判断当前Qt的版本,示例如下:

versionAtLeast(QT_VERSION, 5.12.0):message("Qt 5.12.0")
# out:
# Project MESSAGE: Qt 5.12.0

versionAtMost(variablename, versionNumber)

比较variablename的版本好是否小于等于versionNumber。一般用于判断当前Qt的版本,示例如下:

versionAtMost(QT_VERSION, 5.15.2):message("Qt 5.15.2")
# out
# Project MESSAGE: Qt 5.15.2

warning(string)

以警告的形式输出字符串。同时会在IDE的问题栏中输出信息。

error(string)

以错误的形式输出字符串。同时会在IDE的问题栏中输出信息。

eval(string)

使用qmake语法规则评估字符串的内容并返回true。定义新的变量或修改现有变量的值。示例如下:

# TARGETS 变量没有定义时
eval(TARGETS = myapp) {
    message($$TARGETS)
}
# out:
# Project MESSAGE: myapp

# TARGET 变量已定义时
message($$TARGET)
eval(TARGET = myapp) {
    message($$TARGET)
}
# out: ProTest是当前测试项目的名称
# Project MESSAGE: ProTest
# Project MESSAGE: myapp

exists(filename)

判断文件名的文件是否存在。如果存在则返回成功,否则返回失败。

isEmpty(variablename)

如果variablename变量为空则返回true,反之返回false。等价于count(variablename,0)。例如:

isEmpty(CONFIG) {
CONFIG += qt warn_on debug}

basename(variablename)

返回指定文件的base文件名称。例如:

FILE = /etc/passwd
FILENAME = $$basename(FILE)
# out:
# passwd

dirname(file)

返回指定文件的目录部分。例如:

FILE = /etc/X11R6/XF86Config
DIRNAME = $$dirname(FILE)
# out:
# /etc/X11R6

find(variablename, substr)

在variablename变量的所有值中查找匹配substr字符串的值,substr可能是正则表达式。例如:

MY_VAR = one two three four
MY_VAR2 = $$find(MY_VAR, t.*)
message($$MY_VAR2)
# out:
# two three

join(variablename,glue,before,after)

使用glue连接variablename变量中的值。如果变量的值非空,在值前面加一个前缀before,在值的后面加一个后缀after。Variablename是必须参数,其它参数默认是空字符串。如果需要在glue、before、after中对空格进行编码,必须对它们使用引号。例如:

MY_VAR = one two three four
MY_VAR2 = $$join(MY_VAR, " -L", -L) -Lfive
MY_VAR3 = $$join(MY_VAR, " -L", -L, -M)

message($$MY_VAR2) #out: -Lone -Ltwo -Lthree -Lfour -Lfive
message($$MY_VAR3) #out: -Lone -Ltwo -Lthree -Lfour-M

member(variablename,position)

返回variablename变量的值列表中位置为position的值。如果找不到对应位置,则返回空字符串。如果不指定position参数,则默认为0,返回值列表中的第一个值。

可以理解variablename为一个数组,而position为数组的下标。例如:

MY_VAR = one two three four
MY_VAR2 = $$member(MY_VAR, 3)
MY_VAR3 = $$member(MY_VAR, 2)

message($$MY_VAR2) #out: four
message($$MY_VAR3) #out: three

replace(string, old_string, new_string)

在string字符串中找到old_string字符串,然后用new_string进行替换。例如:

MESSAGE = This is a tent.
message($$replace(MESSAGE, tent, test))
# out:
# This is a test.

unique(variablename)

返回variablename变量的所有值,如果有重复的则删除。例如:

ARGS = 1 2 3 2 5 1
ARGS = $$unique(ARGS) #out: 1 2 3 5

其他

  • 自定义变量以及变量内容的访问
CUSTOMVAL = ./bin     # 自定义变量名为CUSTOMVAL
message($$CUSTOMVAL)  # 输出CUSTOMVAL变量值
# out:
# Project MESSAGE: ./bin
  • 值列表(每个值之间用空格分割)
LIST = 1 2 3
for(a, LIST):message(I see a file.$${a}!)
# out:
# Project MESSAGE: I see a file.1!
# Project MESSAGE: I see a file.2!
# Project MESSAGE: I see a file.3!
  • 单值(单值且中间包含空格时需要用双引号来包含)
LIST = "1 2 3"
for(a, LIST):message(I see a file.$${a}!)
# out:
# Project MESSAGE: I see a file.1 2 3!
  • 注释
# 注释是以'#'符合作为注释的开头,以行末尾作为结束

如果要在变量中使用’#'字符,必须使用内置变量LITERAL_HASH,示例如下:

urlPieces = http://doc.qt.io/qt-5/qtextdocument.html pageCount
message($$join(urlPieces, $$LITERAL_HASH))
# out:
# Project MESSAGE: http://doc.qt.io/qt-5/qtextdocument.html#pageCount

# 注意,想要在变量中使用'#'字符,只有这一种方式,用双引号来包含也是没有用的

相关推荐

  1. Qt QMake指南如何pro文件

    2024-06-14 17:20:03       84 阅读
  2. Dockerfile:如何一个Dockerfile文件

    2024-06-14 17:20:03       56 阅读
  3. Lua 如何ini文件

    2024-06-14 17:20:03       40 阅读
  4. k8s&&如何yaml文件

    2024-06-14 17:20:03       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-14 17:20:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-14 17:20:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-14 17:20:03       87 阅读
  4. Python语言-面向对象

    2024-06-14 17:20:03       96 阅读

热门阅读

  1. Rabbit MQ和Kafka的区别

    2024-06-14 17:20:03       30 阅读
  2. Kafka基础架构与核心概念?有哪些应用场景?

    2024-06-14 17:20:03       32 阅读
  3. Kafka之ISR机制的理解

    2024-06-14 17:20:03       29 阅读
  4. 10.GLM

    10.GLM

    2024-06-14 17:20:03      33 阅读
  5. Golang-goroutine互斥锁与读写互斥锁

    2024-06-14 17:20:03       31 阅读
  6. 多商家抽奖管理系统介绍和小程序APP演示

    2024-06-14 17:20:03       35 阅读
  7. Debian常用命令

    2024-06-14 17:20:03       27 阅读
  8. ISO 19115-2:2019 附录C XML 模式实现

    2024-06-14 17:20:03       33 阅读
  9. Spring Cloud应用框架

    2024-06-14 17:20:03       32 阅读