По-умолчанию, Mxx_ru в процессе своей работы не отображает информации о своих действиях — работает по принципу черного ящика. В больших проектах или при отладке проектных файлах может быть интересно или полезно знать, какие именно команды запускаются. Если передать интерпретатору Ruby аргумент --mxx-show-cmd, то на стандартный поток вывода будут отображаться названия запускаемых команд и их параметры. Например, при компиляции примера из 3.4 на стр. 22 компилятором GNU C++ под Cygwin, аргумент --mxx-show-cmd приведет к следующей печати:
Для формирования командных строк некоторых инструментов на некоторых платформах требуется создание т.н. response-файлов. Это временные текстовые файлы, которые содержат значения параметров для запускаемого инструмента. В этих случаях Mxx_ru создает временные файлы с уникальными именами, осуществляет запуск необходимых инструментов и затем, после окончания обработки проектного файла, уничтожает созданные временные файлы. Например, компиляция примера из 3.4 на стр. 22 компилятром Visual C++ приводит к запуску следующих команд:
Здесь файлы с именами tmpmxx_ru.[0-9]+.[0-9]+ — это временные файлы, созданные Mxx_ru.
Иногда, при отладке проектов или новых toolset бывает полезно сохранить временные файлы для последующего анализа. Достигается это указанием интерпретатору Ruby аргумента --mxx-keep-tmps:
Аргумент --mxx-show-tmps является аналогом аргумента --mxx-show-cmd, но для временных response-файлов. Если этот аргумент передан интрепритатору Ruby, то Mxx_ru после формирования очередного временного файла отображает на стандартный поток вывода содержимое этого файла. Так, компиляция примера из 3.4 на стр. 22 компилятором Visual C++ с аргументами --mxx-show-cmd, --mxx-show-tmps приведет к следующему результату:
Если интерпретатору Ruby передан аргумент --mxx-dry-run, то Mxx_ru выполняет имитацию построения проекта. Т.е. обрабатываются все проекты, формируются командные строки для запуска всех инструментов, включая создание response-файлов, но сами инструменты не запускаются.
Этот аргумент удобно использовать для отладки проектных файлов и новых toolset в сочетании с аргументами --mxx-show-cmd, --mxx-show-tmps, --mxx-keep-tmps.
Язык Ruby является объектно-ориентированным языком, в котором широко используется механизм исключений. Например, когда интерпретатор Ruby встречает в скрипте синтаксическую ошибку, то генерируется исключение. Сам Mxx_ru так же использует исключения для информирования об обнаруженных им ошибках.
Особенностью использования Mxx_ru является то, что в выбранной архитектуре проектных файлов не все иключения можно перехватить средствами Mxx_ru. В результате, например, из-за синтаксической ошибке в проектном файле, интерпретатор может выдать подробный stack-trace:
Такая подробность может первое время шокировать. Но со временем это перестает быть проблемой, во-первых, потому, что с опытом уменьшается количество синтаксических ошибок и, во-вторых, это позволяет легко диагностировать проблемы в самом Mxx_ru.
Если же Mxx_ru в состоянии перехватить исключение, то Mxx_ru делает это и отображает на стандартный поток ошибок только описание перехваченного исключения. Например:
Основная идея Mxx_ru состоит в том, чтобы упростить наиболее типовые действия при компиляции проектов. Поэтому Mxx_ru предоставляет набор готовых шаблонов, в которые необходимо лишь подставить собственные данные. Однако, бывают случаи когда возможностей шаблонов не хватает. Например, в текущей версии Mxx_ru нет поддержки средств локализации Qt-приложений. Если в Qt-проекте потребуется, скажем, сгенерировать .qm-файл из готового .ts-файла, то окажется, что в существующих шаблонах Mxx_ru нет инструмента для выполнения именно этого действия.
Хорошим выходом из этой ситуации стало бы создание для Mxx_ru необходимой возможности с тем, чтобы ее можно было использовать затем и в других Qt-проектах. Но очевидно, что не каждый использующий Mxx_ru разоработчик захочет дорабатывать Mxx_ru. В таких случаях остается только воспользоваться классом генератора Mxx_ru::Makestyle_generator, который позволяет подключить в проект произвольное make-правило:
В данном примере создается make-правило по генерации файла etc/wms_ctl_1.ru.qm (цель make-правила) из файла etc/wms_ctl_1.ru.ts (зависимость для цели make-правила) при помощи команды lrelease из состава Qt. Когда запускается построение проекта, содержащего данное правило, генератор Mxx_ru::Makestyle_generator проверяет существование файла .qm. Если его нет, или он изменялся раньше, чем файл .ts, то запускается lrelease. Т.е. выполняется логика обычного make-правила в обычном make. При выполнении операции clean (очистки проекта) файл etc/wms_ctl_1.ru.qm уничтожается.
Однако, в отличии от обычных make-файлов, заданные с помощью генератора Mxx_ru::Makestyle_generator правила выполняются до основных действий проектного файла. И, кроме того, выполняются строго в том порядке, в котором были созданы генераторы. Поэтому следующий пример:
не будет работать при отсутствии файла b, т.к. первый генератор просто не будет знать, что файл b строится по правилам второго генератора. И это именно то поведение, которое задумывалось при реализации Mxx_ru::Makestyle_generator — Mxx_ru не является традиционным make, и все сложные операции должны выполняться посредством специально созданных для этих операций инструментов Mxx_ru. А генератор Mxx_ru::Makestyle_generator выступает лишь в качестве спасательного круга когда таких инструментов еще нет.
Конструктор класса Mxx_ru::Makestyle_generator получает четыре аргумента (последний аргумент опциональный):
Если аргументу конструктора Mxx_ru::Makestyle_generator требуется передать всего одно значение, то его можно передать в виде строки (как было показано выше). Если же аргументу требуется передать несколько значений, то их нужно указывать как вектор:
При выполнении построения файлов-целей генератор Mxx_ru::Makestyle_generator поочередно запускает команды из аргумента a_build_cmds. Если очередная команда возвращает ненулевой код возврата, то построение целей прерывается исключением. При выполнении операции clean коды возвратов команд из a_clean_cmds игнорируются.