Как работать с правилом сборки с неизвестными целями в OMake при создании генератора списка целей

У меня есть проект, который использует OMake для своей системы сборки, и я пытаюсь справиться с довольно сложным угловым случаем.

У меня есть несколько файлов определений и инструмент, который может взять эти файлы определений и создать файлы GraphViz. Однако есть две проблемы:

  • Каждый файл определения может создавать несколько графиков, и список графиков, которые он может создать, кодируется в файле. Мой дамп инструмент имеет -list опция, которая перечисляет все графики, которые создаст файл определения.
  • Этот инструмент дампа встроен в исходное дерево.
  • Я хочу, чтобы этот список был доступен в OMakefile, чтобы я мог использовать другие правила для преобразования файлов DOT в SVG, и чтобы фиктивная цель зависела от всех SVG (цель: одна команда сборки, которая создает описания SVG для всех моих графиков).

Если бы у меня была только первая проблема, это было бы легко - я бы запустил инструмент для создания списка, а затем использовал этот список для создания цели, которая вызывает дампер для вывода файлов GraphViz. Тем не менее, я застрял на том, чтобы заставить инструмент дампа собираться до того, как он понадобится.

Если бы это было makeЯ бы просто побежал make рекурсивно построить инструмент дампа. Однако OMake не допускает рекурсивного вызова, и build функция доступна только из osh,

Любые предложения для хорошего решения этой проблемы?

1 ответ

Хорошо, вот мое предложение. Во-первых, это быстрый генератор, созданный в bash, который может принимать аргумент "--list", который создает переменную omake, которая содержит список действий. Генератор называется "generator.txt", так как мы собираемся "сделать" его, переименовав в.sh.

#!/bin/bash

if [ "$1" = "--list" ]; then
    echo -e 'FILES[] = \n\ta\n\tb\n\tc'
else
    echo 1 > a.dot
    echo 2 > b.dot
    echo 3 > c.dot
fi

Затем сам OMakefile:

.INCLUDE: rules : generator.txt
    cp generator.txt generator.sh
    chmod 755 generator.sh  
    ./generator.sh
    ./generator.sh --list > rules

DOTS[] =
    $(addsuffix .dot, $(FILES))

SVGS[] =
    $(addsuffix .svg, $(FILES))

# rule to turn a .dot into a .svg
%.svg: %.dot
    cp $*.dot $*.svg

.DEFAULT: $(SVGS)

.PHONY: clean
clean:
    rm -f generator.sh a.* b.* c.* rules

Хитрость в том, чтобы сгенерировать файл "rules" из generator.txt, который будет включен в OMakefile. Всякий раз, когда generator.txt (исходный код нашего генератора) изменяется, мы воссоздаем (собираем) генератор, запускаем его (создаем файлы a.dot, b.dot, c.dot) и, наконец, запускаем его с --list для генерации нашего Переменная FILE[], содержащая список файлов для генерации.

Затем становится тривиально генерировать переменные DOTS и SVGS, а также правило, которое превращает точку в SVG. Цель по умолчанию зависит от списка svgs, который будет собирать все по порядку.

Проблема с этим подходом состоит в том, что сборка генератора является довольно грубой, поскольку мы должны иметь список зависимостей "INCLUDE", являющийся реальными файлами. Тем не менее, это должно по крайней мере выполнить операции в правильном порядке.

Обратите внимание, как изменение generator.txt (например, добавление еще одного.dot для генерирования или изменение способа создания содержимого.dot) корректно вызывает регенерацию generator.sh, а затем любого сгенерированного файла, который будет иметь был изменен.

РЕДАКТИРОВАТЬ

Я думаю, что основная проблема заключается в том, что omake рассчитывает на то, что сможет сгенерировать весь граф зависимостей, прежде чем начинать какую-либо работу. Таким образом, он не может работать с некоторыми зависимостями для построения генератора, а затем генерировать больше зависимостей для работы на его выходе.

Я предполагаю, что есть способы обойти:

  • Во-первых, генератор должен быть скомпонован как часть директивы.INCLUDE, как я описал вначале, что создает трудности, поскольку вы должны поместить весь процесс сборки генератора в эту директиву.

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

  • Третий, который был бы моим любимым, - это двухфазная система сборки. В подкаталоге у вас есть OMakefile, который генерирует генератор и выводит файлы. В другом подкаталоге у вас есть другой OMakefile, который считывает содержимое первого каталога, чтобы сгенерировать список файлов для обработки, а затем выполняет преобразование. Затем в главном каталоге скрипт bash вызывает omake в первом каталоге, а затем во втором. Надеюсь, это должно означать, что вы можете сгенерировать все с помощью одной команды, но также и то, что перестройка будет минимальной: первый omake будет регенерировать файлы только в случае изменения входных данных, а второй omake будет преобразовывать только измененные или новые файлы.

Другие вопросы по тегам