Makefile覆盖默认隐式规则

时间:2015-06-16 16:28:54

标签: c++ c makefile

为什么此规则无法覆盖默认的隐式规则?

当调用make时:make myapp(假设myapp.c在那里)。 make运行默认命令来构建和链接程序,而不是此隐式规则中定义的命令:

#... omitted code
LCUS=$(LIBS)/libcus.a

#... omitted code
% : %.o $(LCUS)
        echo  !!! Custom build !!!
        $(MY_CMD) $< -o $@ $(LCUS)

2 个答案:

答案 0 :(得分:4)

取自GNU online make manual

  

您可以覆盖内置隐式规则(或已定义的规则)   你自己)通过定义一个具有相同目标和的新模式规则   先决条件,但不同的命令。

所以我认为这是因为先决条件与隐式规则不同。

另请参阅make手册:

  

n自动链接单个对象文件n.o   通过C编译器运行链接器(通常称为ld)。该   使用的精确命令是$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)。   对于只有一个的简单程序,此规则是正确的   源文件。如果有多个,它也会做正确的事情   目标文件(可能来自各种其他源文件),一个   其名称与可执行文件的名称相匹配。因此,

 x: y.o z.o
     

x.cy.cz.c全部存在将执行时:

cc -c x.c -o x.o
cc -c y.c -o y.o
cc -c z.c -o z.o
cc x.o y.o z.o -o x
rm -f x.o
rm -f y.o
rm -f z.o

所以基本上make理解从.o文件生成的程序文件的隐式规则,但是当你投入静态库时它并不理解。一种简单的测试方法是从依赖项中删除$(LCUS)(作为临时度量),看它是否使用您的规则而不是内置规则。如果确实如此,那么你知道这是你的问题。如果只是添加myapp替换%是一个问题,因为您希望规则构建多个目标,您可以尝试以下操作:

$(APPS): % : %.o $(LCUS)

其中$(APPS)是一个包含您要构建的所有应用程序的变量。这将允许一个规则构建多个目标。您也可以完全跳过变量的使用并放置一个以空格分隔的列表。这是静态模式规则的示例,可以找到更多信息here。可以找到静态模式和隐式规则之间的差异here.

答案 1 :(得分:2)

您的规则与内置隐式规则不同,因此它不会取消它。

此外,make总是更喜欢不需要将中间文件构建到其中的规则。如果您预先创建.a文件,则可能会使用您的规则(但它可能甚至不会)。

如果您取消内置规则并保留规则,我认为它应该正常工作。