Функции тестирования
Функции тестирования возвращают булево значение, которое можно проверить в условных частях областей. Функции тестирования можно разделить на встроенные функции и функции библиотек.
См. также Функции замещения.
Встроенные функции тестирования
Базовые функции тестирования реализованы как встроенные функции.
cache(variablename, [set|add|sub] [transient] [super|stash], [source variablename])
Это внутренняя функция, которой вам, как правило, не нужно пользоваться.
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. В этом случае соответствующие файлы добавляются в переменные SOURCES и HEADERS.
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 именем. Если файл существует, функция успешно выполняется; в противном случае она завершается неудачно. Если для имени файла указано регулярное выражение, эта функция успешно выполняется, если какой-либо файл соответствует указанному регулярному выражению.
Например:
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}!) greaterThan(variablename, value)
Проверяет, что значение variablename больше, чем value. Сначала эта функция пытается выполнить численное сравнение. Если хотя бы один из операндов не может быть преобразован, эта функция выполняет строковое сравнение.
Например:
ANSWER = 42
greaterThan(ANSWER, 1) {
message("The answer might be correct.")
} Невозможно напрямую сравнивать два числа как строки. В качестве обходного пути создайте временные значения с нечисловым префиксом и сравните их.
Например:
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) содержит переменную var со значением val; в противном случае завершается неудачно. Если вы не указываете 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)
Загружает файл функции (.prf) указанный feature, если функция ещё не была загружена.
log(message)
Выводит сообщение в консоль. В отличие от функции message, ни текст не предваряется, ни перевод строки не добавляется.
См. также message().
message(string)
Всегда успешно выполняется и отображает string как общее сообщение пользователю. В отличие от функции error(), эта функция позволяет продолжить обработку.
message( "This is a message" )
Вышеуказанная строка выводит "Это сообщение" в консоль. Использование кавычек необязательно, но рекомендуется.
Примечание: По умолчанию сообщения выводятся для каждого файла Makefile, созданного qmake для данного проекта. Если вы хотите убедиться, что сообщения отображаются только один раз для каждого проекта, проверьте переменную build_pass в сочетании с областью для фильтрации сообщений во время сборки. Например:
!build_pass:message( "This is a message" )
mkpath(dirPath)
Создаёт путь к каталогу dirPath. Эта функция является обёрткой вокруг функции QDir::makepath.
requires(condition)
Вычисляет condition. Если условие ложно, qmake пропускает этот проект (и его SUBDIRS) при сборке.
Примечание: Вы также можете использовать переменную REQUIRES для этой цели. Однако мы рекомендуем использовать эту функцию вместо неё.
system(command)
Выполняет заданную command команду в дочерней оболочке. Успешно выполняется, если команда возвращает код выхода 0; в противном случае завершается неудачно. Можно проверить возвращаемое значение этой функции с помощью области.
Например:
system("ls /bin"): HAS_BIN = TRUE См. также вариант замещения system().
touch(filename, reference_filename)
Обновляет отметку времени filename для соответствия отметке времени reference_filename.
unset(variablename)
Удаляет variablename из текущего контекста.
Например:
NARF = zort
unset(NARF)
!defined(NARF, var) {
message("NARF is not defined.")
} warning(string)
Всегда успешно выполняется и отображает string как сообщение об ошибке пользователю.
write_file(filename, [variablename, [mode]])
Записывает значения variablename в файл с именем filename, каждое значение в новой строке. Если variablename не указано, создаёт пустой файл. Если mode равно append, и файл уже существует, добавляет к нему вместо замены.
Библиотека функций тестирования
Сложные функции тестирования реализованы в библиотеке файлов .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)
Подкаталоги с have_no_default или no_<target>_target в их .CONFIG исключаются из этой цели:
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
qtCompileTest(test)
Строит тестовый проект. Если тест пройден, возвращается true и config_<test> добавляется в переменную CONFIG. В противном случае возвращается false.
Чтобы сделать эту функцию доступной, необходимо загрузить соответствующий файл функции:
# <project root>/project.pro load(configure)
Это также устанавливает переменную QMAKE_CONFIG_TESTS_DIR в подкаталог config.tests родительского каталога проекта. Можно переопределить это значение после загрузки файла функции.
Внутри каталога 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().
qtHaveModule(name)
Проверяет, присутствует ли модуль Qt, указанный name. Список возможных значений см. в QT.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.9/qmake-test-function-reference.html