Язык qmake
Многие файлы проектов qmake просто описывают исходные файлы и заголовочные файлы, используемые проектом, с помощью списка name = value и name += value определений. qmake также предоставляет другие операторы, функции и области, которые могут использоваться для обработки информации, предоставляемой в объявлениях переменных. Эти расширенные возможности позволяют генерировать Makefiles для нескольких платформ из одного файла проекта.
Операторы
Во многих файлах проекта операторы присваивания (=) и добавления (+=) могут использоваться для включения всей информации о проекте. Типичный шаблон использования заключается в присваивании списка значений переменной и добавлении других значений в зависимости от результата различных проверок. Поскольку qmake определяет некоторые переменные с помощью значений по умолчанию, иногда необходимо использовать оператор удаления (-=) для фильтрации значений, которые не требуются. В следующих разделах описано, как использовать операторы для управления содержимым переменных.
Присваивание значений
Оператор = присваивает значение переменной:
TARGET = myapp
Вышеприведенная строка устанавливает переменную TARGET в значение myapp. Это перезапишет любые ранее заданные значения для TARGET на myapp.
Добавление значений
Оператор += добавляет новое значение в список значений переменной:
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 считывается сразу при обработке файла проекта, но $(PWD) присваивается DESTDIR в сгенерированном Makefile. Это делает процесс сборки более гибким, пока переменная среды установлена правильно при обработке 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
} Приведенный выше код добавит файл paintwidget_win.cpp к списку исходных файлов, перечисленных в сгенерированном Makefile, при построении для платформы Windows. При построении для других платформ определение будет проигнорировано.
Условия, используемые в данной области, также могут быть инвертированы, чтобы предоставить альтернативный набор объявлений, которые будут обработаны только в том случае, если исходное условие ложно. Например, для обработки чего-либо при построении для всех платформ кроме 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
Вышеприведенная строка добавляет USE_MY_STUFF к переменной DEFINES только при построении для платформы Windows. В общем случае оператор : ведет себя как логический оператор И, объединяя несколько условий и требуя, чтобы все они были истинными.
Также есть оператор | для поведения как логического оператора ИЛИ, объединяющего несколько условий и требующего истинности только одного из них.
win32|macx {
HEADERS += debugging.h
} Вы также можете предоставить альтернативные объявления тем, которые находятся в области, используя область 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, это предоставляет удобный способ настройки файлов проекта и тонкой настройки сгенерированных Makefiles.
Значения области платформы
В дополнение к значениям win32, macx, и unix, используемым во многих условиях области, различные другие встроенные значения, специфичные для платформы и компилятора, могут быть проверены с помощью областей. Они основаны на спецификациях платформы, предоставленных в каталоге mkspecs Qt. Например, следующие строки из файла проекта показывают используемую спецификацию и проверку спецификации linux-g++:
message($$QMAKESPEC)
linux-g++ {
message(Linux)
} Вы можете проверить любые другие комбинации платформ и компиляторов, пока существует спецификация для них в каталоге mkspecs.
Переменные
Многие переменные, используемые в файлах проекта, являются специальными переменными, которые qmake использует при генерировании Makefiles, такими как 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)
}
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.13/qmake-language.html