测试函数

测试函数返回一个布尔值,您可以在作用域的条件的部分中测试它。测试函数可以分为内置函数和函数库。

另请参阅 替换函数.

内置测试函数

基本测试函数以内置函数的形式实现。

cache(variablename, [set|add|sub] [transient] [super|stash], [source variablename])

这是一个内部函数,您通常不需要它。

该函数在 Qt 5.0 中引入。

CONFIG(config)

此函数可用于测试是否将变量放入 CONFIG 变量中。这与作用域相同,但具有额外的优势,即可以传递第二个参数来测试活动配置。因为 CONFIG 变量中的值顺序很重要(也就是说,最后一个设置的值将被认为是相互排斥值的活动配置),因此可以使用第二个参数指定一组要考虑的值。例如

CONFIG = debug
CONFIG += release
CONFIG(release, debug|release):message(Release build!) #will print
CONFIG(debug, debug|release):message(Debug build!) #no print

因为发布被认为是活动设置(用于功能解析),所以它将用于生成构建文件。在常见的情况下,不需要第二个参数,但对于特定的相互排斥测试非常有价值。

contains(variablename, value)

如果变量 variablename 包含值 value,则成功;否则,失败。可以为参数 value 指定正则表达式。

您可以使用作用域检查此函数的返回值。

例如

contains( drivers, network ) {
    # drivers contains 'network'
    message( "Configuring for network build..." )
    HEADERS += network.h
    SOURCES += network.cpp
}

只有在 drivers 变量包含值 network 时,作用域中的内容才会处理。如果这种情况发生,则相应的文件将被添加到 SOURCESHEADERS 变量。

count(variablename, number)

如果变量 variablename 包含指定数量的 number 值,则成功;否则失败。

此函数用于确保仅在变量包含正确数量的值时才处理作用域内部的声明。例如

options = $$find(CONFIG, "debug") $$find(CONFIG, "release")
count(options, 2) {
    message(Both release and debug specified.)
}

debug(level, message)

检查 qmake 是否在指定的调试级别下运行。如果是,则返回 true 并打印调试信息。

defined(name[, type])

测试是否定义了函数或变量 name。如果省略 type,则检查所有函数。要仅检查变量或特定类型的函数,请指定 type。它可以是以下值

  • test 仅检查测试函数
  • replace 仅检查替换函数
  • var 只检查变量

equals(variablename, value)

测试 variablename 是否等于字符串 value.

例如

TARGET = helloworld
equals(TARGET, "helloworld") {
    message("The target assignment was successful.")
}

error(string)

此函数永远不返回值。qmake 将 string 显示为错误信息并退出。此函数仅应用于不可恢复的错误。

例如

error(An error has occurred in the configuration process.)

eval(string)

使用 qmake 语法规则评估字符串的内容并返回 true。可以在字符串中使用定义和赋值来修改现有变量的值或创建新的定义。

例如

eval(TARGET = myapp) {
    message($$TARGET)
}

注意:可以使用引号来界定字符串,如果不需要返回值,可以丢弃返回值。

exists(filename)

测试是否存在具有指定 filename 的文件。如果文件存在,函数成功;否则失败。

filename 参数可能包含通配符。在这种情况下,如果任何文件匹配,则该函数成功。

例如

exists( $(QTDIR)/lib/libqt-mt* ) {
      message( "Configuring for multi-threaded Qt..." )
      CONFIG += thread
}

注意:无论所使用的是哪种平台,“/” 应用作目录分隔符。

export(variablename)

variablename 的当前值从函数的局部上下文导出到全局上下文。

for(iterate, list)

启动一个循环,遍历 list 中的所有值,轮流将 iterate 设置为每个值。作为便利,如果 list 是 1..10,则 iterate 将遍历 1 至 10 的值。

例如

LIST = 1 2 3
for(a, LIST):exists(file.$${a}):message(I see a file.$${a}!)

可以使用 break() 中断循环。next() 语句跳过循环体的其余部分并继续执行下一个迭代。

greaterThan(variablename, value)

测试 variablename 的值是否大于 value。首先,此函数尝试数值比较。如果至少有一个操作数无法转换,此函数将进行字符串比较。

例如

ANSWER = 42
greaterThan(ANSWER, 1) {
    message("The answer might be correct.")
}

无法直接将两个数字作为字符串进行比较。作为 workaround,构造具有非数字前缀的临时值并比较这些值。

例如

VALUE = 123
TMP_VALUE = x$$VALUE
greaterThan(TMP_VALUE, x456): message("Condition may be true.")

另请参阅 lessThan()

if(condition)

评估 condition。它用于组合布尔表达式。

例如

if(linux-g++*|macx-g++*):CONFIG(debug, debug|release) {
    message("We are on Linux or Mac OS, and we are in debug mode.")
}

include(filename)

在包含的地方将文件的 filename 指定的内容包含到当前项目中。如果包含 filename,则该函数成功;否则失败。包含的文件将被立即处理。

您可以通过使用此函数作为作用域的条件来检查文件是否已包含。例如

include( shared.pri )
OPTIONS = standard custom
!include( options.pri ) {
    message( "No custom build options specified" )
OPTIONS -= custom
}

infile(filename, var, val)

如果文件 filename(由 qmake 本身分析时)包含具有值 val 的变量 var,则成功;否则失败。如果您未指定 val,则该函数测试是否已在该文件中分配 var

isActiveConfig

这是 CONFIG 函数的别名。

isEmpty(variablename)

如果变量 variablename 为空,则成功;否则失败。这等价于 count( variablename, 0 )

例如

isEmpty( CONFIG ) {
CONFIG += warn_on debug
}

isEqual

这是对于 equals 函数的别名。

lessThan(variablename, value)

检查变量 variablename 的值是否小于 value。表现为 greaterThan()

例如

ANSWER = 42
lessThan(ANSWER, 1) {
    message("The answer might be wrong.")
}

load(feature)

加载由 feature 指定的特性文件(.prf),除非该特性已被加载。

log(message)

在控制台上打印一条消息。与 message 函数不同,它既不在前面添加文本也不在后面添加换行符。

该函数在 Qt 5.0 中引入。

另见 message()

message(string)

始终成功,并将 string 显示为对用户的通用消息。与 error() 函数不同,此函数允许处理继续。

message( "This is a message" )

上面的行将 "This is a message" 写入控制台。使用引号是可选的,但建议这样做。

注意:默认情况下,为给定项目生成的每个 Makefile 将记录消息。如果您想确保每个项目只出现一次消息,测试在构建期间连同范围一起测试 build_pass 变量,以过滤出消息。例如

!build_pass:message( "This is a message" )

mkpath(dirPath)

创建目录路径 dirPath。此函数是围绕 QDir::mkpath 函数的包装。

该函数在 Qt 5.0 中引入。

requires(condition)

评估 condition。如果条件为假,当构建时,qmake 跳过此项目(及其 SUBDIRS)。

注意:您还可以为此目的使用 REQUIRES 变量。然而,我们建议使用此函数。

system(command)

在次级 shell 中执行给定的 command。如果命令以零退出状态返回,则成功;否则失败。您可以使用范围检查此函数的返回值。

例如

system("ls /bin"): HAS_BIN = TRUE

另见 system() 的替换变体。

touch(filename, reference_filename)

filename 的时戳更新为与 reference_filename 的时戳匹配。

该函数在 Qt 5.0 中引入。

unset(variablename)

从当前范围中删除 variablename

例如

NARF = zort
unset(NARF)
!defined(NARF, var) {
    message("NARF is not defined.")
}

versionAtLeast(variablename, versionNumber)

检查来自 variablename 的版本号是否大于或等于 versionNumber。版本号被认为是非负十进制数字序列,由 '.' 分隔;任何非数值尾部的字符串将被忽略。比较是从左向右部分进行的;如果一个版本是另一个的子序列,则它被认为是较小的。

此函数在 Qt 5.10 中引入。

versionAtMost(variablename, versionNumber)

检查来自 variablename 的版本号是否小于或等于 versionNumber。与 versionAtLeast() 相同。

此函数在 Qt 5.10 中引入。

warning(string)

总是成功,并向用户显示警告消息 string

write_file(filename, [variablename, [mode]])

variablename 的值写入名为 filename 的文件,每个值占一行。如果没有指定 variablename,则创建一个空文件。如果 modeappend 并且文件已存在,则将其附加到文件的末尾而不是替换它。

该函数在 Qt 5.0 中引入。

测试函数库

复杂的测试函数实现在一个 .prf 文件库中。

packagesExist(packages)

使用 PKGCONFIG 机制确定在项目解析时指定的包是否存在。

这可以用于可选地启用或禁用功能。例如

packagesExist(sqlite3 QtNetwork QtDeclarative) {
    DEFINES += USE_FANCY_UI
}

然后在代码中

#ifdef USE_FANCY_UI
    // Use the fancy UI, as we have extra packages available
#endif

prepareRecursiveTarget(target)

通过准备一个遍历所有子目录的目标,促进创建与 install 目标类似的项目级目标。例如

TEMPLATE = subdirs
SUBDIRS = one two three
prepareRecursiveTarget(check)

在它们的 .CONFIG 中指定了 have_no_defaultno_<target>_target 的子目录被排除在这个目标之外

two.CONFIG += no_check_target

您必须手动将准备好的目标添加到 QMAKE_EXTRA_TARGETS

QMAKE_EXTRA_TARGETS += check

为了使目标全局,上面的代码需要包含在所有子目录子项目中。此外,为了使这些目标发挥作用,非子目录子项目需要包含相应的代码。最简单的方法是创建一个自定义功能文件。例如

# <project root>/features/mycheck.prf
equals(TEMPLATE, subdirs) {
    prepareRecursiveTarget(check)
} else {
    check.commands = echo hello user
}
QMAKE_EXTRA_TARGETS += check

功能文件需要注入到每个子项目中,例如通过 .qmake.conf

# <project root>/.qmake.conf
CONFIG += mycheck

该函数在 Qt 5.0 中引入。

qtCompileTest(test)

构建测试项目。如果测试通过,返回 true 并将 config_<test> 添加到 CONFIG 变量中。否则,返回 false。

为了使此函数可用,需要加载相应的功能文件

# <project root>/project.pro
load(configure)

这还将变量 QMAKE_CONFIG_TESTS_DIR 设置为项目父目录的 config.tests 子目录。加载功能文件后,可以覆盖此值。

在测试目录中,必须为每个测试有一个子目录,该子目录包含一个简单的 qmake 项目。下面的代码段展示了项目的 .pro 文件

# <project root>/config.tests/test/test.pro
SOURCES = main.cpp
LIBS += -ltheFeature
# Note that the test project is built without Qt by default.

下面的代码段展示了项目的主要 .cpp 文件

// <project root>/config.tests/test/main.cpp
#include <TheFeature/MainHeader.h>
int main() { return featureFunction(); }

下面的代码段展示了测试的调用

# <project root>/project.pro
qtCompileTest(test)

如果测试项目成功构建,则测试通过。

测试结果会自动缓存,这也使它们对所有子项目可用。因此,建议在顶层项目文件中运行所有配置测试。

为了抑制缓存结果的重复使用,将 CONFIG+=recheck 传递给 qmake。

参见 load()

该函数在 Qt 5.0 中引入。

qtHaveModule(name)

检查由 name 指定的 Qt 模块是否存在。有关可能的值列表,请参阅 QT

此函数自 Qt 5.0.1 以来引入。

© 2024 The Qt Company Ltd. 本文档中包含的文档贡献均为各自所有者的版权。提供的文档根据免费软件基金会发布的GNU自由文档许可协议第1.3版进行许可。Qt及其相关标志是芬兰及/或其他国家的The Qt Company Ltd的商标。所有其他商标均为各自所有者的财产。