简体   繁体   English

Makefile覆盖默认隐式规则

[英]Makefile overriding default implicit rule

Why this rule cannot override the default implicit rule ? 为什么此规则无法覆盖默认的隐式规则?

When make is invoked like: make myapp (suppose myapp.c is there). 当调用make时: make myapp (假设myapp.c在那里)。 The make runs the default command to build and link the program instead the commands defined in this implicit rule: make运行默认命令来构建和链接程序,而不是此隐式规则中定义的命令:

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

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

Taken from the GNU online make manual : 摘自GNU在线make手册

You can override a built-in implicit rule (or one you have defined yourself) by defining a new pattern rule with the same target and prerequisites, but different commands. 您可以通过定义具有相同目标和先决条件但具有不同命令的新模式规则来覆盖内置隐式规则(或您自己定义的规则)。

So I would assume it is because the prerequisites are not the same as the implicit rule. 所以我认为这是因为先决条件与隐式规则不同。

Also take from the make manual: 还可以从make手册中获取:

Linking a single object file n is made automatically from no by running the linker (usually called ld ) via the C compiler. 联的单个对象文件n自动地从由no通过运行接头(通常称为ld通过C编译器)。 The precise command used is $(CC) $(LDFLAGS) no $(LOADLIBES) $(LDLIBS) . 使用的精确命令是$(CC) $(LDFLAGS) no $(LOADLIBES) $(LDLIBS) This rule does the right thing for a simple program with only one source file. 对于只有一个源文件的简单程序,此规则是正确的。 It will also do the right thing if there are multiple object files (presumably coming from various other source files), one of which has a name matching that of the executable file. 如果有多个目标文件(可能来自各种其他源文件),其中一个名称与可执行文件的名称相匹配,它也会做正确的事情。 Thus, 从而,

  x: yo zo 

when xc , yc and zc all exist will execute: xcyczc都存在时将执行:

 cc -c xc -o xo cc -c yc -o yo cc -c zc -o zo cc xo yo zo -ox rm -f xo rm -f yo rm -f zo 

So basically make understands implicit rules for program files that are generated from .o files but when you throw in your static library it doesn't understand. 所以基本上make理解为从生成的程序文件潜规则.o文件,但是当你在你的静态库扔它不理解。 A simple way to test would be to remove $(LCUS) from your dependencies (as a temporary measure) to see if it then uses your rule instead of the built in one. 一种简单的测试方法是从依赖项中删除$(LCUS) (作为临时措施),看它是否使用您的规则而不是内置规则。 If it does then you know that is your problem. 如果确实如此,那么你知道这是你的问题。 If simply adding myapp in replace of % is a problem because you want the rule to build multiple targets you can try the following: 如果只是添加myapp替换%是一个问题,因为您希望规则构建多个目标,您可以尝试以下方法:

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

where $(APPS) is a variable containing all the applications you wish to build. 其中$(APPS)是一个包含您要构建的所有应用程序的变量。 This will allow one rule to build multiple targets. 这将允许一个规则构建多个目标。 You could also skip the use of the variable altogether and place a space separated list. 您也可以完全跳过变量的使用并放置一个以空格分隔的列表。 This is an example of a static pattern rule, more information can be found here . 这是静态模式规则的示例,可以在此处找到更多信息。 The difference between static pattern and implicit rules can be found here. 静态模式和隐式规则之间的区别可以在这里找到

Your rule isn't the same as the built-in implicit rule so it doesn't cancel it. 您的规则与内置隐式规则不同,因此不会取消它。

Additionally, make always prefers a rule that doesn't require intermediate files to be built to one that does. 此外,make始终优先选择不需要将中间文件构建到其中的规则。 If you pre-create the .a file make might use your rule instead (but it might not even still). 如果你预先创建.a文件make可能会使用你的规则(但它甚至可能不会)。

If you cancel the built-in rule and leave your rule in place it should work correctly I believe. 如果您取消内置规则并保留规则,我认为它应该正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM