Makefile处理具有相同扩展名的文件

Mat*_* D. 3 makefile

这似乎与如何编写 Makefile 其中目标文件和源文件具有相同的扩展名略有相关?。在该问题中,扩展名是相同的,但输入和输出文件似乎位于同一目录中,并且文件名正在有条件地重命名。

我有大量.txt文件../src/需要处理,并作为同名的 txt 文件转储到./(名为 的目录)中。target/我想使用make, 这样只有../src/已更改的文件才会在./. 我希望在放入真正的代码之前先让原型工作。

我的Makefile内容./如下:

DIR = ../src
INPUTS = $(wildcard $(DIR)/*.txt)
OUTPUTS = $(patsubst $(DIR)/%.txt,%.txt,$(INPUTS))

all: $(OUTPUTS)

.PHONY: $(INPUTS)

check:
    @echo "DIR = $(DIR)"
    @echo "INPUTS = $(INPUTS)"
    @echo "OUTPUTS = $(OUTPUTS)"

%.txt: $(DIR)/%.txt
    sed -e "s/test/cat/g" "$<" > $@
Run Code Online (Sandbox Code Playgroud)

目前, 的内容../src/test1.txttest2.txt。正如现在的 Makefile 所示,运行make test2.txt会按预期生成文件。

target/ $ make test2.txt
sed -e "s/test/cat/g" "../src/test2.txt" > test2.txt
Run Code Online (Sandbox Code Playgroud)

运行make check显示INPUTSOUTPUTS正确。

target/ $ make check
DIR = ../src
INPUTS = ../src/test1.txt ../src/test2.txt
OUTPUTS = test1.txt test2.txt
Run Code Online (Sandbox Code Playgroud)

如果我运行make all,它每次都会生成每个文件。这是预期的线路.PHONY $(INPUTS)

如果我删除.PHONY $(INPUTS)目标,Make 本身就会陷入困境,试图找到要生成的目标../src/test1.txt,并在其前面添加前缀$(DIR),直到文件名太长并放弃。

make: stat: ../src/../src/../src/ [repeat for a few pages] ../src/../src/test1.txt: File name too long
make: stat: ../src/../src/../src/ [repeat for a few pages] ../src/../src/../src/test1.txt: File name too long
make: *** No rule to make target `../src/../src/../src/[repeat]../src/../src/test1.txt', needed by `../src/[repeat]../src/../src/test1.txt'.  Stop.
Run Code Online (Sandbox Code Playgroud)

它永远不会进行处理test2.txt


当我起草这篇文章时,我想到../从 DIR 中删除 ,并重新定位 Makefile,使其成为 和 的父src/target/。这种方法似乎有效,但并不理想。最终会有一系列这样的 Makefile,每个文件都从一个目录拉到另一个目录。

有没有办法将Makefile“target/”中的内容与生成的目标文件一起保留,并将这些目标文件基于相对路径中的某些内容?

Max*_*kin 6

代替

\n\n
%.txt: $(DIR)/%.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

和:

\n\n
${CURDIR}/%.txt: $(DIR)/%.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

这种方式%.txt不匹配.txt任何目录中的任何文件。换句话说,您将此规则的范围限制为${CURDIR}/仅文件,这可以防止无限递归。

\n\n

有关更多详细信息,请参阅\xc2\xa710.5.4 模式如何匹配。

\n\n

避免相对路径也是一个好习惯:

\n\n
DIR = $(abspath ../src)\n
Run Code Online (Sandbox Code Playgroud)\n