如何制作将相同命令应用于子目录的单个makefile?

时间:2018-07-08 12:56:21

标签: recursion makefile makefile-project multiple-makefiles

为清楚起见,我正在使用 GnuWin32 make在Windows上运行此代码。

我有一组目录,其中的markdown文件位于几个不同的级别上-理论上它们可以在分支节点中,但是我认为当前它们仅在叶节点中。我有一组 pandoc / LaTeX 命令可以运行,以将降价文件转换为PDF-并且显然只想在降价文件已更新的情况下重新创建PDF,因此看来makefile合适的。

我想要的是在根目录中的单个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来处理这种情况?

2 个答案:

答案 0 :(得分: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称为make 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开头的行替换为更新后的列表。文件。

答案 1 :(得分:0)

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

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

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

all: ${PDF_FILES}