make执行makefile中未指定的命令

时间:2012-06-06 07:19:48

标签: makefile

说我有以下makefile:

TARGETS = a b c

all: $(TARGETS)
    @echo Done.

%.o: %.cpp
    @echo Compiling $@...
    touch $@

%: %.o
    @echo Building $@...
    touch $@

我希望这应该没有问题:all规则会触发%规则,这将触发%.o规则,生成a.o },b.oc.o个文件,最后会生成abc个文件。

但是,运行make会导致以下输出:

ghb@Nemo:~/Downloads$ make
g++     a.cpp   -o a
/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/../../../crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [a] Error 1

为什么我试图突然运行g++?我没有规则。此外,运行make a.o后跟make a工作正常,但运行make a会导致上述行为。

我可以做些什么来防止make尝试“提出”它认为适合目标的命令?

2 个答案:

答案 0 :(得分:0)

最后一条规则似乎被忽略或误解,因此make会依赖于其对cpp文件的隐式规则(参见Catalogue of Implicit Rules)。
它可以使用这种语法解决:

TARGETS := a b c

all: $(TARGETS)
        @echo Done.

%.o: %.cpp
        @echo Compiling $@...
        touch $@

define make_target
$(1): $(1).o
        @echo Building $$@...
        touch $$@
endef
$(foreach tgt, $(TARGETS), $(eval $(call make_target, $(tgt))))

顺便说一下,使用make all而不是make,否则只会构建第一个目标。

答案 1 :(得分:0)

这里涉及三个规则,你写的两个:

%.o: %.cpp
    @echo Compiling $@...
    touch $@

%: %.o
    @echo Building $@...
    touch $@

和一个“内置”:

%: %.cpp
    $(CXX) $< -o $@     # There's a little more to it, but never mind.

当您尝试构建a时,Make会查看其规则列表并提出两个候选项:

%: %.o    # yours
%: %.cpp  # built in

如果a.o已经存在,那么您的规则优先(这就是为什么如果您make a.o首先使用您的链的原因)。如果没有,则Make选择第二个,因为a.cpp 存在。

如果您不希望Make在构建目标时考虑这些内置规则,请使用make -r,也称为make --no-builtin-rules.