Lila25mila
Lila25mila4 марта 2019 г. 4:08

Недокументированный QMake

Вступление

Qmake - это очень мощная система "meta-make", которую можно использовать для генерации make-файлов для различных компиляторов и платформ из одного и того же файла проекта qmake (.pro). Документация для qmake значительно улучшилась с Qt3, но все еще отсутствует некоторая информация. В этой статье все расскажем на примерах.


Обратите внимание, что информация была написана для Qt4, но некоторые из них могут работать в Qt3. Кстати, должно работать в Qt5 или же рассмотреть для удаления.

Недокументированные переменные

Простейший вид контроля, который вы можете получить над сгенерированным make-файлом, - это использование встроенных переменных, предоставляемых qmake. Конечно, проблема в том, что многие из этих переменных не перечислены в документации по qmake. Но у вас есть удобный список их всех прямо здесь (наряду с богатым источником трюков и хаков, написанных Trolltech (в настоящее время Qt Company - прим. ред), тщательно добытые для вас). В вашем каталоге установки qmake есть подкаталог с именем "mkspecs". Он содержит определения для всех комбинаций платформы / компилятора, которые поддерживает qmake (обратите внимание, что не все они «формально» поддерживаются!) В разных точках есть каталоги с именем «features», там вы найдете код qmake для многих вещей, которые вы можете включить с помощью переменной CONFIG.

Так что, если вы пытаетесь выяснить что-то вроде: «Как мне изменить имя компилятора, который используется в make-файле?» или "Как я могу изменить способ вызова файла-копии для 'make install'?" и тому подобное, в каталоге mkspecs вы должны искать имя переменной, которую нужно изменить.

Вот несколько особенно полезных (начиная с v4.3.4), обнаруженных при исследовании источника qmake:

  • _ DATE_ - текущая дата и время. (V4.3.4)
  • _ FILE_ - текущее имя файла, которое анализирует qmake. (V4.3.4)
  • _ LINE_ - текущий номер строки, анализируемый qmake. (V4.3.4)
  • _ QMAKE_CACHE_ - путь к любому используемому файлу .qmake.cache. (V4.3.4)
  • DIR_SEPARATOR или QMAKE_DIR_SEP - символ прямой или обратной косой черты, в зависимости от платформы хоста.
  • IN_PWD - базовый каталог исходного дерева. (V4.3.4)
  • QMAKE_NOFORCE - опустить использование цели "FORCE".
  • QMAKE_utility - команда для утилиты, которая будет назначена макросу с именем утилита в сгенерированных файлах Makefile. Имена макросов утилит используются соответствующим образом в различных стандартных целях. Значение этих переменных можно изменить, чтобы указать различные служебные команды, а переменные - в форме $$ variable_name или $ (macro_name) - можно использовать при определении команд для QMAKE_EXTRA_TARGETS. Названия утилит:
    QMAKE_CHK_DIR_EXISTS
    • QMAKE_COPY
    • QMAKE_COPY_DIR
    • QMAKE_COPY_FILE
    • QMAKE_DEL_DIR
    • QMAKE_DEL_FILE
    • QMAKE_INSTALL_DIR
    • QMAKE_INSTALL_FILE
    • QMAKE_INSTALL_PROGRAM
    • QMAKE_LINK (используется для связывания исполняемых файлов)
    • QMAKE_LINK_SHLIB
    • QMAKE_MKDIR
    • QMAKE_MOVE
    • QMAKE_QMAKE
    • QMAKE_STRIP
    • QMAKE_SYMBOLIC_LINK (это назначено макросу SYMLINK)
  • QMAKE_ARGS - параметры, используемые для вызова qmake.
  • QMAKE_PROJECT_DEPTH - при использовании большого количества * .pro (и вложенных папок) в основную * .pro может быть удобно установить значение больше 4 для этой переменной, это представляет количество подпапок, на которые qmake ссылается в относительные пути (в makefile.cpp задана глубина = 4). Это особенно полезно при использовании Windows (nmake / jom) с пробелами в корневом пути проекта.
Пользовательские инструменты

В документации по qmake в Qt4 кратко упоминается о возможности пользовательских «компиляторов», но для описания, к сожалению, не так много.

Есть несколько специальных псевдопеременных, которые вы можете использовать внутри пользовательских компиляторов. Я говорю «псевдопеременные» по двум причинам: во-первых, они используют только один знак доллара; и во-вторых, они оцениваются позже, чем все, которые вы хотели бы использовать. По этой причине такие функции, как $$ replace (...) и такие операторы, как ~ =, не будут выполнять то, что должны, - они будут действовать так, как будто вы передаете им пустую переменную.

Надеюсь, Trolltech (Qt Company) уже предоставили вам то, что вам нужно!

  • QMAKE_FILE_IN - это входное имя файла (ов), с указанием пути, если это предусмотрено, что компилятор обрабатывает,
  • QMAKE_FILE_OUT - содержимое переменной "compiler.output" для текущего значения $ {QMAKE_FILE_IN}, то есть текущего выходного файла,
  • QMAKE_FILE_IN_BASE (или QMAKE_FILE_BASE) - текущее имя входного файла без расширения,
  • QMAKE_FILE_IN_PATH (или QMAKE_FILE_PATH) - просто путь к текущему входному файлу,
  • QMAKE_FILE_OUT_BASE - текущее имя выходного файла без расширения,
  • QMAKE_FILE_OUT_PATH - просто путь к текущему выходному файлу,
  • QMAKE_FILE_EXT - расширение файла входного файла, включая точку.

Самое простое определение пользовательского инструмента обычно выглядит примерно так:

idl_c.output = ${QMAKE_FILE_IN}.c
idl_c.input = IDL
idl_c.commands = $${QMAKE_IDL} ${QMAKE_FILE_IN} $${IDLFLAGS} \
                 /h ${QMAKE_FILE_IN}.h /iid ${QMAKE_FILE_IN}.c
idl_c.variable_out = SOURCES
idl_c.name = MIDL

QMAKE_EXTRA_COMPILERS += idl_c

В этом примере выполняется запуск компилятора Microsoft MIDL для файла .ODL и создание пары .c и .h с информацией о хосте COM.

Чтобы определить пользовательский инструмент, вы должны сначала выбрать имя для составной переменной (аналог структуры) для определения. В приведенном выше примере я выбрал «idl.c».

Есть несколько свойств, которые могут быть включены в определение пользовательского инструмента:

  • .commands - указывает команду, которая должна быть запущена на каждом из исходных файлов. Обратите внимание, что вам нужно будет использовать двойной $ для любых обычных переменных qmake, которые вы хотите раскрыть (это не включает QMAKE_FILE_IN и друзей),
  • .clean_commands - указывает команды, которые должны быть выполнены для очистки сгенерированных дополнительно выходных файлов,
  • .clean - устанавливает файлы, которые должны быть удалены с помощью make clean,
  • .depend_command - указывает команду, которая должна быть выполнена для генерации информации о зависимостях,
  • .dependency_type - использовать один из стандартных алгоритмов обхода зависимостей, встроенных в qmake. Начиная с версии 4.3.3, допустимыми являются TYPE_C и TYPE_UI.
  • .depends - устанавливает файлы, которые являются зависимостями для этого шага. Вывод .depend_command, если он используется, должен быть указан здесь. Это также можно использовать для проверки, изменился ли сам исполняемый файл компилятора,
  • .input - устанавливает переменную qmake, которая содержит список файлов, на которых должен работать этот компилятор,
  • .name - это, кажется, просто внутреннее имя, используемое в qmake; просто убедитесь, что вы используете разные значения для каждого пользовательского компилятора,
  • .output - устанавливает имя выходного файла, который сгенерирует шаг. Переменная $ {QMAKE_FILE_IN} может использоваться, чтобы основать это на имени входного файла. По умолчанию это GENERATED_SOURCES,
  • .output_function - называет функцию, определенную с помощью defineReplace, которая будет использоваться для определения имени выходного файла. Переменная $ {QMAKE_FILE_IN} будет передана этой функции, а ее возвращаемое значение будет использовано в качестве имени выходного файла. Убедитесь, что функция существует и действительно что-то возвращает, иначе вы получите вводящие в заблуждение сообщения об ошибках.
  • .variable_out - сгенерированные целевые файлы, выведенные на этапе сборки, будут добавлены в эту переменную. В этом случае шаг генерирует файл .c, поэтому файлы должны быть добавлены в SOURCES.
  • .variables - точно не выявлено, что делает эта функция.
  • .verify_function - подключен к флагу function_verify в .CONFIG - точно не выявлено, что делает эта функция.

Существует также свойство .CONFIG, которое само по себе имеет несколько специальных флагов, которые вы можете установить, используя синтаксис, идентичный основной переменной CONFIG:

  • combine (объединение) - вызвать компилятор со списком всех файлов в исходной переменной, а не один раз для каждого файла,
  • xplicit_dependencies - комментарий в источнике: "compiler.CONFIG + =xplicit_dependencies означает, что ТОЛЬКО compiler.depends может вызывать зависимости Makefile",
  • function_verify - см. также .verify_function выше,
  • ignore_no_exist - игнорировать (не обрабатывать) файлы в списке ввода, которые не существуют. Если эта функция не установлена, то выдается предупреждение, что входной файл все еще обрабатывается,
  • moc_verify - скорее всего гарантирует, что файл должен быть пропущен через препроцессор moc перед добавлением его в качестве цели moc.
  • no_dependencies - не делать генерацию зависимостей от файлов в исходной переменной,
  • no_link - файлы, которые создаются, не должны добавляться в OBJECTS - т.е. они не являются скомпилированным кодом, который должен быть связан,
  • target_predeps - скорее всего гарантирует, что пользовательский компилятор будет запущен первым в проекте,
  • verify (проверка) - не выявлено, что делает эта функция. Пользовательский компилятор никогда не вызывается, если он включен.

После того, как вы определили составную переменную для инструмента, вы должны затем добавить эту составную переменную в QMAKE_EXTRA_COMPILERS. Это дает понять qmake, что он должен просмотреть указанные вами файлы и запустить на них этот инструмент.

Примеры

Вот еще один, причем необычный, пример:

CFLAGS_FILE = .   # Need to give some bogus input
compile_inp.output = compile.inp
compile_inp.input = CFLAGS_FILE
compile_inp.commands = echo >\$(OBJECTS_DIR)compile.inp \$(CXXFLAGS)
compile_inp.name = compile.inp
compile_inp.variable_out = JUNK
compile_inp.CONFIG = no_link
QMAKE_EXTRA_COMPILERS += compile_inp

Этот инструмент просто выводит содержимое переменной CXXFLAGS в файл с именем «compile.inp». Поскольку этот инструмент предназначен для создания файла с фиксированным именем, переменная, переданная в .input, содержит только «.» (текущий каталог), который всегда будет существовать (но нигде в правиле не используется). В этом правиле используется конструкция \ $ (foo), которая выводит расширение переменной формата GNU Make или NMAKE, в основном задерживая расширение переменной до тех пор, пока make или NMAKE не будут вызваны в сгенерированном make-файле.

Способ компиляции разных файлов с разными CXXFLAGS (на основе qt / src / gui / painting / painting.pri):

SOURCES_NOOPTIMIZE = somefile.cpp
nooptimize.name = nooptimize
nooptimize.input = SOURCES_NOOPTIMIZE
nooptimize.dependency_type = TYPE_C
nooptimize.variable_out = OBJECTS
nooptimize.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${first(QMAKE_EXT_OBJ)}
nooptimize.commands = $${QMAKE_CXX} $(CXXFLAGS) -O0 $(INCPATH) -c ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} # Note the -O0
QMAKE_EXTRA_COMPILERS += nooptimize

Конечно, вы можете указать различные пользовательские флаги вместо -O0, который используется для отключения оптимизации.

И, наконец, пример того, как вызывать пакетный файл с именем «PreBuildEvent.bat» каждый раз, когда вы компилируете свой код (протестировано в VisualStudio на основе qt-creator-enterprise-src-3.1.0 \ share \ qtcreator \ static.pro):

PRE_BUILD_FILE = ../Applications/PreBuildEvents.bat
# должен использовать переменную в качестве входных данных
PHONY_DEPS = .
PreBuildEvent.input = PHONY_DEPS
# использовать несуществующий файл для выполнения каждый раз
PreBuildEvent.output = phony.txt
# tсистемный вызов командного файла
PreBuildEvent.commands = call $$PRE_BUILD_FILE
# какое-то имя, которое отображается во время исполнения
PreBuildEvent.name = running Pre-Build steps...
# «no_link» сообщает qmake, что нам не нужно добавлять выходные данные в объектные файлы для компоновки, а «no_clean» означает, что для них нет чистого шага.
# «target_predeps» сообщает qmake, что выходные данные этого должны существовать, прежде чем мы сможем выполнить остальную часть нашей компиляции.
PreBuildEvent.CONFIG += no_link no_clean target_predeps
# Добавьте компилятор в список «дополнительных компиляторов».
QMAKE_EXTRA_COMPILERS += PreBuildEvent
Особенности конфигурации

Есть несколько «переключателей», которые могут быть добавлены к переменной CONFIG, которые влияют на различное поведение qmake (обратите внимание, что это не включает функции CONFIG специфичные для пользовательских инструментов или установщиков):

  • app_bundle - превращает цель в пакет, а не в отдельный исполняемый файл (только для Mac).
  • compile_libtool - использует «libtool» для компиляции, компоновки и т. д. вместо обычного компилятора (только * nix).
  • echo_depend_creation - выводит сообщения на экран во время создания зависимости (только * nix).
  • generate_pbxbuild_makefile - создает оболочку make-файла для проекта PowerBuilder (только для Mac).
  • GNUmake - позволяет инструменту GNU make определять зависимости (только * nix).
  • lib_bundle - превращает цель в пакет вместо автономной библиотеки (только для Mac).
  • no_autoqmake - запрещает выводимому make-файлу вызывать qmake, если файл .pro изменился.
  • no_empty_targets - гарантирует, что проекты, основанные на SUBDIR, не имеют целей, которые ничего не делают (вместо этого они заполняются "cd.").
  • no_fix_and_continue - отключает функцию GCC «исправить и продолжить» (только для Mac).
  • no_include_pwd - пропускает текущий каталог из окончательного INCLUDEPATH.
  • no_pb_munge_key - предотвращает qmake от кеширования MD5 ключа проекта (только для Mac).
  • no_pbx_xcode - отключает поддержку XCode (только для Mac).
  • no_smart_library_merge, no_lflags_merge - предотвращает удаление дублирующихся записей в флагах компоновщика (только * nix).
  • no_zero_link - отключает функцию GCC «нулевая ссылка» (только для Mac).
  • object_parallel_to_source - воссоздает исходное дерево папок для объектных файлов (заменяет object_with_source).
  • object_with_source - выводит каждый объектный файл в тот же каталог, в котором находится его исходный файл (в последних версиях он заменяется на object_parallel_to_source).
  • rpath_libdirs - добавляет QMAKE_LFLAGS_RPATH к флагам ссылки (только * nix).
  • ordered - гарантирует, что проекты построены в указанном порядке.
  • static_and_shared - генерирует make-файлы для статических и общих сборок. Обратите внимание, что shared_and_static игнорируется. Создается основной make-файл с именем $$ MAKEFILE (Makefile по умолчанию) и вспомогательные make-файлы с именами $$ MAKEFILE.StaticRelease и $$ MAKEFILE.SharedRelease, если CONFIG содержит release (по умолчанию для платформ unix), или $$ MAKEFILE.StaticDebug и $$ MAKEFILE.SharedDebug, если CONFIG содержит отладку (по умолчанию для win32), или оба, если CONFIG содержит debug_and_release (всего пять make-файлов). Первичный make-файл будет содержать набор целей {static, shared} {debug, release} [- xxx], соответствующих вторичным make-файлам, которые можно использовать для вызова соответствующих правил make-файла. Однако у первоочередных целей по умолчанию (а также при установке и удалении) будет только одно предварительное условие (по умолчанию создается только один файл библиотеки) в зависимости от активного CONFIG: static-release, static-debug, shared-release или shared -debug; добавить статические или общие в CONFIG, в дополнение к static_and_shared, и отпустить или отладить в дополнение к debug_and_release, чтобы qmake выбрал соответствующую цель для первого обязательного условия цели.

Также есть несколько значений, которые qmake будет динамически устанавливать в CONFIG, когда он записывает make-файл (а не при записи файлов проекта XCode), кроме основного Make-файла - то есть дополнительных вспомогательных make-файлов, когда установлены debug_and_release и/или static_and_shared:

  • build_pass - пишется вспомогательный make-файл (build_pass не устанавливается, когда пишется основной Make-файл).
  • Debug и DebugBuild - когда установлен debug_and_release и расширение имени файла makefile содержит «Debug».
  • Release и ReleaseBuild - когда установлен debug_and_release и расширение имени файла makefile содержит «Release».
  • Static и StaticBuild - когда установлен static_and_shared и расширение имени файла makefile содержит «Static».
  • Shared и SharedBuild - когда установлен static_and_shared и расширение имени файла makefile содержит «Shared».

Когда используются debug_and_release и static_and_shared, все четыре комбинации Debug / Release и Static / Shared будут добавлены в дополнение к build_pass.

Путем проверки этих значений в области build_pass можно настроить соответствующее содержимое make-файла. Например, если исходный код содержит отладочные выходные разделы, обусловленные определением макроса препроцессора DEBUG_SECTION, следующий синтаксис qmake позволяет определить значение макроса во время компиляции:

build_pass: DebugBuild {
    # Provide compile-time DEBUG_SECTION.
    DEFINES += DEBUG_SECTION=$(DEBUG_SECTION)
    # Provide console output on MS/Windows.
    win32: CONFIG += console
    }

После запуска qmake с файлом .pro, содержащим вышеизложенное, разработчик может создать отладочную версию кода следующим образом:

make DEBUG_SECTION=ENABLED_SECTION debug

Здесь ENABLED_SECTION - это символ, определенный в исходном коде для вывода раздела отладки, который должен быть включен. Необходимо указать цели shared-debug и / или static-debug, если static_and_shared был установлен в списке CONFIG.

Кроме того, есть несколько значений с неопределенным значением:

  • explicitlib - значение не установлено,
  • no_delete_multiple_files - связанные с пользовательскими целями и "make clean",
  • no_fixpath - изменяет, как qmake изменяет пути к файлам, чтобы они были относительными (хотя точно не понятно как),
  • subdir_first_pro, cd_change_global - имеют отношение к проектам, использующим шаблон SUBDIRS.

Еще одна интересная ценность для тех, кому надоели длинные журналы компиляции:

  • silent - созданный make-файл использует команду "echo" для вывода таких строк, как "compiling x.cpp", "moc x.h", "linking x.exe".

Не используйте временный файл, содержащий флаги командной строки, например, для звонков. компилятор или компоновщик (@C: \ TEMP \ nm1234.tmp), но пишите все непосредственно в командную строку (специфично для nmake). Полезно для воспроизводимых журналов сборки:

  • no_batch -? (Для Win32 NMAKE)

Другая интересная функциональность qmake, по крайней мере, начиная с Qt4, заключается в том, что он имеет (недокументированный) переключатель «config», который изменяет значение переменной CONFIG во время выполнения без изменения содержимого обрабатываемого файла. Это особенно полезно для замены целей сборки. Действительно, qmake не может генерировать другие цели сборки, кроме классических «release», «debug», «clean» и «install». Поскольку переменная CONFIG проверяется при разрешении областей, она позволяет создавать сложную структуру проекта, основанную на целях, которая остается удобочитаемой.

#sample project

TARGET = sample
TEMPLATE = app

SOURCES += main.cpp someclass.cpp
HEADERS += someclass.h

target_one {
    DEFINES += _BUILD_ONE_
    SOURCES += someclass_one.cpp
    HEADERS += someclass_one.h
}

target_two {
    DEFINES += _BUILD_TWO_
    SOURCES += someclass_two.cpp
    HEADERS += someclass_two.h
}

Вышеупомянутый проект будет иметь 4 возможных выхода:

  • простое приложение с реализованным только «someclass»
  • то же самое приложение, но с добавленным someclass_one, генерация make-файла выполняется с помощью следующей команды:
qmake -config target_one
  • то же самое приложение, но с добавлением someclass_two, генерация make-файла выполняется с помощью следующей команды:
qmake -config target_two
  • то же самое приложение, но с добавленными необязательными классами, генерация make-файла выполняется с помощью следующей команды:
qmake -config "target_one target_two"

Этот трюк будет использован Edyuk, чтобы позволить формату * .pro стать таким же мощным, как и известные стандарты, такие как * .cbp, используемый Code :: Blocks, и * .vcproj, используемый MSVC.

Выборочная установка конфигурации

Следующие недокументированные ключи могут быть добавлены в свойство .CONFIG пользовательской цели установки (то есть myInstallTarget.CONFIG). Цель - это пользовательская цель установки, если она была добавлена в список INSTALLS. Следует отметить, что «target» также считается пользовательской целью установки, если его свойство .files было явно определено в файле проекта.

  • no_check_exist - создает цель установки, даже если устанавливаемые файлы не существуют во время запуска qmake.

Поправка: есть две формы, которые qmake может использовать для установки файлов: INSTALL_FILE и INSTALL_DIR. Когда существующий каталог устанавливается и no_check_exist не применяется, используется форма INSTALL_DIR. Однако, если каталог не существует при запуске qmake (например, подкаталог файлов документации, которые будут созданы во время выполнения make) и применяется no_check_exist, используется форма INSTALL_FILE, которая в системах Unix завершится ошибкой во время выполнения make. Чтобы предотвратить это, нельзя применять no_check_exist, и при запуске qmake должен быть создан пустой каталог с заданным именем. Для этого используйте функцию «system» qmake с соответствующей командой (это будет «mkdir -p» в системах Unix; просто mkdir в Windows) и путь к каталогу (путь должен иметь разделители, соответствующие системе хоста).

SUBDIRS проекты

SUBDIRS - это мощный метод разбиения проектов на более мелкие куски. Хотя на самом деле он намного мощнее, чем указано в документации.

Существует три возможных значения в переменной SUBDIRS. Они могут быть каталогами, как указано в руководстве: в этом случае qmake будет искать файл .pro с тем же именем, что и каталог. Это также может быть файл .pro, с или без пути, и в этом случае он будет идти непосредственно к этому файлу. Или наиболее вероятно, это может быть переменная. В этом случае можно настроить поведение с помощью составных переменных, используя следующие ключевые слова:

  • subdir - путь к файлу .pro. Программа будет вести себя так, как будто вы просто указали каталог.
  • file - сам файл .pro. Программа будет вести себя так, как будто вы указали полный путь и имя файла.
  • depends - список других записей SUBDIRS, от которых зависит эта запись.
  • makefile - кажется, это устанавливает имя make-файла, который будет сгенерирован и вызван для этой цели.
  • target - это устанавливает цель в make-файле, который будет вызываться. (Вероятно, наиболее полезно в сочетании с опцией "makefile".)

Например:

TEMPLATE = subdirs
SUBDIRS = sub_lib sub_tests sub_app

sub_lib.subdir = lib
sub_tests.file = tests/proj.pro
sub_tests.depends = sub_lib
sub_app.subdir = app
sub_app.depends = sub_lib

Это позволяет использовать make -j 4 в вашей причудливой четырехъядерной системе с проектом, который состоит из нескольких компонентов, которые зависят друг от друга. Чтобы немного упростить процесс, можно определить следующую тестовую функцию:

# addSubdirs(subdirs,deps): Adds directories to the project that depend on
# other directories
defineTest(addSubdirs) {
    for(subdirs, 1) {
        entries = $$files($$subdirs)
        for(entry, entries) {
            name = $$replace(entry, [/\\\\], _)
            SUBDIRS += $$name
            eval ($${name}.subdir = $$entry)
            for(dep, 2):eval ($${name}.depends += $$replace(dep, [/\\\\], _))
            export ($${name}.subdir)
            export ($${name}.depends)
        }
    }
    export (SUBDIRS)
}

Вы можете использовать его как:

addSubdirs (contrib/*)

addSubdirs (src/lib/kernel, contrib/module1 contrib/module2)
addSubdirs (src/lib/gui, src/lib/kernel contrib/module3 contrib/module4)

addSubdirs (src/tests/kernel, src/lib/kernel)
addSubdirs (src/tests/gui, src/lib/gui)

addSubdirs (src/main, src/lib/gui src/lib/kernel)

addSubdirs (src/modules/*, src/lib/kernel)

проект, который имеет:

  • несколько модулей, которые должны быть скомпилированы в первую очередь;
  • библиотека ядра для вещей, не связанных с графическим интерфейсом, которые зависят от некоторых модулей contrib;
  • библиотека GUI, которая зависит от библиотеки ядра и некоторых других модулей contrib;
  • испытательные стенды для ядра и gui libs;
  • основная программа, использующая библиотеки графического интерфейса и ядра;
  • несколько модулей, которые зависят только от ядра lib;
  • компилируется параллельно, где это возможно.
Недокументированные режимы

Помимо хорошо известных режимов "-project" и "-makefile", qmake поддерживает несколько других ключей, которые могут переводить его в разные режимы.

  • -prl превращает его в "prl generation mode". Не понятно, что это значит, но, безусловно, связано с файлами .prl, которые присутствуют в каталоге $ QTDIR / libs;
  • -set и -query превращает его в «properties mode». Затем qmake может дать вам значения некоторых специфических переменных Qt, которые жестко запрограммированы в нем во время сборки. Кроме того, выбранные пользователем свойства могут быть определены и опрошены. Эти значения могут быть получены приложением Qt через QLibraryInfo, но переключатель qmake позволяет сценариям оболочки знать о них.

Значения встроенных свойств:

  • QMAKE_MKSPECS
  • QMAKE_VERSION
  • QT_INSTALL_BINS
  • QT_INSTALL_CONFIGURATION
  • QT_INSTALL_DATA
  • QT_INSTALL_DEMOS
  • QT_INSTALL_DOCS
  • QT_INSTALL_EXAMPLES
  • QT_INSTALL_HEADERS
  • QT_INSTALL_LIBS
  • QT_INSTALL_PLUGINS
  • QT_INSTALL_PREFIX
  • QT_INSTALL_QML
  • QT_INSTALL_TRANSLATIONS
  • QT_VERSION

Например, если Qt 4.1.3 установлен в /usr/local/Trolltech/Qt-4.1.3 (по умолчанию):

$ qmake -query QT_VERSION
4.1.3

$ qmake -query QT_INSTALL_PREFIX
/usr/local/Trolltech/Qt-4.1.3

Определяемые пользователем свойства являются глобальными для системы - они не относятся к отдельным проектам. Под Win32 они хранятся в реестре по адресу HKEY_CURRENT_USER \ Software \ Trolltech \ QMake \ 2.00a.

Вы также можете получить значения этих переменных, используя $$ [varname] (обратите внимание на использование квадратных скобок).

Недокументированные функции

Есть несколько очень удобных функций, которых нет в документации по Qt4. Некоторые из них не были добавлены до Qt 4.2, так что будьте осторожны.

Функции потока программы

Что касается qmake, то это тестовые функции, принадлежащие своему собственному разделу:

  • break () - действует как оператор C break.
  • debug (level, msg) - выводит сообщение в журнал отладки qmake (включается опцией -d). Параметр «level» указывает количество параметров -d, которые должны быть указаны для отображения этого сообщения.
  • clear (var) - Инициализирует переменную для очистки.
  • export (var) - при написании пользовательской функции объявленные переменные являются локальными для функции. Чтобы сделать переменную доступной для вызывающего контекста, используйте export (var).
  • next () - Действует как оператор C continue.
  • unset (var) - полностью удаляет переменную (она будет действовать так, как если бы она никогда не была установлена).
Замена функции

Эти функции возвращают значение:

  • files (glob) - возвращает список файлов, которые соответствуют указанному шаблону glob.
    На самом деле эта функция задокументирована как тестовая функция.
Недокументированные тонкости

Qmake - действительно мощный инструмент, если вы все еще не уверены в этом, посмотрите: области могут быть вложенными, но также объединяться с помощью логических операторов. Следующие строки эквивалентны:

win32|unix {
    VAR += value
}

win32 {
    VAR += value
}

unix {
    VAR += value
}

Подстановочный знак можно использовать практически везде: области видимости, значения, и т.д.

win32-msvc* {
    # same as win32-msvc|win32-mscv.net
}

TEXTS += *.txt

Определение, используется ли статическая сборка Qt:

qtConfig(static) {
 # this is a static build
}
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Дмитрий
  • 16 марта 2019 г. 9:55

Спасибо за статью.
Давно итересует следующий вопрос:
с помощью переменных
QMAKE_TARGET_COMPANY
QMAKE_TARGET_PRODUCT
QMAKE_TARGET_DESCRIPTION
можно задать свойства компилируемой программы, однако русский язык они не поддерживают.
Можно ли это исправить?

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
e
  • ehot
  • 1 апреля 2024 г. 0:29

C++ - Тест 003. Условия и циклы

  • Результат:78баллов,
  • Очки рейтинга2
B

C++ - Тест 002. Константы

  • Результат:16баллов,
  • Очки рейтинга-10
B

C++ - Тест 001. Первая программа и типы данных

  • Результат:46баллов,
  • Очки рейтинга-6
Последние комментарии
k
kmssr9 февраля 2024 г. 5:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко5 февраля 2024 г. 12:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 декабря 2023 г. 21:30
Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 декабря 2023 г. 19:38
Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 декабря 2023 г. 8:01
Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
a
a_vlasov14 апреля 2024 г. 16:41
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел Дорофеев14 апреля 2024 г. 12:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
Mm
Mind mingles12 апреля 2024 г. 10:42
ASO Service Forum: Enhancing App Visibility and Reach Welcome to the ASO Service Forum, your ultimate destination for insights, discussions, and strategies revolving around App Store Optimization. ASO (App Store Optimization) is paramoun…
f
fastrex4 апреля 2024 г. 14:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
P
Pisych27 февраля 2023 г. 15:04
Как получить в массив значения из связанной модели? Спасибо, разобрался:))

Следите за нами в социальных сетях