前面我们已经学习了 qtcreator.pro 和 qtcreator.pri 两个文件的代码。在 qtcreator.pro 中有这么一段代码:
TEMPLATE = subdirs CONFIG += ordered SUBDIRS = src share
这意味着,Qt Creator 会按照SUBDIRS定义的顺序编译。所以,下面我们需要从 src 目录开始。打开 src 目录,有这么几个目录和文件。

我们从最根本的 src.pro 开始。当TEMPLATE被定义为subdirs时,Qt 会去找SUBDIRS定义的各个目录中与目录同名的 .pro 文件。因此,src.pro 就是 src 目录的“结构说明文件”。我们也从这里开始。
include(../qtcreator.pri) TEMPLATE = subdirs CONFIG += ordered
前几行与之前看到的没有什么不同,这里不再赘述。后面有关 QBS 的内容则不在本文范围之内,暂时跳过。接下来的是,
SUBDIRS += \
libs \
app \
plugins \
tools \
share/qtcreator/data.pro \
share/3rdparty/data.pro 这意味着我们又要去 libs 目录,去找 libs.pro。libs.pro 也是一样的套路:首先引入 qtcreator.pri 文件,然后定义TEMPLATE为subdirs,接下来定义了SUBDIRS中所需要的所有目录。后面几行,
for(l, SUBDIRS) {
QTC_LIB_DEPENDS =
include($l/${l}_dependencies.pri)
lv = ${l}.depends
$lv = $QTC_LIB_DEPENDS
} 使用一个for循环,遍历SUBDIRS中定义的每一个目录,将QTC_LIB_DEPENDS赋值为$$l/$${l}_dependencies.pri的内容,该内容是由include函数引入的。如果此时的l为aggregation,那么,QTC_LIB_DEPENDS就会是include(aggregation/aggregation_dependencies.pri)的输出值。
鉴于 qmake 复杂的括号标记,我们可以总结一下:
| qmake 语句 | 含义 | 备注 |
VAR = foobar | 在 qmake 运行时,将值 foobar 赋给变量VAR | |
$$VAR | 在 qmake 运行时,获取 qmake 变量VAR的值 | |
$${VAR} | 在 qmake 运行时,获取 qmake 变量VAR的值 | $${VAR}与$$VAR等价,区别在于,$${VAR}能够将 VAR 与外围字符串分离开。例如,$$l_dependencies获取的是变量l_dependencies的值,而$${l}_dependencies则是获取变量l的值,然后作字符串拼接 |
$(VAR) | 在 make 运行时,获取环境变量的值 | |
$$(VAR) | 在 qmake 运行时,获取环境变量的值 |
.depends属性指明了这个库依赖于其它的库。例如,
TEMPLATE = subdirs
SUBDIRS += \
ConsoleTest \
SomeLibrary \
SomeExternalLibrary
# ConsoleTest.subdir 隐式设置为 ConsoleTest
SomeLibrary.subdir = SomeLibrary
SomeExternalLibrary.subdir = external/SomeExternalLibrary
SomeLibrary.depends = SomeExternalLibrary
ConsoleTest.depends = SomeLibrary 在这个 .pro 文件片段中,TEMPLATE依旧被设置为subdirs;SUBDIRS则分为三个目录。现在可以详细说明下SUBDIRS的含义。之前我们把SUBDIRS理解为实际的物理目录集合。这是不准确的。事实上,我们可以把SUBDIRS看作一个对象的集合。这些对象有subdir和depends两个属性。顾名思义,subdir即子目录名字;depends即依赖项。如果没有设置subdir,则默认去找同名目录,这就是为什么我们没有显式设置subdir,qmake 也成功找到了目录。depends则指定了依赖,例如上面的代码,SomeLibrary 依赖于 SomeExternalLibrary,ConsoleTest 则依赖于 SomeLibrary。
最后部分没有新的内容,我们不再详细说明。