模式每次调用仅匹配一次,make将删除中间文件 [英] Pattern only matches once per invocation and make is deleting intermediate files

查看:127
本文介绍了模式每次调用仅匹配一次,make将删除中间文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆