2012-06-06 87 views
1

说我有以下生成文件没有指定命令:make执行在makefile

TARGETS = a b c 

all: $(TARGETS) 
    @echo Done. 

%.o: %.cpp 
    @echo Compiling [email protected] 
    touch [email protected] 

%: %.o 
    @echo Building [email protected] 
    touch [email protected] 

我预计,这应该没有问题,运行:all规则将触发%,规则,可能会触发%.o规则,生成a.ob.oc.o文件,然后最终生成a,bc文件。

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

[email protected]:~/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“想出”它认为适合目标的命令?

回答

0

最后一条规则似乎被忽略或误解,因此请回落它对cpp文件的隐含规则(请参阅Catalogue of Implicit Rules)。
它可工作围绕这个语法:

TARGETS := a b c 

all: $(TARGETS) 
     @echo Done. 

%.o: %.cpp 
     @echo Compiling [email protected] 
     touch [email protected] 

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

顺便说一句,使用make all而不是make或只有第一个目标将建成。

+0

这很酷!但是,请您解释一下您的解决方案中发生了什么,以及它为什么可行,而不是我的解决方案? – gablin

+0

其实我没有解释为什么“%:%o”规则被忽略。但是,如果将其替换为“%.exe:%o”(与每个目标名称一起),它就可以工作!我的解决方案为每个目标(使用define..endef)定义了一个通用规则,并且$(foreach ..,$(eval ..))宏将其扩展为目标的每个元素(请参阅http:// www .gnu.org /软件/制作/手动/ make.html#EVAL-功能)。 – Francois

+0

...并回答你最初的问题,因为“%:%.o”规则被忽略,使得它回到它的C++隐式编译规则上(参见http://www.gnu.org/software/make/manual /make.html#Catalogue-of-Rules),这就是令人惊讶的g ++调用的来源。 – Francois

0

有三个规则这里涉及到两个,你写道:

%.o: %.cpp 
    @echo Compiling [email protected] 
    touch [email protected] 

%: %.o 
    @echo Building [email protected] 
    touch [email protected] 

,一个是“建”:

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

当您尝试建立a,使经过它的规则清单并出现两位候选人:

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

如果a.o已经存在,那么您的规则优先(这就是为什么如果您首先make a.o您的链条工作)。如果不是,那么Make选择第二个,因为a.cpp确实存在

如果你不想让你的构建目标时要考虑这些内置的规则,使用make -r,也被称为make --no-builtin-rules.