qmake手册——qmake语言
qmake语言
许多qmake项目文件只是简单的描述了项目使用的源文件和头文件,使用了一列形如name=value或者
name+=value的表达式。但是qmake也提供了其他的操作符,函数还有域。这些可以用来处理变量声明
中提供的信息。这些高级特性使得仅仅使用一个项目文件就能为多个平台生成makefile
操作符
在许多项目文件中,赋值符号(=)和追加符号(+=)被用来包含项目中的全部信息,典型的使用
模式是给一个变量赋一列值,然后根据各种测试追加更多的值,因为qmake使用默认的值定义了
一些变量,所以有时候使用移除符号(-=)剔除一些不需要的值也是必要的。下面几节描述了
如何使用运算符来操作变量的内容。
分配值
“=“运算符为变量分配一个值: TARGET = myapp
上面的一行将TARGET的值设置为myapp,myapp会覆盖TARGET之前的所有值。
追加值
”+=“运算符向变量的值列表中追加一个新值。 DEFINES += USE_MY_STUFF
上述行将USE_MY_STUFF附加到要在生成的Makefile中放置的预处理器定义的列表中。
移除值
”-=“运算符从变量的值列表中删除一个值 DEFINES -= USE_MY_STUFF
添加唯一值
仅当一个值在变量的值列表中不存在时,”*=”运算符才会将它添加到值列表中。
这可以防止一个值的多次引用 。 DEFINES *= USE_MY_STUFF
注意函数unique()函数也可以被用来确定一个变量中的每个值只有一个实例。
替换值
“~=”运算符可以将任何符合正则运算符的值替换为指定的值 DEFINES ~= s/QT_[DT].+/QT
在上面的一行中,任意以QT_D
或QT_T
开头的值都会被替换为QT
变量扩展
$$
运算符可以提取一个变量的值,还可以被用来在两个变量之间传递值或者
提供给函数
EVERYTHING = $$SOURCES $$HEADERS
message("The project contains the following files:")
message($$EVERYTHING)
变量可以用来存储环境变量,当qmake被运行时这些环境变量能够被评估,或者
这些变量也可以被包含到生成的makefile中,当构建项目时再评估。
想要在qmake运行时获得环境变量的内容,使用$$(…)运算符:
DESTDIR = $$(PWD)
message(The project will be installed in $$DESTDIR)
在上面的表达式中,环境变量“PWD”的值会在项目文件被处理时读取。
想要在makefile运行时获得环境变量的内容,使用$(…)运算符:
DESTDIR = $$(PWD)
message(The project will be installed in $$DESTDIR)
DESTDIR = $(PWD)
message(The project will be installed in the value of PWD)
message(when the Makefile is processed.)
在上面的表达式中,PWD的值会在处理项目文件时立刻读取,但是$(PWD)被赋值给了
生成的makefile中的DESTDIR。这将会使得构建过程更加灵活,只要在makefile
执行时环境变量被正确设置。
访问qmake属性
特殊操作符$$[...]
可以用来访问qmake属性。
message(Qt version: $$[QT_VERSION])
message(Qt is installed in $$[QT_INSTALL_PREFIX])
message(Qt resources can be found in the following locations:)
message(Documentation: $$[QT_INSTALL_DOCS])
message(Header files: $$[QT_INSTALL_HEADERS])
message(Libraries: $$[QT_INSTALL_LIBS])
message(Binary files (executables): $$[QT_INSTALL_BINS])
message(Plugins: $$[QT_INSTALL_PLUGINS])
message(Data files: $$[QT_INSTALL_DATA])
message(Translation files: $$[QT_INSTALL_TRANSLATIONS])
message(Settings: $$[QT_INSTALL_CONFIGURATION])
message(Examples: $$[QT_INSTALL_EXAMPLES])
要获取更多信息,查看“配置qmake”
此操作符可访问的属性通常用于使第三方插件和组件能够集成到Qt中。例如,一个
QT Designer插件能够被安装到QT Designer的内建插件旁边,如果在项目文件
中输入下列声明:
target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target
域
域与编程语言中的if语句很像,如果某一条件为真,域中的语句就将会执行。
域的语法
域由包括一个条件,后面是同一行上的左括号,一系列命令和定义,以及一个
新行上的右括号:
<condition> {
<command or definition>
...
}
左括号一定要和条件写在同一行。条件可能会有多个。
域和条件
范围被写成一个条件,后跟一对括号中包含的一系列声明。例如:
win32 {
SOURCES += paintwidget_win.cpp
}
上面的代码表明如果在Windows平台上构建的话paintwidget_win.cpp就会被
添加到源代码列表中。当为其他平台构建时,该定义会被忽略。
域的条件也可以被否定,以提供仅在原始条件为假时才会处理的替代的一组声明。
例如,例如,为Windows之外的所有平台构建时要处理某些内容,可以这样做:
!win32 {
SOURCES -= paintwidget_win.cpp
}
域还可以嵌套组合多个条件,例如,在debug开启时为某一平台包含一个特定文件,
可以这么做:
macx {
CONFIG(debug, debug|release) {
HEADERS += debugging.h
}
}
你还可以使用:运算符来在一行中执行条件语句,例如:
win32:DEFINES += USE_MY_STUFF
上面这行表明,仅当为Windows平台构建时,向DEFINES变量添加一个值。
通常情况下,冒号运算符的行为就像一个逻辑与运算符,将许多条件组合起来,
并且要求它们都为真。
还有一个|操作符,他的行为就像一个逻辑或操作符,将许多条件组合起来,只要它们中的一个
为为真就为真。
win32|macx {
HEADERS += debugging.h
}
你还可以使用else来提供二选一的声明,当前一个域的条件失败else域就会执行,这样就可以
使用域来写复杂的测试。例如:
win32:xml {
message(Building for Windows)
SOURCES += xmlhandler_win.cpp
} else:xml {
SOURCES += xmlhandler.cpp
} else {
message("Unknown configuration")
}
设置与域
在变量CONFIG中存储的值会被qmake特殊对待,其中的每一个值都会被视为一个域的条件。
例如,CONFIG中可以使用opengl扩展,
CONFIG += opengl
作为这个操作的结果,任何检测opengl的域都会成功,
我们可以使用这个特性来给最后的可执行文件起一个合适的名字。
opengl {
TARGET = application-gl
} else {
TARGET = application
}
此功能可以轻松更改项目的配置,而不必担心丢失特别指定的设置。在上面的代码中,
第一个域中的代码将会执行,最后的可执行文件会叫做application-gl。然后,如果
opengl没有被定义,第二个域中会被执行,最终应用将会叫application。
所以你可以通过对CONFIG的值的配置来很方便的控制生成的makefile。
特定平台下的域的值
许多域的条件是内建的平台或编译器指定的值,比如win32,macx,unix。这些都是
基于Qt的mkspecs目录中提供的平台规范。例如,下面这几行显示了当前项目文件中
有关
the following lines from a project file show the current specification in use and test for the linux-g++ specification:
message($$QMAKESPEC)
linux-g++ {
message(Linux)
}
You can test for any other platform-compiler combination as long as a specification exists for it in the mkspecs directory.
变量
许多变量都是qmake在生成makefile时使用的特殊变量。例如DEFINES,SORUCES和HEADERS,
当然,你也可以自己定义变量。当遇到与给某个名称赋值时,qmake就创建具有给定名称的新变量。
例如: MY_VARIABLE = value
你可以对这些变量做任何事,应为qmake会忽略他们,除非在处理域时需要检测它们。
你可以通过使用前缀$$
来将一个变量的值赋给另一个变量。例如 MY_DEFILES = $$DEFINES
现在变量MY_DEFINES包含了当前变量DEFINES的值,这与下面这句话是等同的: MY_DEFINES = $${DEFINES}
第二种表示法允许你将这个变量的值附加到另一个值的后面而不用空格分离。
下面这个例子将确保最后的可执行文件会被赋给一个包含使用的项目模板的名字: TARGET = myproject_$${TEMPLATE}
替换函数
qmake提供了一些内置函数,以允许处理变量的内容。这些函数处理提供给它们
的参数,并返回一个值或值列表。要把结果赋给一个变量,在这类函数前面添加 $$
运算符,就像把一个变量的值赋给另一个一样:
HEADERS = model.h
HEADERS += $$OTHER_HEADERS
HEADERS = $$unique(HEADERS)
这类函数应该放在等于号的右边。
你可以像下面这样定义你自己的函数:
defineReplace(functionName){
#function code
}
以下示例函数将变量名称作为其唯一参数,并使用eval()内置函数从变量
中提取值列表,并编译文件列表:
defineReplace(headersAndSources) {
variable = $$1
names = $$eval($$variable)
headers =
sources =
for(name, names) {
header = $${name}.h
exists($$header) {
headers += $$header
}
source = $${name}.cpp
exists($$source) {
sources += $$source
}
}
return($$headers $$sources)
}
测试函数
qmake提供了一些可以用做域的条件的内建函数。这个函数返回的是success或failure而不是一个值。
count(options, 2) {
message(Both release and debug specified.)
}
这类函数应当只用作条件表达式。
你也可以自己写这类函数,下面这个例子检测了所有文件是否都在一个列表中:
defineTest(allFiles) {
files = $$ARGS
for(file, files) {
!exists($$file) {
return(false)
}
}
return(true)
}