前面我们已经学习了 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。
最后部分没有新的内容,我们不再详细说明。