这似乎与如何编写 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.txt和test2.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显示INPUTS和OUTPUTS正确。
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/”中的内容与生成的目标文件一起保留,并将这些目标文件基于相对路径中的某些内容?
代替
\n\n%.txt: $(DIR)/%.txt\nRun Code Online (Sandbox Code Playgroud)\n\n和:
\n\n${CURDIR}/%.txt: $(DIR)/%.txt\nRun Code Online (Sandbox Code Playgroud)\n\n这种方式%.txt不匹配.txt任何目录中的任何文件。换句话说,您将此规则的范围限制为${CURDIR}/仅文件,这可以防止无限递归。
有关更多详细信息,请参阅\xc2\xa710.5.4 模式如何匹配。
\n\n避免相对路径也是一个好习惯:
\n\nDIR = $(abspath ../src)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
4257 次 |
| 最近记录: |