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

时间:2016-06-10 17:03:36

标签: makefile

这似乎与How to write Makefile where target and source files have the same extension?略有关系。在那个问题中,扩展名是相同的,但输入和输出文件似乎在同一个目录中,文件名被有条件地重命名。

我在.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" "$<" > $@

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

target/ $ make test2.txt
sed -e "s/test/cat/g" "../src/test2.txt" > test2.txt

正在运行make check会正确显示INPUTSOUTPUTS

target/ $ make check
DIR = ../src
INPUTS = ../src/test1.txt ../src/test2.txt
OUTPUTS = test1.txt test2.txt

如果我运行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.

它永远不会处理test2.txt

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

有没有办法让Makefile保持在&#39;目标/&#39;以及生成的目标文件,并将这些目标文件基于相对路径中的某些内容?

1 个答案:

答案 0 :(得分:2)

替换

%.txt: $(DIR)/%.txt

使用:

${CURDIR}/%.txt: $(DIR)/%.txt

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

有关详细信息,请参阅§10.5.4 How Patterns Match

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

DIR = $(abspath ../src)