Язык 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
} Если вам нужно объединить оба оператора, вы можете использовать функцию 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
} Примечание: Исторически qmake проверял имя mkspec с помощью подстановочных знаков, как показано выше, для проверки платформы. В настоящее время рекомендуется использовать значения, определенные mkspec в переменной QMAKE_PLATFORM.
Вы также можете предоставить альтернативные объявления к тем, которые находятся внутри области видимости, используя область видимости 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-6.2/qmake-language.html