多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## A.2 使用 qmake qmake 工具是与 Qt 一起提供的。它用来编译 Qt 本身,并且生成 Qt 自带的工具和例 子。贯穿整书,我们一直使用 qmake 工程文件(.pro 文件)编译示例应用程序。本附录将 系统(但非全面)的学习.pro 文件的语法,并且会介绍几个 qmake 的基本概念。要想全面 了解它们,请参阅 qmake 指南的在线帮助文档。 ### A.2.1 .pro 文件语法 .pro 文件的目的是列举工程中包含的源文件。由于 qmake 用于编译 Qt 及其相关工具, 所以它很熟悉 Qt,并且能够生成一些触发 moc、uic、和 rcc 的规则。因此,qmake 的语法 很简明,而且很容易学习。 工具文件主要分为三种:app(单独的应用程序)、lib(静态和动态库)和 subfirs(递归编译)。工程文件的类型可以使用 TEMPLATE 变量指定如下: ``` TEMPLATE = lib ``` subdirs 模板可以用来编译子目录里的目标文件。在这种情况下,除 TEMPLATE = subdirs 外,还需要指定 SUBDIRS 变量。在每个子目录中,qmake 会搜寻以目录名命名 的.pro 文件,并且会编译该工程。如果没有 TEMPLATE 这一项,那么默认工程是 app。对于 app 或者 lib 工程,最常用使用的变量是下面这些: + HEADERS 指定工程的 C++头文件(.h)。 + SOURCES 指定工程的C++实现文件(.cpp)。 + FORMS 指定需要 uic 处理的由 Qt 设计师生成的.ui 文件。 + RESOURCES 指定需要 rcc 处理的.qrc 文件。 + DEFINES 指定预定义的 C++预处理符号。 + INCLUDEPATH 指定 C++编译器搜索全局头文件的路径。 + LIBS 指定工程要链接的库。库既可以通过绝对路径指定,也可以使用源自 Unix 的- L 和-l 标识符来指定(例如,-L/usr/local/lib 和-ldb_cxx)。 + CONFIG 指定各种用于工程配置和编译的参数。 + QT 指定所要使用的 Qt 模块(默认是 core gui,对应于 QtCore 和 QtGui 模块)。 + VERSION 指定目标库的版本号。 + TARGET 指定可执行文件或库的基本文件名,其中不包含任何的扩展、前缀或版本 号(默认的是当前的目录名)。 + DESTDIR 指定可执行文件放置的目录(默认值是平台相关的。例如,在 Linux 上,指当前目录;在 Windows 上,则是指 debug 或 release 子目 录)。 + DLLDESTDIR 指定目标库文件放置的目录(默认路径与 DESTDIR 相同)。 + CONFIG 变量用来控制编译过程中的各个方面。它支持下面这些参数: + debug 是指具有调试信息的可执行文件或者库,链接 Qt 库的调试版。 + release 是指编译不具有调试信息的可执行文件或者库,链接发行版的 Qt 库。如果 同时指定 debug 和 release,则 debug 有效。 + warn_off 会关闭大量的警告。默认情况下,警告的状态是打开的。 + qt 是指应用程序或者库使用 Qt。这一选项是默认包括的。 + dll 是指动态编译库。 + staticlib 是指静态编译库。 + plugin 是指编译一个插件。插件总是动态库,因此这一参数暗含 dll 参数。 + console 是指应用程序需要写控制台(使用 cout、cerr、qWarning(),等等)。 + app_bundle 只适用于 Mac OS X 编译,是指可执行文件被放到束中,这是 Mac OS X 的默认情况。 + lib_bundle 只适用于 Mac OS X 编译,指库被放到框架中。 要生成工程文件 hello.pro 的 makefile,可以输入: ``` qmake hello.pro ``` 在这之后,可以调用 make 或 nmake 编译工程。通过键入以下命令,也可以使用 qmake 生成一个 Microsoft Visual Studio 工程(.dsp 或.vproj)文件: ``` qmake -tp vd hello.pro ``` 在 Mac OS X 系统上,可以创建一个 Xcode 工程文件: ``` qmake -spec macx-xcode hello.pro ``` 要创建 makefile,可以输入: ``` qmake -spec macx-g++ hello.pro ``` 这里的-spec 命令行参数可以用来指定平台/编译器的组合。通常,qmake 可以正确的检测到所在的平台,但在某些情况下则由必要显式的指定平台的情况。例如,在 Linux 上 以 64 位模式调用 Intel C++编译器(ICC)生成 makefile,应当输入: ``` qmake -spec linux-icc-64 hello.pro ``` 那些可用的规则在 Qt 的 mkspecs 目录中。 尽管 qmake 的主要用途是生成.pro 文件的 makefile,但也可以使用-project 参数在当 前目录下使用 qmake 生成.pro 文件,例如: ``` qmake -project ``` 在这种模式下,qmake 将搜索当前目录下已知扩展名(.h、.cpp、.ui 等等)的文件,生成一个列举这些文件的.pro 文件。 本附录的余下部分将更详细的介绍.pro 文件的语法。一个.pro 文件中的条目的语法通 常具有如下形式: ``` variable = values ``` values 是字符串的列表。注释以井号(#)开头,在行尾处结束。例如: ``` CONFIG = qt release warn_off # I know what I'm doing ``` 将列表["qt","release","warn_off"]赋给 CONFIG 变量,它会覆盖以前的各个值。 额外的操作符作为=操作符的补充。+=操作符可以用来扩展变量的值。因此: ``` CONFIG = qt CONFIG += release CONFIG += warn_off ``` 这几行会和前面的例子一样,可以有效的把列表 ["qt","release","warn_off"] 赋值给 CONFIG 变量。-=操作符从当前的变量中移除所有出现的指定的值。因此: ``` CONFIG = qt realease warn_off CONFIG -= qt ``` 会使 CONFIG 的值变成["release","warn_off"]。*=操作在一个变量上添加一个值,但要求被添加的值不在变量的列表上;否则,就什么都不做。例如: ``` SOURCE *= main.cpp ``` 这一行将把 main.cpp 实现文件添加到工程中,只有当还没有被添加的情况下才添加它。最后,=操作符使用指定的值替换符合正则表达式的值,这是一种类似于 sed(UNIX 流 编辑器)的语法。 例如: ``` SOURCE ~= s/\.cpp\b/.cxx/ ``` 使用.cxx 替换 SOURCES 变量中所有.cpp 文件的扩展名。 在值的列表中,qmake 提供了访问其他 qmake 变量、环境变量和配置参数的方法。表附 录 A-1 列举了这些语法。 表附录 A-1 qmake 变量语法 | 存取函数 | 说明 | | --- | --- | | $$var/Name 或者$${varName} | .pro 文件中 qmake 变量在那一时刻的值 | | $$(varName) | 当 qmake 运行时环境变量的值 | | $(varName) | 当处理 makefile 时环境变量的值 | | $$[varName] | Qt 的配置参数值 | ### A.2.2 qmake 的存取函数 前面的例子中使用的总是一些标准变量,例如 SOURCES 和 CONFIG,然而,我们也可以 设置任意变量的值,并且可以使用 $$varName 或者$${varName}语法引用它。例如: ``` MY_VRESION = 1.2 SOURCE_BASIC = alphadialog.cpp \ main.cpp \ windowpanel.cpp SOURCE_EXTRA = bezierextension.cpp \ xplot.cpp SOURCES = $$SOURCES_BASIC \ $$SOURCES_EXTRA TARGET = imgpro_$${MY_VERSION} ``` 接下来的例子组合了前面介绍的几种语法,使用内置函数 $$lower()把字符串转换为小写: ``` # List of classes in the project MY_CLASS = Annotation \ CityBlock \ CityScape \ CityView # Append .cpp extension to lowercased class names,and add main.cpp SOURCES = $$lower($$MY_CLASSES) SOURCES ~= s/([a-z0-9_]+)/\1.cpp/ SOURCES += main.cpp # Append .h extension to lowercased class names HEADERS = $$lower($$MY_CLASSES) HEADERS ~= s/([a-z0-9_]+)/\1.h/ ``` 有时可能需要在.pro 文件中指定包含空格的文件名。在这种情况下,只需简单的把文件名用引号括起来即可。 当在不同的平台上编译工程时,可能有必要基于平台指定不同的文件或者不同的参 数。qmake 的条件语法是: ``` condition { then-case } else { else-case } ``` condition 部分可以是平台名字(例如,win32、unix、或者 macx),或者更复杂的断言。then-case 和 else-case 部分使用标准语法为变量赋值。例如: ``` win32 { SOURCES += serial_win.cpp } else { SOURCES += serial_unix.cpp } ``` else 分支是可选的。为了方便,当 then-case 部分仅有一条变量赋值,而且在没有 else-case 分支时,qmake 也支持单行形式的语法: ``` condition:then-case ``` 例如: ``` macx:SOURCE += serial_mac.cpp ``` 如果有几个工程文件需要共享相同的项,则可以把相同的项提取到单独的文件中,在各自的.pro 文件中使用 include()语句包含它们: ``` include(../common.pri) HEADERS += window.h SOURCES += main.cpp \ window.cpp ``` 通常,打算被别的工程文件所包含的工程文件会带有 .pri(工程包含)的扩展名。 在前面的例子中,我们了解了$$lower()内置函数,它可以返回参数的小写版本。另外 一个有用的函数是$$system(),它允许我们从外部应用程序中产生字符串。例如,如果想要 确认当前使用的 UNIX 版本,可以这样写: ``` OS_VERSION = $$ system(uname -r) ``` 然后,可以在条件中使用结果变量,并与 contains()合用: ``` contains(OS_VERSION,SunOS):SOURCES += mythread_sun.c ``` 本附录只讲了一些表面的东西。qmake 工具提供了许多参数和特性,远多于这里所讲到的这些,包括对预编译头文件的支持、对 Mac OS X 通用二进制库的支持以及对用户定义的 编译器或者其他工具的支持等。对于这方面更多信息的了解,可以参阅 qmake 指南在线帮助文档。