品牌问题

Nowox

让我们考虑这个小例子。没有的话,一切都会正常运行VILLAIN其实这个词会导致错误,但不是我期望的那样。

错误:

$ make
mkdir -p obj
zip out.exe obj/foo.o obj/bar.o obj/baz.o
        zip warning: name not matched: obj/foo.o
        zip warning: name not matched: obj/bar.o
        zip warning: name not matched: obj/baz.o

zip error: Nothing to do! (out.exe)
Makefile:9: recipe for target 'out.exe' failed
make: *** [out.exe] Error 12

似乎make希望通过执行尚未建立依赖关系的配方来快一点(obj / foo.o ...)。实际上,我期待的是这样的错误:“无法找到VILLAIN来制作obj / foo.o”

Makefile:

#!/usr/bin/env make
SRCDIR = src
OBJDIR = obj

SRC = $(addsuffix .c,foo bar baz)
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRC:c=o)))

out.exe: $(OBJ)
    zip $@ $^ 

$(OBJDIR)/%.o: $(SRCDIR)/%.c VILLAIN
    cp $< $@

$(OBJ) : | $(OBJDIR)

$(OBJDIR):
    mkdir -p $@

clean:
    rm -f *.c
    rm -rf $(OBJDIR)/ $(SRCDIR)/
    mkdir -p $(SRCDIR)/
    touch $(addprefix $(SRCDIR)/,$(SRC))

但是,如果我删除小人,一切正常:

$ make clean
rm -f *.c
rm -rf obj/ src/
mkdir -p src/
touch src/foo.c src/bar.c src/baz.c

$ make
mkdir -p obj
cp src/foo.c obj/foo.o
cp src/bar.c obj/bar.o
cp src/baz.c obj/baz.o
zip out.exe obj/foo.o obj/bar.o obj/baz.o
  adding: obj/foo.o (stored 0%)
  adding: obj/bar.o (stored 0%)
  adding: obj/baz.o (stored 0%)

为什么要在建立先决条件之前先尝试确定目标?

疯狂的科学家

在这方面,模式规则不像显式规则那样工作。可以使用许多不同的模式规则来创建相同的目标(考虑到,.o可以从C源文件,C ++源文件,FORTRAN源文件等创建)。

因此,当make尝试找到构建目标的模式规则时,为了确定模式是否匹配,make会尝试构建所有先决条件。如果前提条件之一不能建立,那么这不是错误!Make只需继续执行下一个匹配并尝试的模式规则。因此,VILLIAN不存在且无法构建的事实意味着,make将永远不会选择此模式规则,因为无法满足先决条件……但这不是错误,也不会打印任何消息(嗯,如果您查看make的调试输出时,会看到关于它的注释)。

因此,make将发现它没有知道如何构建的规则obj/foo.o您可能会在那时遇到错误...但是不会,因为您添加了以下规则:

$(OBJ) : | $(OBJDIR)

通过这样做,您已经声明obj/foo.o是一个知道的目标,因此如果目标不存在,它将不会抱怨。如果更改此选项以将仅订购的先决条件添加到模式规则中,那么您将获得更多可理解的行为:

$(OBJDIR)/%.o: $(SRCDIR)/%.c VILLAIN | $(OBJDIR)
        cp $< $@

$(OBJDIR):
        mkdir -p $@

给出:

make: *** No rule to make target 'obj/foo.o', needed by 'out.exe'.  Stop.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章