Как сделать один make-файл, который применяет одну и ту же команду к подкаталогам?
Для ясности, я запускаю это на Windows с GnuWin32 make
,
У меня есть набор каталогов с файлами уценки на нескольких разных уровнях - теоретически они могут быть в узлах ветвления, но я думаю, что в настоящее время они находятся только в конечных узлах. У меня есть набор команд pandoc/LaTeX, чтобы превратить файлы уценки в PDF-файлы, и, очевидно, я хочу воссоздать PDF-файлы только в том случае, если файл уценки был обновлен, поэтому makefile
кажется уместным.
То, что я хотел бы, это один makefile
в корне, который перебирает все подкаталоги (на любую глубину) и применяет правило make, которое я укажу для запуска pandoc.
Из того, что я смог найти, recursive makefiles
потребовать от вас иметь makefile
в каждом подкаталоге (что похоже на административные издержки, которых я бы хотел избежать) и / или требовать, чтобы вы перечислили все подкаталоги в начале makefile
(опять же, предпочел бы избежать этого).
Теоретическая структура папок:
root
|-make
|-Folder AB
| |-File1.md
| \-File2.md
|-Folder C
| \-File3.md
\-Folder D
|-Folder E
| \-File4.md
|-Folder F
\-File5.md
Как мне написать make-файл, чтобы справиться с этой ситуацией?
2 ответа
Вот небольшой набор правил Makefile, которые, надеюсь, помогут вам
%.pdf : %.md
pandoc -o $@ --pdf-engine=xelatex $^
PDF_FILES=FolderA/File1.pdf FolderA/File2.pdf \
FolderC/File3.pdf FolderD/FolderE/File4.pdf FolderD/FolderF/File5.pdf
all: ${PDF_FILES}
Позвольте мне объяснить, что здесь происходит. Сначала у нас есть шаблонное правило, которое сообщает make, как преобразовать файл Markdown в файл PDF. --pdf-engine=xelatex
вариант здесь только для иллюстрации.
Затем мы должны сказать Make, какие файлы рассмотреть. Мы объединяем имена в одну переменную PDF_FILES
, Это значение для этой переменной может быть создано с помощью отдельных сценариев, которые сканируют все подкаталоги для .md
файлы.
Обратите внимание, что нужно быть особенно осторожным, если имена файлов или каталогов содержат пробелы.
Затем мы просим Make проверить, PDF_FILES
должно быть обновлено.
Если у вас есть другие цели в вашем make-файле, убедитесь, что all
это первая нешаблонная цель, или вызов make как make all
Обновление Makefile
Если shell
функции работают для вас, а базовые утилиты, такие как sed и find, доступны, вы можете сделать свой make-файл динамическим с помощью одной строки.
%.pdf : %.md
pandoc -o $@ --pdf-engine=xelatex $^
PDF_FILES:=$(shell find -name "*.md" | xargs echo | sed 's/\.md/\.pdf/g' )
all: ${PDF_FILES}
MadScientist предложил именно это в комментариях
В противном случае вы можете реализовать скрипт, используя инструменты, доступные в вашей операционной системе, и добавить дополнительную цель update:
что бы вычислить список файлов и заменить строку, начинающуюся с PDF_FILES
с обновленным списком файлов.
Окончательная версия кода, которая работала для Windows, основана на предложениях @DmitiChubarov и @MadScientist:
%.pdf: %.md
pandoc $^ -o $@
PDF_FILES:=$(shell dir /s /b *.md | sed "s/\.md/\.pdf/g")
all: ${PDF_FILES}