Как работать с правилом сборки с неизвестными целями в 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 будет преобразовывать только измененные или новые файлы.