本章描述了如何为基于Qt的三种常见项目类型(应用程序application、库library和插件plugin)设置qmake项目文件。尽管所有项目类型都使用许多相同的变量,但每个项目类型都使用项目特定的变量来自定义输出文件。

此处不描述特定于平台的变量。有关更多信息,请参阅Qt for Windows - Deployment和Qt for macOS。

1 构建应用程序

app模板告诉qmake生成一个用于构建应用程序的Makefile。使用此模板,可以通过将以下选项之一添加到CONFIG变量定义来指定应用程序的类型:

选项 描述
windows 应用程序是Windows图形用户界面应用程序。
console 仅适用于app模板:应用程序是Windows控制台应用程序。
testcase 应用程序是自动化测试。

使用此模板时,qmake将识别以下系统变量。您应该在您的.pro文件中使用这些变量来指定有关您的应用程序的信息。有关其他平台相关的系统变量,请参阅平台注释。

  • HEADERS - 应用程序的头文件列表。
  • SOURCES - 应用程序的C++源文件列表。
  • FORMS - 应用程序的UI文件列表(使用Qt Designer创建)。
  • LEXSOURCES - 应用程序的Lex源文件列表。
  • YACCSOURCES - 应用程序的Yacc源文件列表。
  • TARGET - 应用程序的可执行文件名称。默认为项目文件的名称(自动添加扩展名)。
  • DESTDIR - 放置目标可执行文件的目录。
  • DEFINES - 应用程序所需的任何附加预处理器定义的列表。
  • INCLUDEPATH - 应用程序所需的任何附加包含路径的列表。
  • DEPENDPATH - 应用程序的依赖性搜索路径。
  • VPATH - 查找提供的文件的搜索路径。
  • DEF_FILE - 仅适用于Windows:应用程序链接的.def文件。

只需要使用您拥有值的系统变量。例如,如果没有额外的INCLUDEPATH,则无需指定任何INCLUDEPATH。qmake将添加必要的默认值。示例项目文件可能如下所示:

TEMPLATE = app
DESTDIR  = c:/helloapp
HEADERS += hello.h
SOURCES += hello.cpp
SOURCES += main.cpp
DEFINES += USE_MY_STUFF
CONFIG  += release

对于单值的项目,例如模板或目标目录,我们使用”=”;但对于多值的项目,我们使用”+=”来添加到该类型的现有项目中。使用”=”会替换变量值为新值。例如,如果我们写成DEFINES=USE_MY_STUFF,则会删除所有其他定义。

2 构建测试用例

测试用例项目是旨在作为自动化测试运行的应用程序项目。可以通过将值testcase添加到CONFIG变量来将任何应用程序标记为测试用例。

对于测试用例项目,qmake将在生成的Makefile中插入一个检查目标。该目标将运行应用程序。如果应用程序以退出代码为零终止,则测试被视为通过。

检查目标会自动遍历SUBDIRS项目。这意味着可以在SUBDIRS项目内部发出make check命令以运行整个测试套件。

可以通过某些Makefile变量来自定义检查目标的执行。这些变量包括:

  • TESTRUNNER - 附加到每个测试命令前的命令或shell片段。一个示例用例是一个”timeout”脚本,如果测试未在指定的时间内完成,它将终止测试。
  • TESTARGS - 附加到每个测试命令的其他参数。例如,可以传递附加参数以设置测试的输出文件和格式(例如,由QTestLib支持的-o filename,format选项)。

注意:这些变量必须在调用make工具时设置,而不是在.pro文件中设置。大多数make工具支持在命令行上直接设置Makefile变量的设置:

# 通过test-wrapper运行测试,并使用JUnit XML输出格式。
# 在此示例中,test-wrapper是一个虚构的包装脚本,如果未在“--timeout”中设置的秒数内完成测试,它将终止测试。
# "-o result.xml,junitxml"选项由QTestLib解释。
make check TESTRUNNER="test-wrapper --timeout 120" TESTARGS="-o result.xml,junitxml"

测试用例项目可以通过以下CONFIG选项进一步自定义:

选项 描述
insignificant_test 在make check期间将忽略测试的退出代码。

测试用例通常会使用QTest或TestCase编写,但使用CONFIG+=testcase和make check并非必须。唯一的主要要求是测试程序在成功时以零退出代码退出,在失败时以非零退出代码退出。

3 构建库

lib模板告诉qmake生成一个用于构建库的Makefile。使用此模板时,除了app模板支持的系统变量外,还支持VERSION变量。使用这些变量在您的.pro文件中指定有关库的信息。

使用lib模板时,可以将以下选项添加到CONFIG变量以确定所构建的库的类型:

选项 描述
dll 库是共享库(dll)
staticlib 库是静态库
plugin 库是插件

还可以定义以下选项以提供有关库的其他信息:

  • VERSION - 目标库的版本号,例如2.3.1。

库的目标文件名是与平台相关的。例如,在X11、macOS和iOS上,库名称将以lib前缀开头。在Windows上,文件名不添加前缀。

4 构建插件

插件是使用lib模板构建的,如前一节所述。这告诉qmake生成一个项目的Makefile,该项目将为每个平台构建插件,通常以库的形式。与普通库一样,VERSION变量用于指定有关插件的信息。

  • VERSION - 目标库的版本号,例如2.3.1。

4.1 构建Qt Designer插件

Qt Designer插件是使用特定的配置设置构建的,这些配置设置取决于Qt为您的系统配置的方式。为了方便起见,可以通过将designer添加到QT变量来启用这些设置。例如:

QT          += widgets designer

有关基于插件的项目的更多示例,请参阅Qt Designer示例。

5 在调试和发布模式下构建和安装

有时需要在调试和发布模式下构建项目。虽然CONFIG变量可以保存调试和发布选项,但只应用最后指定的选项。

5.1 在两种模式下构建

要使项目能够在两种模式下构建,必须将debug_and_release选项添加到CONFIG变量中:

CONFIG += debug_and_release

CONFIG(debug, debug|release) {
    TARGET = debug_binary
} else {
    TARGET = release_binary
}

上述代码段中的作用域会修改每种模式下的构建目标,以确保生成的目标具有不同的名称。为目标提供不同的名称可以确保一个不会覆盖另一个。

当qmake处理项目文件时,它将生成一个Makefile规则,允许以以下方式构建项目:

make all

可以将build_all选项添加到项目文件中的CONFIG变量中,以确保默认情况下以两种模式构建项目:

CONFIG += build_all

这允许使用默认规则处理Makefile:

make

6.1 在两种模式下安装

build_all选项还确保在调用安装规则时安装两个版本的目标:

make install

可以根据目标平台自定义构建目标的名称。例如,在Windows上,库或插件的命名可能与在Unix平台上使用的命名约定不同:

CONFIG(debug, debug|release) {
    mac: TARGET = $$join(TARGET,,,_debug)
    win32: TARGET = $$join(TARGET,,d)
}

上面的代码片段中的默认行为是在调试模式下修改用于构建目标的名称。可以在作用域中添加else子句以在发布模式下执行相同操作。如果不更改,目标名称将保持不变。

7 参考

Building Common Project Typess:https://doc.qt.io/qt-6/qmake-common-projects.html