模式每次调用仅匹配一次,make将删除中间文件 [英] Pattern only matches once per invocation and make is deleting intermediate files
问题描述
我在Makefile中有以下规则,可以分三个阶段构建可执行文件:
I have the following rules in a Makefile to build an executable in 3 stages:
all: build/myexe
build/myexe: output/main_dats.o output/foo_dats.o | build/
gcc $^ -o $@
output/%.o: output/%.c
patscc -c $< -o $@
output/%_dats.c: src/%.dats | output/
patsopt -cc -o $@ -d $<
build/:
mkdir -p build/
output/:
mkdir -p output/
src/%.dats
源文件用于生成output/%_dats.c
源文件,该文件被编译为output/%.o
目标文件,最后将它们链接到可执行文件build/myexe
.
An src/%.dats
source file is used to generate an output/%_dats.c
source file which is compiled to an output/%.o
object file and finally they are linked into the executable build/myexe
.
第一次运行make
只会成功构建两个.o
文件的 first :
Running make
the first time will only successfully build the first of the two .o
files:
$ make
mkdir -p output/
patsopt -cc -o output/main_dats.c -d src/main.dats
patscc -c output/main_dats.c -o output/main_dats.o
make: *** No rule to make target `output/foo_dats.o', needed by `build/myexe'. Stop.
rm output/main_dats.c
但是再次运行将构建第二个.o
文件并成功链接可执行文件:
But running again will build the second .o
file and successfully link the executable:
$ make
patsopt -cc -o output/foo_dats.c -d src/foo.dats
patscc -c output/foo_dats.c -o output/foo_dats.o
mkdir -p build/
gcc output/main_dats.o output/foo_dats.o -o build/myexe
rm output/foo_dats.c
,请注意,在每次调用结束时,命令rm output/..._dats.c
都将删除生成的.c
源文件.
and note that at the end of each invocation the command rm output/..._dats.c
is deleting the generated .c
source file.
这是一个没有模式匹配的Makefile:
Here is a Makefile written without pattern matching:
all: build/myexe
build/myexe: output/main_dats.o output/foo_dats.o | build/
gcc $^ -o $@
output/foo_dats.o: output/foo_dats.c
patscc -c $< -o $@
output/main_dats.o: output/main_dats.c
patscc -c $< -o $@
output/foo_dats.c: src/foo.dats | output/
patsopt -cc -o $@ -d $<
output/main_dats.c: src/main.dats | output/
patsopt -cc -o $@ -d $<
build/:
mkdir -p build/
output/:
mkdir -p output/
更可预测的工作方式:
$ make
mkdir -p output/
patsopt -cc -o output/main_dats.c -d src/main.dats
patscc -c output/main_dats.c -o output/main_dats.o
patsopt -cc -o output/foo_dats.c -d src/foo.dats
patscc -c output/foo_dats.c -o output/foo_dats.o
mkdir -p build/
gcc output/main_dats.o output/foo_dats.o -o build/myexe
,请注意,不会再删除生成的.c
文件.
and note that the generated .c
files are not being removed any more.
显然我在滥用模式匹配机制.我知道有某种通配符功能,但我相信它是用于文件遍历的.
Apparently I am misusing the pattern matching mechanism. I know there is some kind of wildcard function but I believe it is intended for file globbing.
推荐答案
为避免删除中间文件,您只需要将它们作为实际目标列出即可.例如,您可以编写一个单独的规则:
To avoid removing intermediate files, you just need to list them as actual targets somewhere. For example you could write a separate rule:
make_srcs: output/main_dats.c output/foo_dats.c
您不必将此目标make_srcs
作为先决条件列出,也不必为其提供配方等.只需将_dats.c
文件作为makefile中的实际目标或先决条件列出就足以防止它们被删除.
You don't have to list this target make_srcs
as a prerequisite, or provide it a recipe, etc. Just listing the _dats.c
files as actual targets or prerequisites in the makefile is enough to keep them from being deleted.
至于您的仅构建一些输出"行为,我不知道:它对我来说很好:
As for your "only building some output" behavior, I don't know: it works fine for me:
$ make --version | head -n1
GNU Make 4.2.1
$ cat Makefile
all: build/myexe
build/myexe: output/main_dats.o output/foo_dats.o | build/
touch $@
output/%.o: output/%.c
touch $@
output/%_dats.c: src/%.dats | output/
touch $@
build/:
mkdir -p build/
output/:
mkdir -p output/
make_srcs: output/main_dats.c output/foo_dats.c
$ rm -rf output build && make
mkdir -p output/
touch output/main_dats.c
touch output/main_dats.o
touch output/foo_dats.c
touch output/foo_dats.o
mkdir -p build/
touch build/myexe
因此,关于您的设置的某些问题尚未明确.正如评论所建议的那样,您需要运行make -d
(我会忽略-R
选项,我不知道您为什么要添加该选项),并弄清楚为什么make会引发该错误.
So there's something about your setup which hasn't been made clear in your question. As the comment suggested you need to run make -d
(I would leave off the -R
option, I don't know why you'd add that) and figure out why make throws that error.
这篇关于模式每次调用仅匹配一次,make将删除中间文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!