Название «qmake» несколько вводит в заблуждение, т.к. сам qmake ничего не билдит, он только подготавливает сборку под конкретный тулчейн. Идея заключается в том, чтобы на основании одного файла проекта qmake (*.pro) можно было автоматически создать необходимый makefile или его аналог для каждого сочетания платформы и компилятора; дальше проект собирается уже средствами конкретного тулчейна.
Под Windows qmake «из коробки» умеет делать makefile под Visual C++ от 2005 до 2012 и под MinGW (это то, что я пробовал), а также под Cygwin и Intel C++ Compiler (а в эти края я не гулял). Также помимо makefile qmake может создавать родные проекты для Viusal Sudio, но лично я эту фичу никогда не использовал и не знаю, насколько она рабочая; в дальнейшем я рассматриваю только вариант с makefile.
Makefile создается на основании значений ряда переменных, которые явно или неявно определяются в .pro файле. Смысл предопределенных переменных — это тема дальнейших заметок, а пока рассмотрим базовый синтаксис файла проекта qmake, т.е. — работу с переменными.
Синтаксис объявления переменных
Имя переменной — обычный идентификатор, регистр имеет значение. Объявляются переменные неявно, с помощью присваивания значения.
1 2 3 4 |
VAR = value1 value2 # комментарий - от решетки до конца строки VAR = value1 "value with spaces" |
В списке значений можно использовать значения других переменный с помощью оператора $$:
1 2 3 4 5 6 7 8 9 10 |
PREFIX = lib VAR1 = value1 value2 VAR2 = v3 $$VAR1 $${PREFIX}v4 # v3 value1 value2 libv4 # {} нужны в том случае, если имя переменной без них # будет неправильно определяться. # $$PREFIXv4 молча даст пустую строку, т.к. # если переменная не была определена ранее, # ее значение полагается пустым. |
Список значений переменной должен быть в одной строке. Если хочется красоты, то можно заескейпить конец строки на сишный манер:
1 2 3 4 |
VAR = value1 value2 \ value3 |
Аналогичным образом можно заескейпить специальные символы:
1 2 3 |
VAR = \\ \" \[ \] \{ \} \( \) \$ # \ " [ ] { } ( ) $ |
Символ #
заескейпить нельзя. Чтобы указать в значении решетку, нужно использовать предопределенную переменную LITERAL_HASH:
1 2 3 |
VAR = value$${LITERAL_HASH}123 # value#123 |
$
(LITERAL_DOLLAR) и табуляции \t
(LITERAL_WHITESPACE).
Очистить переменную можно несколькими способами:
1 2 3 4 5 6 |
VAR = # присвоить пустое значение clear(VAR) # то же самое unset(VAR) # вообще удаляет пременную, как будто # ее никогда не было. |
Операции с переменными
Кроме простого присваивания qmake понимает также следующие операции:
1 2 3 4 5 6 7 8 |
VAR = v1 v2 v3 # заменяет список: v1 v2 v3 VAR += v3 v4 # добавляет к списку: v1 v2 v3 v3 v4 VAR -= v3 # убирает из списка: v1 v2 v4 VAR *= v4 v5 v5 # добавляет, если нет: v1 v2 v4 v5 VAR += v5 # v1 v2 v4 v5 v5 VAR ~= s/v5/vvv # заменяет по regexp: v1 v2 v4 vvv v5 |
На последнем операторе остановлюсь подробнее. Синтаксис выражения следующий: s/regexp поиска/на что меняется
. Заменяется почему-то только первое найденное значение. Если и есть способ использовать matches (значения из круглых скобок в regexp) в подстановке, то он мне неизвестен. Таким образом, этот оператор имеет практическую пользу только для замены уникальных значений в списке.
Помимо описанных выше операций, qmake поддерживает большой набор встроенных функций для работы с переменными, которые позволяют реализовать, наверное, все что угодно. Эти функции я рассмотрю подробно в одном из дальнейших постов.
«Объектная» нотация
В некоторых фичах qmake используется следующий паттерн, использующий нотацию наподобие обращения к полям объекта:
1 2 3 4 5 6 7 |
obj1.param1 = v1 obj1.param2 = v2 obj2.param1 = v3 obj2.param2 = v3 OBJLIST += obj1 obj2 |
На самом деле никаких «объектов» в qmake нет, просто в имени переменной можно точку использовать.
1 2 3 4 5 6 7 |
# это все - никак не связанные друг с другом переменные s.f1 = v1 s.f2 = v2 s.f2.subfield = zzz s = value |
1 2 3 4 5 6 |
s.f1 = 10 name = s v = $${$${name}.f1} # ошибка, так нельзя eval(v = \$\$$${name}.f1) # а вот так - можно |
v = $$s.f1
), а затем интерпретирует получившийся текст как часть .pro файла (в v запишется 10).
В абзаце «Операции с переменными» для того, чтобы регулярное выражение делало замену рекурсивно можно попробовать написать: VAR ~= s/v5/vvv/g
P.S. у меня сработало как надо.
Спасибо!