zoukankan      html  css  js  c++  java
  • 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的写法。

    .

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    如何升级 sof_to_rbf.bat 文件
    用sopc-create-header-files工具产生头文件提示找不到命令
    HTTP状态码
    HTML5与CSS3知识点总结
    uni-app input 监听回车键 输入回车确定
    原生微信小程序转换uni-app
    关闭vscode保存就自动格式化的功能
    uni-appH5(uni.chooseFile uni.chooseImage)限制图片类型
    uni-appH5(uni.chooseFile uni.chooseImage)上传图片大小限制大小
    textRNN & textCNN
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/11678891.html
Copyright © 2011-2022 走看看