Тестовые функции
Тестовые функции возвращают булево значение, которое можно проверить в условных частях областей. Тестовые функции можно разделить на встроенные функции и функции библиотек.
См. также Функции замены.
Встроенные тестовые функции
Базовые тестовые функции реализованы как встроенные функции.
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
Поскольку релиз считается активным значением (для анализа функций) он будет использоваться CONFIG для генерации файла сборки. В общем случае второй параметр не нужен, но для специфических взаимно исключающих проверок он очень полезен.
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 из локального контекста функции в глобальный контекст.
files(pattern[, recursive=false])
Расширяет указанный шаблон подстановочных знаков и возвращает список имён файлов. Если recursive имеет значение true, эта функция входит в подкаталоги.
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 в дочерней оболочке. Успешно выполняется, если команда возвращает нулевой код выхода; в противном случае завершается неудачей. Можно проверить возвращаемое значение этой функции, используя область.
Например:
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 родительского каталога проекта. После загрузки файла функции эту переменную можно переопределить.
Внутри каталога тестов должен быть один подкаталог на каждый тест, содержащий простой проект 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/archives/qt-5.6/qmake-test-function-reference.html