本页内容

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

上述代码行将 `USE_MY_STUFF ` 从将写入生成的 Makefile 中的预处理器定义列表中移除。

添加唯一值

*= 运算符将一个值添加到变量的值列表中,但仅当该值尚未存在时才添加。这可防止某个值被多次包含在变量中。例如:

DEFINES *= USE_MY_STUFF

在上文中,只有当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 的值是在项目文件被处理时立即读取的,但在生成的Makefile中,$(PWD) 被赋值给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 Widgets Designer 插件即可与Qt Widgets Designer 的内置插件一同安装:

target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target

作用域

作用域类似于过程式编程语言中的if 语句。如果某个条件为真,则会处理作用域内的声明。

作用域语法

作用域由一个条件组成,该条件后紧跟同一行上的左大括号,接着是一系列命令和定义,最后在新行上以右大括号结束:

<condition> {
    <command or definition>
    ...
}

左大括号必须与条件位于同一行。如后续章节所述,作用域可以串联起来包含多个条件。

作用域与条件

作用域的写法是:一个条件,后跟一组包含在一对大括号内的声明。例如:

win32 {
    SOURCES += paintwidget_win.cpp
}

上述代码将在为 Windows 平台构建时,将paintwidget_win.cpp 文件添加到生成的 Makefile 中列出的源文件列表中。当为其他平台构建时,该定义将被忽略。

特定作用域中使用的条件还可以进行否定,以提供一组替代声明,这些声明仅在原始条件为假时才会被处理。例如,若要在除Windows以外的所有平台上进行构建时处理某些内容,可按如下方式对作用域进行否定:

!win32 {
    SOURCES -= paintwidget_win.cpp
}

作用域可以嵌套,以组合多个条件。例如,若要仅在启用调试时为特定平台包含某个文件,请编写如下代码:

macx {
    CONFIG(debug, debug|release) {
        HEADERS += debugging.h
    }
}

为避免编写大量嵌套作用域,可使用: 运算符进行嵌套。上例中的嵌套作用域可重写为:

macx:CONFIG(debug, debug|release) {
    HEADERS += debugging.h
}

您还可以使用 `: ` 运算符进行单行条件赋值。例如:

win32:DEFINES += USE_MY_STUFF

上述代码行仅在针对 Windows 平台构建时,才将 `USE_MY_STUFF ` 添加到 `DEFINES` 变量中。通常,`: ` 运算符的行为类似于逻辑与(AND)运算符,它将多个条件组合在一起,并要求所有条件均为真。

此外还有| 运算符,其作用类似于逻辑“或”(OR)运算符,将多个条件组合在一起,且只需其中一个条件为真即可。

win32|macx {
    HEADERS += debugging.h
}

如果需要混合使用这两个运算符,可以使用 `if ` 函数来指定运算符的优先级。

if(win32|macos):CONFIG(debug, debug|release) {
    # Do something on Windows and macOS,
    # but only for the debug configuration.
}
win32|if(macos:CONFIG(debug, debug|release)) {
    # Do something on Windows (regardless of debug or release)
    # and on macOS (only for debug).
}

该条件支持通配符,用于匹配一组CONFIG 值或mkspec名称。

win32-* {
    # Matches every mkspec starting with "win32-"
    SOURCES += win32_specific.cpp
}

注意:从历史上看 ,像上面那样使用通配符检查 mkspec 名称是 qmake 检查平台的一种方式。如今,我们建议在QMAKE_PLATFORM 变量中使用由 mkspec 定义的值。

您还可以通过使用else 作用域,为该作用域内的声明提供替代声明。当前面的作用域条件为假时,每个else 作用域都会被处理。这使您能够与其他作用域结合(如上文所示,使用: 运算符分隔)编写复杂的测试。例如:

win32:xml {
    message(Building for Windows)
    SOURCES += xmlhandler_win.cpp
} else:xml {
    SOURCES += xmlhandler.cpp
} else {
    message("Unknown configuration")
}

配置与作用域

qmake 会对存储在CONFIG变量中的值进行特殊处理。每个可能的值均可作为作用域的条件。例如,可以通过添加opengl 值来扩展CONFIG 所包含的值列表:

CONFIG += opengl

通过此操作,任何以opengl 为条件的范围都会被处理。我们可以利用此功能为最终可执行文件赋予适当的名称:

opengl {
    TARGET = application-gl
} else {
    TARGET = application
}

此功能使得更改项目配置变得十分简单,同时不会丢失特定配置可能需要的所有自定义设置。 在上述代码中,将处理第一个作用域中的声明,最终可执行文件将命名为application-gl 。但是,如果未指定opengl ,则会处理第二个作用域中的声明,最终可执行文件将命名为application 。

由于可以在CONFIG 这一行中指定自定义值,这为您提供了自定义项目文件并微调生成的 Makefile 的便捷方式。

平台作用域值

除了许多作用域条件中使用的win32 、macx 和unix 值外,还可以使用作用域测试各种其他内置的平台和编译器特定值。这些值基于 Qt 的mkspecs 目录中提供的平台规范。例如,项目文件中的以下几行显示了当前使用的规范,并测试了linux-g++ 规范:

message($$QMAKESPEC)

linux-g++ {
    message(Linux)
}

只要在mkspecs 目录中存在相应的规范,您就可以对任何其他平台-编译器组合进行检测。

变量

项目文件中使用的许多变量都是 qmake 在生成 Makefile 时使用的特殊变量,例如DEFINES、SOURCES 和HEADERS。此外,您还可以创建供自己使用的变量。当 qmake 遇到对某个名称的赋值时,会创建一个具有该名称的新变量。例如:

MY_VARIABLE = value

对自定义变量的操作没有任何限制,因为除非在处理作用域时需要评估它们,否则 qmake 会忽略这些变量。

您还可以通过在变量名前添加 $$ 前缀,将当前变量的值赋给另一个变量。例如:

MY_DEFINES = $$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 提供了内置函数,可在编写作用域时用作条件。这些函数不返回值,而是指示成功或失败:

count(options, 2) {
    message(Both release and debug specified.)
}

此类函数仅应用于条件表达式中。

您可以定义自定义函数来为作用域提供条件。以下示例测试列表中每个文件是否存在,如果所有文件都存在则返回 true,否则返回 false:

defineTest(allFiles) {
    files = $$ARGS

    for(file, files) {
        !exists($$file) {
            return(false)
        }
    }
    return(true)
}

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.