[英]How to make a single makefile that applies the same command to sub-directories?
For clarity, I am running this on windows with GnuWin32 make
. 为了清楚起见,我在Windows上使用GnuWin32
make
运行它。
I have a set of directories with markdown files in at several different levels - theoretically they could be in the branch nodes, but I think currently they are only in the leaf nodes. 我有一组目录,其中的markdown文件位于几个不同的级别上-理论上它们可以在分支节点中,但是我认为当前它们仅在叶节点中。 I have a set of pandoc/LaTeX commands to run to turn the markdown files into PDFs - and obviously only want to recreate the PDFs if the markdown file has been updated, so a
makefile
seems appropriate. 我有一组pandoc / LaTeX命令可以运行,以将markdown文件转换为PDF-显然,仅当markdown文件已更新时才想重新创建PDF,因此
makefile
似乎合适。
What I would like is a single makefile
in the root, which iterates over any and all sub-directories (to any depth) and applies the make rule I'll specify for running pandoc . 我想要的是根目录中的单个
makefile
,它遍历所有子目录(至任何深度)并应用我将为运行pandoc指定的make规则。
From what I've been able to find, recursive makefiles
require you to have a makefile
in each sub-directory (which seems like an administrative overhead that I would like to avoid) and/or require you to list out all the sub-directories at the start of the makefile
(again, would prefer to avoid this). 根据我的发现,
recursive makefiles
要求您在每个子目录中都有一个makefile
(这似乎是我要避免的管理开销)和/或要求您列出所有子目录在makefile
的开头(再次,宁愿避免这种情况)。
Theoretical folder structure: 理论文件夹结构:
root
|-make
|-Folder AB
| |-File1.md
| \-File2.md
|-Folder C
| \-File3.md
\-Folder D
|-Folder E
| \-File4.md
|-Folder F
\-File5.md
How do I write a makefile to deal with this situation? 如何编写一个makefile来处理这种情况?
Here is a small set of Makefile rules that hopefuly would get you going 这是一小套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}
Let me explain what is going on here. 让我解释一下这是怎么回事。 First we have a pattern rule that tells make how to convert a Markdown file to a PDF file.
首先,我们有一个模式规则,该规则告诉make如何将Markdown文件转换为PDF文件。 The
--pdf-engine=xelatex
option is here just for the purpose of illustration. --pdf-engine=xelatex
选项仅在此处用于说明目的。
Then we need to tell Make which files to consider. 然后,我们需要告诉Make要考虑哪些文件。 We put the names together in a single variable
PDF_FILES
. 我们将名称放到单个变量
PDF_FILES
。 This value for this variable can be build via a separate scripts that scans all subdirectories for .md
files. 可以通过扫描所有子目录中的
.md
文件的单独脚本来构建此变量的此值。
Note that one has to be extra careful if filenames or directory names contain spaces. 请注意 ,如果文件名或目录名称包含空格,则必须格外小心。
Then we ask Make to check if any of the PDF_FILES
should be updated. 然后,我们要求Make检查是否应更新任何
PDF_FILES
。
If you have other targets in your makefile, make sure that all
is the first non-pattern target, or call make as make all
如果您的makefile中还有其他目标,请确保
all
是第一个非模式目标,或将make称为make all
If shell
functions works for you and basic utilities such as sed and find are available, you could make your makefile dynamic with a single line. 如果
shell
函数对您有用,并且sed和find等基本实用程序可用,则可以使一行的makefile动态化。
%.pdf : %.md
pandoc -o $@ --pdf-engine=xelatex $^
PDF_FILES:=$(shell find -name "*.md" | xargs echo | sed 's/\.md/\.pdf/g' )
all: ${PDF_FILES}
MadScientist suggested just that in the comments MadScientist在评论中建议
Otherwise you could implement a script using the tools available on your operating system and add an additional target update:
that would compute the list of files and replace the line starting with PDF_FILES
with an updated list of files. 否则,您可以使用操作系统上可用的工具来实现脚本,并添加其他目标
update:
它将计算文件列表,并将以PDF_FILES
开头的行替换为更新的文件列表。
Final version of the code that worked for Windows, based on @DmitiChubarov and @MadScientist's suggestions is as follows: 基于@DmitiChubarov和@MadScientist的建议,适用于Windows的代码的最终版本如下:
%.pdf: %.md
pandoc $^ -o $@
PDF_FILES:=$(shell dir /s /b *.md | sed "s/\.md/\.pdf/g")
all: ${PDF_FILES}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.