高级用法

添加新配置特性

qmake 允许您创建自己的 特性,这些特性可以通过在 CONFIG 变量的值列表中添加它们的名称来包含到项目文件中。特性是位于多个标准目录中之一的 .prf 文件中的自定义函数和定义集合。这些目录的位置在多个位置定义,qmake 按以下顺序检查它们以查找 .prf 文件

  1. 在包含使用平台路径列表分隔符(Unix 中的冒号,Windows 中的分号)分隔的目录列表的 QMAKEFEATURES 环境变量列出的目录中。
  2. 在包含使用平台路径列表分隔符分隔的目录列表的 QMAKEFEATURES 属性变量列出的目录中。
  3. mkspecs 目录中具有特性目录。可以找到这些目录之一在包含使用平台路径列表分隔符分隔的目录列表的 QMAKEPATH 环境变量下。例如:$QMAKEPATH/mkspecs/<features>
  4. 在与 QMAKESPEC 环境变量提供的目录中具有特性目录。例如:$QMAKESPEC/<features>
  5. data_install/mkspecs 目录中具有特性目录。例如:data_install/mkspecs/<features>
  6. 在作为 QMAKESPEC 环境变量指定的目录的兄弟目录中具有特性目录。例如:$QMAKESPEC/../<features>

以下特性目录会搜索特性文件

  1. 根据使用的平台为 features/unixfeatures/win32features/macx
  2. features/

例如,考虑以下项目文件中的以下赋值

CONFIG += myfeatures

添加到 CONFIG 变量中的这个添加将在 qmake 完成解析您的项目文件后搜索上述位置中的 myfeatures.prf 文件。在 Unix 系统上,它将寻找以下文件

  1. $QMAKEFEATURES/myfeatures.prf(在 QMAKEFEATURES 环境变量列出的每个目录中)
  2. $$QMAKEFEATURES/myfeatures.prf(在 QMAKEFEATURES 属性变量列出的每个目录中)
  3. myfeatures.prf(项目的根目录中)。项目根由顶级 .pro 文件确定。但是,如果您将 .qmake.cache 文件放在子目录或子项目的目录中,则项目根变为该子目录本身。
  4. $QMAKEPATH/mkspecs/features/unix/myfeatures.prf$QMAKEPATH/mkspecs/features/myfeatures.prfQMAKEPATH 环境变量列出的每个目录中)
  5. $QMAKESPEC/特性/unix/myfeatures.prf$QMAKESPEC/特性/myfeatures.prf
  6. data_install/mkspecs/特性/unix/myfeatures.prfdata_install/mkspecs/特性/myfeatures.prf
  7. $QMAKESPEC/../特性/unix/myfeatures.prf$QMAKESPEC/../特性/myfeatures.prf

注意: .prf 文件必须使用小写字母命名。

安装文件

在 Unix 中,也常用构建工具来安装应用程序和库;例如,通过调用 make install。因此,qmake 有“安装集”的概念,这是一个包含关于项目某部分安装方式的说明的对象。

documentation.path = /usr/local/program/doc
documentation.files = docs/*

path 成员告知 qmake 文件应安装到 /usr/local/program/doc(路径成员),而 files 成员指定要复制到安装目录的文件。在这种情况下,docs 目录中的所有内容都将复制到 /usr/local/program/doc

一旦完全描述了安装集,就可以使用以下行将其追加到安装列表中

INSTALLS += documentation

qmake 将确保指定的文件被复制到安装目录。如果您需要对此过程有更多控制,也可以为对象的 extra 成员提供定义。例如,以下行告诉 qmake 对此安装集执行一系列命令

unix:documentation.extra = create_docs; mv master.doc toc.doc

unix 范围 确保这些特定命令仅在 Unix 平台上执行。可以使用其他范围规则定义其他平台适当的命令。

extra 成员中指定的命令在执行对象的其它成员中的说明之前执行。

如果您将内置的安装集追加到 INSTALLS 变量,并未指定 filesextra 成员,qmake 将为您决定需要复制的文件。目前,支持 targetdlltarget 安装集。例如

target.path = /usr/local/myprogram
INSTALLS += target

在上面的行中,qmake 知道需要复制什么,并将自动处理安装过程。

添加自定义目标

qmake 尝试做跨平台构建工具预期的一切。当您真的需要运行特殊平台依赖性命令时,这通常并不是理想的。这可以通过向不同的 qmake 后端提供特定说明来实现。

Makefile 输出的定制通过类似于 qmake 其它地方的面向对象 API 来执行。通过指定它们的 成员 来自动定义对象。例如

mytarget.target = .buildfile
mytarget.commands = touch $$mytarget.target
mytarget.depends = mytarget2

mytarget2.commands = @echo Building $$mytarget.target

如上所述的定义创建了一个名为 mytarget 的 qmake 目标,其中包含一个名为 .buildfile 的 Makefile 目标,该目标通过 touch 命令生成。最后,.depends 成员指定 mytarget 依赖于后来定义的另一个目标 mytarget2mytarget2 是一个虚拟目标。它仅用于向控制台输出某些文本。

最后一步是使用 QMAKE_EXTRA_TARGETS 变量来指导 qmake 此对象是一个要构建的目标

QMAKE_EXTRA_TARGETS += mytarget mytarget2

这就是构建自定义目标所需做的全部工作。当然,您可能希望将这些目标之一与 qmake 构建目标 绑定。为此,您只需将您的 Makefile 目标包含在 PRE_TARGETDEPS 列表中即可。

自定义目标规范支持以下成员

成员描述
命令用于生成自定义构建目标的命令。
CONFIG为自定义构建目标指定的特定配置选项。可以设置为 recursive 来指明应该在 Makefile 中创建规则以调用子目标特定的 Makefile 中的相关目标。此成员默认为为每个子目标创建条目。
depends自定义构建目标所依赖的现有构建目标。
recurse指定在 Makefile 中创建规则并调用子目标特定的 Makefile 时应使用的子目标。此成员仅当在 CONFIG 中设置 recursive 时使用。典型值是 "Debug" 和 "Release"。
recurse_target指定通过子目标 Makefile 为 Makefile 中的规则构建的目标。此成员添加类似 $(MAKE) -f Makefile.[subtarget] [recurse_target] 的内容。此成员仅当在 CONFIG 中设置 recursive 时使用。
target自定义构建目标的名字。

添加编译器

可以自定义 qmake 以支持新的编译器和预处理器。

new_moc.output  = moc_${QMAKE_FILE_BASE}.cpp
new_moc.commands = moc ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT}
new_moc.depend_command = g++ -E -M ${QMAKE_FILE_NAME} | sed "s,^.*: ,,"
new_moc.input = NEW_HEADERS
QMAKE_EXTRA_COMPILERS += new_moc

有了上述定义,你可以使用可选的 moc 做 буде-vector replacement。该命令将对 NEW_HEADERS 变量(来自 input 成员)的所有参数执行,并将结果写入到由 output 成员定义的文件中。此文件将添加到项目中的其他源文件中。此外,qmake 将执行 depend_command 以生成依赖信息,并将此信息添加到项目中。

自定义编译器规格支持以下成员

成员描述
命令用于从输入生成输出的命令。
CONFIG为自定义编译器指定的特定配置选项。有关详细信息,请参阅 CONFIG 表。
depend_command指定用于生成输出文件依赖列表的命令。
dependency_type指定输出的文件类型。如果是已知类型(如 TYPE_C, TYPE_UI, TYPE_QRC),则将其视为该类型之一处理。
depends指定输出文件的依赖关系。
input指定应与自定义编译器处理的文件变量。
name对自定义编译器正在执行的描述。这仅在某些后端中使用。
output从自定义编译器创建的文件名。
output_function指定用于指定要创建的文件名的自定义 qmake 函数。
variables在此指定的变量在作为 $(VARNAME) 在 pro 文件中引用时用 $(QMAKE_COMP_VARNAME) 替换。
variable_out应将输出创建的文件添加到其变量。

CONFIG 成员支持以下选项

选项描述
combine指示将所有输入文件合并为一个输出文件。
target_predeps指示应将输出添加到 PRE_TARGETDEPS 列表中。
explicit_dependencies仅从 depends 成员生成输出文件的依赖关系,而不从其他地方生成。
dep_existing_only检查 .depend_command 的每个结果依赖项是否存在。忽略不存在的依赖项。此值是在 Qt 5.13.2 中引入的。
dep_lines.depend_command 的输出解释为每行一个文件。默认情况下是在空白处拆分,仅为了向后兼容。
no_link指示不应将输出添加到要链接的对象列表中。

库依赖关系

通常情况下,当链接到一个库时,qmake 依赖于底层平台知道该库链接到哪些其他库,并允许平台将这些库自动链接进来。然而,在很多情况下,这并不足够。例如,当静态链接一个库时,没有链接到其他库,因此也没有创建对这些库的依赖。然而,后来链接到这个库的应用程序需要知道静态库所需的符号在哪里。如果显式启用跟踪,qmake 将尝试跟踪库的依赖项。

第一个步骤是在库本身中启用依赖跟踪。为此,您必须告诉 qmake 保存有关库的信息。

CONFIG += create_prl

这仅适用于 lib 模板,对于其他模板将被忽略。当此选项启用时,qmake 将创建一个以 .prl 结尾的文件,以保存关于库的一些元信息。这个元文件就像一个普通的项目文件,但只包含内部变量声明。在安装这个库时,将其指定为 INSTALLS 声明中的目标,qmake 将自动将 .prl 文件复制到安装路径。

这个过程的第二个步骤是在使用静态库的应用程序中启用读取这些元信息的功能。

CONFIG += link_prl

当启用时,qmake 将处理应用程序链接到的所有库,并找到它们的元信息。qmake 将使用这些信息确定相关的链接信息,具体来说,向应用程序项目文件的 DEFINES 列表中添加值,以及 LIBS。一旦 qmake 处理了此文件,它将检查 LIBS 变量中新引入的库,找到它们的依赖于 .prl 文件,持续到所有库都已解析。此时,将按照常规创建 Makefile,并将库显式链接到应用程序。

.prl 文件应由 qmake 仅创建,不应在不同操作系统之间传输,因为它们可能包含依赖平台的特定信息。

© 2024 Qt 公司。此处包含的文档贡献者是各自版权的拥有者。本文档是根据自由软件基金会发布的 GNU自由文档许可证版本 1.3 许可的。Qt 以及其相应的标志是在芬兰和/或全球的其他国家的商标,属于 Qt 公司所有。所有其他商标是各自拥有者的财产。