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

Makefile处理具有相同扩展名的文件,makefile,Makefile,这似乎与我们的关系不大。在这个问题中,扩展名是相同的,但是输入和输出文件似乎在同一个目录中,并且文件名被有条件地重命名 我在./src/中收集了大量需要处理的.txt文件,并作为同名的txt文件转储到/(这是一个名为target/的目录)。我想使用make,这样只有./src/中已更改的文件才能在/中更新。我想让原型工作之前,我把真正的代码 我在/中的Makefile如下所示: DIR = ../src INPUTS = $(wildcard $(DIR)/*.txt) OUTPUTS = $(

这似乎与我们的关系不大。在这个问题中,扩展名是相同的,但是输入和输出文件似乎在同一个目录中,并且文件名被有条件地重命名

我在
./src/
中收集了大量需要处理的
.txt
文件,并作为同名的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" "$<" > $@
运行
make check
可正确显示
输入和
输出

target/ $ make check
DIR = ../src
INPUTS = ../src/test1.txt ../src/test2.txt
OUTPUTS = test1.txt test2.txt
如果我运行
makeall
,它每次都会生成每个文件。这是预期的
.PHONY$(输入)

如果我删除了
.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


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

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

替换

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

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

有关更多详细信息,请参阅

避免相对路径也是一种良好做法:

DIR = $(abspath ../src)

完美的我不得不将
OUTPUTS=…
行更改为
OUTPUTS=$(patsubst$(DIR)/%.txt,${CURDIR}/%.txt,$(INPUTS))
,但工作方式与广告相同。谢谢大家!@马特。很好,
make
对路径过于敏感,它只进行字符串文件名比较,例如“./src/x”不等于“./src/./src/x”。@MattD。这就是为什么将所有路径转换为绝对路径有助于避免此问题。
${CURDIR}/%.txt: $(DIR)/%.txt
DIR = $(abspath ../src)