1

为清楚起见,我在带有GnuWin32 make的 Windows 上运行它。

我有一组目录,其中包含多个不同级别的降价文件 - 理论上它们可能位于分支节点中,但我认为目前它们仅位于叶节点中。我有一组pandoc/LaTeX命令可以运行以将降价文件转换为 PDF——显然,如果降价文件已更新,我只想重新创建 PDF,所以 amakefile似乎合适。

我想要的是makefile根目录中的单个,它遍历任何和所有子目录(到任何深度)并应用我将为运行pandoc指定的 make 规则。

根据我所能找到的,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

我如何编写一个makefile来处理这种情况?

4

2 回答 2

0

这是一小组 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应该更新任何内容。

如果您的 makefile 中有其他目标,请确保这all是第一个非模式目标,或调用 make asmake all

更新 Makefile

如果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 在评论中建议

否则,您可以使用操作系统上可用的工具来实现脚本,并添加一个额外的目标update:来计算文件列表并用更新的文件列表替换以更新的文件列表开头的行PDF_FILES

于 2018-07-08T13:05:40.380 回答
0

根据 @DmitiChubarov 和 @MadScientist 的建议,适用于 Windows 的代码的最终版本如下:

%.pdf: %.md
    pandoc $^ -o $@

PDF_FILES:=$(shell dir /s /b *.md | sed "s/\.md/\.pdf/g")

all: ${PDF_FILES}
于 2018-07-23T20:57:22.783 回答