【问题标题】:How can we 'loop' around files in Makefile我们如何在 Makefile 中“循环”文件
【发布时间】:2021-06-09 13:55:55
【问题描述】:

我在一个目录中有一些 tex 文件,其中一些被进一步组织到子目录中。

input/
|
|-- one.tex
|-- two.tex
|-- sub1/
|   |
|   |-- three.tex
|           
|-- four.tex
|           
|-- sub2/
|   |
|   |-- five.tex
|           
|-- six.tex

然后我在这些 tex 文件中的每一个上运行 pdflatex 以在输出目录中创建一个具有相同目录结构(可能使用 mkdir -p)的相应 pdf 文件(在其名称后附加一个 "_out" 而没有扩展名) .

output/
|
|-- one_out.pdf
|-- two_out.pdf
|-- sub1/
|   |
|   |-- three_out.pdf
|           
|-- four_out.pdf
|           
|-- sub2/
|   |
|   |-- five_out.pdf
|           
|-- six_out.pdf

如果修改了任何tex文件,我需要使用make更新相应的pdf文件。

有谁知道如何做到这一点?

我做了类似的事情,但它只处理一个文件(第一个)。

SOURCE_DIR := input
BUILD_DIR := output

TEX_FILES := $(shell find $(SOURCE_DIR) -type f -name "*.tex")
PDF_FILES := $(patsubst $(SOURCE_DIR)/%.tex, $(BUILD_DIR)/%.pdf, $(TEX_FILES))

.PHONY: all

all: $(PDF_FILES)

# $< are inp files and $@ are out files
$(BUILD_DIR)/%.pdf: $(SOURCE_DIR)/%.tex
    pdflatex -jobname=$(addsuffix _out,$(basename $@)) $<

PS:使用其他工具可能有更简单的方法来做到这一点(我也很高兴知道它们!)但我正在寻找一种使用 gnu 完成此操作的方法)make 作为一种方法更好地了解它。

【问题讨论】:

    标签: linux makefile gnu-make


    【解决方案1】:

    如果您展示一个带有一些实际文件名的小示例以及运行 make 时获得的实际输出,将会很有帮助。我在这个 makefile 中看不到为什么它应该停止在一个文件上的明显原因,除非所有其他文件已经存在并且是最新的。

    我确实看到了一些奇怪的东西,但由于我对 pdflatex 的工作原理一无所知,所以也许这是意料之中的:

    # $< are inp files and $@ are out files
    $(BUILD_DIR)/%.pdf: $(SOURCE_DIR)/%.tex
            pdflatex -jobname=$(addsuffix _out,$(basename $@)) $<
    

    您的评论(正确)说$@ 是输出文件,但我在您的pdflatex 命令行上没有看到您告诉pdflatex 要使用什么输出文件名的任何地方。它是怎么计算出来的?

    【讨论】:

    • pdflatex 似乎使用 -jobname 选项来接受没有 .pdf 扩展名的输出 pdf 名称。所以我把它命名为-jobname=$(addsuffix _out,$(basename $@))。这是错的吗? $@ 具有完整的输出文件路径,例如 /path/to/output/one.tex,在 basename 之后变为 /path/to/output/one,在 addsuffix 上变为 /path/to/output/one_out。这是我的思路。
    • 正如您的评论所说,make 将它希望您的配方创建的文件放入 $@ 变量中,这就是您的配方应该创建的文件。如果您的配方创建了一些不完全是 $@ 的其他文件名,那么这是不正确的并且 make 将不起作用:下次运行 make 时,它​​将查找文件 $@ 并发现它不存在(因为上次运行 make 它创建了一些其他文件),它将再次运行该命令。然后下一次它会寻找$@ 并看到它仍然不存在,然后再次运行命令......等等......
    • 哦.. 有道理.. 让我多摆弄一下我的 Makefile,看看会发生什么。谢谢。
    • 而且它并没有真正给出终端上打印的任何输出(至少目前是这样写的)。这就是我没有包含任何错误消息的原因。
    • “处理一个文件”与“不给出任何输出”不同......我想看看你真正得到的一个简单的例子。问题是,$@ 的问题不应该导致 make 跳过一堆应该创建的文件。它会导致 make rebuild 不应该重建的文件。因此,如果您真的看到您有很多文件并忽略它们的情况,那么还有其他问题。我建议您运行 make --debug=b 并查看输出是否能说明正在发生的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    相关资源
    最近更新 更多