简体   繁体   English

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

[英]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

Updating the Makefile 更新Makefile

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.

相关问题 SHELL-在单个命令行中删除主目录及其子目录下的文件 - SHELL - Deleting files under home directory and its sub-directories in a single command line Bash:递归地重新创建子目录 - Bash: Recreate recursively sub-directories 获取VBA中的子目录列表 - Get list of sub-directories in VBA “查找”或“ grep”文件名以匹配目录和子目录中的模式 - 'find' or 'grep' a filename to match pattern within directories and sub-directories 仅列出所有目录和子目录的详细信息 - List details of all directories and sub-directories only 列出目录和子目录,并将每个级别存储在数组中 - List directories and sub-directories and store every level in array 通过C ++中的递归查找目录和子目录 - Find directories and sub-directories through recursion in C++ 如何使用 PowerShell 递归搜索目录和子目录中的所有文件? - How to recursively search all files in a directory and sub-directories using PowerShell? 如何使用PowerShell删除一个目录和所有小于100kb的子目录中的所有文件 - How to delete all files in a directory and all sub-directories less than 100kb using PowerShell 如何在子目录中使用子目录名称的前缀重命名所有文件,然后将文件移动到新目录? - How can I rename all files in sub-directories with prefix of sub-directory name and then move files to new directory?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM