qmake 语言

许多 qmake 项目文件只简单地描述项目使用的源文件和头文件,使用一系列 name = valuename += value 定义。qmake 还提供了其他操作符、函数和范围,可以用于处理变量声明中提供的信息。这些高级功能允许从一个项目文件生成适用于多个平台的 Makefile。

操作符

在许多项目文件中,可以使用赋值(=)和追加(+=)操作符包含有关项目的信息。典型的使用模式是分配一个值列表给一个变量,并根据各种测试结果追加更多值。由于 qmake 使用默认值定义了某些变量,有时需要使用移除(-=)操作符来过滤掉不需要的值。以下部分介绍如何使用操作符来操作变量的内容。

赋值

=操作符将值赋给一个变量

TARGET = myapp

上面的行将TARGET变量设置为myapp。这将使用myapp覆盖之前为TARGET设置的任何值。

追加值

+=操作符将新值追加到变量的值列表中

DEFINES += USE_MY_STUFF

上面的行将USE_MY_STUFF追加到要放入生成的 Makefile 中的预处理器定义的列表中。

移除值

-=操作符从变量的值列表中删除一个值

DEFINES -= USE_MY_STUFF

上面的行从要放入生成的 Makefile 中的预处理器定义的列表中删除了USE_MY_STUFF

添加唯一值

*=操作符将值添加到变量的值列表中,但只有当它尚未存在时。这防止了值在变量中被包含多次。例如

DEFINES *= USE_MY_STUFF

在上面的行中,只有当USE_MY_STUFF尚未定义时,才会将其添加到预处理器定义的列表中。请注意,unique()函数也可以用于确保变量只包含每个值的一个实例。

替换值

~=操作符用指定的值替换与正则表达式匹配的任何值

DEFINES ~= s/QT_[DT].+/QT

在上行中,列表中以QT_DQT_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文件添加到生成的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 变量。通常,: 操作符行为类似于逻辑与操作符,将多个条件连接在一起,并且要求所有条件都为真。

还有一个 | 操作符可以像逻辑或操作符一样工作,将多个条件连接在一起,只需其中一个条件为真即可。

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")
}

配置和范围

存储在 CONFIG 变量中的值在 qmake 中被特殊处理。每个可能的值都可以用作范围的条件。例如,CONFIG 存储的值列表可以通过 opengl 值扩展

CONFIG += opengl

在此操作的结果下,将处理测试 opengl 的所有范围。我们可以使用此功能为最终可执行文件提供一个合适的名称

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

此功能可以轻松更改项目的配置,而不会丢失可能需要为特定配置的所有自定义设置。在上述代码中,将处理第一个范围中的声明,最终可执行文件将被命名为 application-gl。但是,如果没有指定 opengl,则将处理第二个范围中的声明,最终可执行文件将被命名为 application

由于可以将自己的值放在 CONFIG 行上,这为您提供了自定义项目文件和微调生成的 Makefile 的便利方式。

平台范围值

除了在许多范围条件中使用的 win32macxunix 值外,还可以使用范围测试各种内置的平台和编译器特定值。这些基于 Qt 的 mkspecs 目录中提供的平台规范。例如,以下来自项目文件的行显示了当前正在使用的规范和测试 linux-g++ 规范

message($$QMAKESPEC)

linux-g++ {
    message(Linux)
}

只要在 mkspecs 目录中有针对该平台-编译器组合的定义,您就可以测试任何一个平台-编译器组合。

变量

在项目文件中使用的许多变量都是 qmake 生成 Makefile 时使用的特殊变量,例如 DEFINESSOURCESHEADERS。此外,您还可以创建自己使用的变量。当 qmake 遇到对该名称的赋值时,将使用给定名称创建新变量。例如

MY_VARIABLE = value

对于您的变量,没有任何限制,因为qmake会忽略它们,除非在处理作用域时需要评估它们。

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

MY_DEFINES = $$DEFINES

现在,MY_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)
}

© 2024 Qt公司有限公司。此处包括的文档贡献是各自所有者的版权。此处提供的文档是根据自由软件基金会发布的GNU自由文档许可证版本1.3的条款许可的。Qt及其相关标志是芬兰和/或其他国家和地区的Qt公司商标。所有其他商标均为其各自所有者的财产。