makefile的隐式规则

target := exe

source_code = hello.c

OBJS = $(source_code:.c=.o)

$(target):$(OBJS)
    gcc $^ -o $@

clean:
    $(RM) $(target) $(OBJS)

一上来直接展示一份makefile代码。

功能: 从功能角度来说,这份makefile代码可以编译出对应的目标文件,并且顺利执行。

思考: 这其实是一份质量不合格的makefile代码。请仔细观察。 

。。。。 什么 ?  你看着这个makefile却一点都不觉得奇怪吗?(好吧,难道你平时写makefile都是这样写的?  )

下面我们通过实验来讲解。

做点简单修改,还是上面这份makefile,只修改编译器, 更换为交叉编译器来试试,贴代码:

target := exe

source_code = hello.c

OBJS = $(source_code:.c=.o)

$(target):$(OBJS)
    /usr/external-toolchain/bin/arm-linux-gnueabi-gcc $^ -o $@

clean:
    $(RM) $(target) $(OBJS)

功能:请问现在更换为交叉编译器,还能编译出正确的目标文件吗?  

编译观察:

令人吃惊的答案:编译报错!

解答: 

 当前截图make报错显示:不是有效格式的.o文件。 
这里的玄机是makefile的一个暗黑操作:隐式规则。 

做一下简单修改即可:使用预定义的CC 这会改变隐式规则的行为。修改为如下图所示代码:

target := exe

CC := /usr/external-toolchain/bin/arm-linux-gnueabi-gcc

source_code = hello.c

OBJS = $(source_code:.c=.o)

$(target):$(OBJS)
    $(CC) $^ -o $@
clean:
    $(RM) $(target) $(OBJS)

这样就能顺利编译出目标文件了。

虽然可以通过增加CC变量进行简单修改,达到顺利生成目标文件的目的,但是这样的makefile仍旧不被推荐使用,因为使用了有可能产生隐式规则行为的代码

这里通过使用CC变量能够顺利编译出目标文件, 本质还是使用了隐式规则,即makefile在执行make对应的规则内的命令时,发现却没有有效的汇编文件:

于是通过默认的gcc编译器尝试将本地的XX.c文件去编译为XX.o文件。

如果本地没有XX.c文件,有一个XX.p或者XX.cpp文件,make的这种隐式规则也会去将其编译为汇编文件。

如果XX.p和XX.cpp同时存在,是选择XX.p还是XX.cpp,这由make的隐式规则决定。

可以通过 make -p|grep "文件格式" 查看隐式规则的这部分相关内容:

 上面是正面讲解makefile隐式规则, 下面我侧面证明一下makefile隐式规则的存在。 
还是使用这份代码来分析。注意:我们使用的编译器是交叉编译器哦!
 
 虽然make这个makefile时报错,但还是生成了hello.o(我自己先写一个hello.c放在与makefile的同一路径下), 我们来打印一下这个hello.o的部分二进制:
 
 完成了上面的步骤,我们直接手动使用gcc编译出一个汇编文件: 
 
 观察总结:
我们这份makefile内根本就没有出现使用gcc的代码啊,我们使用的是交叉编译器啊!,竟然出现了gcc编译出来的汇编文件! 这说明什么?
这说明当前的这份makefile在make后发生了隐式规则的执行!
makefile的隐式规则是大型makefile工程应注意极力避免的,这很可能导致无法解决的bug!大家需要了解一下makefile的隐式规则,避免写下的makefile出现隐式规则的行为
 
这也是本博客最开头的例子使用gcc没暴露出问题的原因,换成交叉编译器去尝试后,就会发现问题所在。
 
总结:
 
重点是要先生成有效的依赖。本例的最佳改进是再增加一条包含%.o:%.c 的规则去得到有效的汇编文件。参考我之前的makefile博客,那里有正规的makefile的写法。

.

/************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/11678891.html