• 【Linux】Makefile


    一、gcc 的缺点

    gcc -o test a.c b.c
    
    • 1

    我们具体分析:gcc -o test a.c b.c这条命令
    它们要经过下面几个步骤:

    • 1)对于a.c:执行:预处理 编译 汇编 的过程,a.c ==>xxx.s ==>xxx.o 文件。
    • 2)对于b.c:执行:预处理 编译 汇编 的过程,b.c ==>yyy.s ==>yyy.o 文件。
    • 3)最后:xxx.oyyy.o链接在一起得到一个test应用程序。

    提示:gcc -o test a.c b.c -v :加上一个**‘-v’**选项可以看到它们的处理过程。

    第一次编译 a.c 得到 xxx.o 文件,这是很合乎情理的, 执行完第一次之后,如果修改 a.c 又再次执行:gcc -o test a.c b.cb.c 又会重新编译一次,这完全没有必要,b.c 根本没有修改,直接使用第一次生成的 yyy.o 文件就可以了。

    缺点:对所有的文件都会再处理一次,即使 b.c 没有经过修改,b.c 也会重新编译一次,当文件比较少时,这没有没有什么问题,当文件非常多的时候,就会带来非常多的效率问题如果文件非常多的时候,我们,只是修改了一个文件,所用的文件就会重新处理一次,编译的时候就会等待很长时间。

    对于这些源文件,我们应该分别处理,执行:预处理 编译 汇编,先分别编译它们,最后再把它们链接在一次,比如:

    编译:

    gcc -o a.o a.c
    gcc -o b.o b.c
    
    • 1
    • 2

    链接:

    gcc -o test a.o b.o
    
    • 1

    比如:上面的例子,当我们修改a.c之后,a.c会重现编译然后再把它们链接在一起就可以了。b.c
    就不需要重新编译。



    二、Makefile的引入及规则

    makefie最基本的语法是规则,规则:

    目标 : 依赖1 依赖2 ...
    [TAB]命令
    
    • 1
    • 2

    当“依赖”比“目标”新,执行它们下面的命令。我们要把上面三个命令写成makefile规则,如下:

    //test是目标,它依赖于a.o b.o文件,一旦a.o或者b.o比test新的时候,
    //就需要执行下面的命令,重新生成test可执行程序。
    test :a.o b.o  
    	gcc -o test a.o b.o
    
    //a.o依赖于a.c,当a.c更加新的话,执行下面的命令来生成a.o	
    a.o : a.c  
    	gcc -c -o a.o a.c
    	
    //b.o依赖于b.c,当b.c更加新的话,执行下面的命令,来生成b.o
    b.o : b.c  
    	gcc -c -o b.o b.c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    a.o和a.c 来举例,分为两种情况:

    1. 如果目标文件a.o还不存在,那么a.o.time = 0 < a.c.time ,说明a.c比a.o新,会执行:
    gcc -c -o a.o a.c
    
    • 1
    1. 如果目标文件 a.o 和 依赖文件a.c 都存在,此时却重新修改了a.c。那么a.o.time < a.c.time ,说明a.c比a.o新,就会执行:
    gcc -c -o a.o a.c
    
    • 1

    优点:

    • 如果修改a.c ,我们再次执行make,它的本意是想生成第一个目标test应用程序,它需要先生成a.o,发现a.o依赖a.c(执行我们修改了a.c)发现a.c比a.o更加新,就会执行 gcc -c -o a.o

    • a.c命令来生成a.o文件。b.o依赖b.c,发现b.c并没有修改,就不会执行gcc -c -o b.o

    • b.c来重新生成b.o文件。现在a.o b.o都有了,其中的a.o比test更加新,就会执行 gcc -o test a.ob.o 来重新链接得到test可执行程序。

    所以当执行make命令时候就会执行下面两条执行:

    gcc -c -o a.o a.c
    gcc -o test a.o b.o
    
    • 1
    • 2



    Makefile的语法

    通配符

    假如一个目标文件所依赖的依赖文件很多,那样岂不是我们要写很多规则,这显然是不合乎常理的

    我们可以使用通配符,来解决这些问题。

    我们对上节程序进行修改代码如下:

    test: a.o b.o 
    	gcc -o test $^
    	
    %.o : %.c
    	gcc -c -o $@ $<
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • %.o:表示所用的.o文件

    • %.c:表示所有的.c文件

    • $@:表示目标

    • $<:表示第1个依赖文件

    • $^:表示所有依赖文件

    执行:

    make
    
    • 1

    结果:

    gcc -c -o a.o a.c
    gcc -c -o b.o b.c
    gcc -o test a.o b.o 
    
    • 1
    • 2
    • 3
  • 相关阅读:
    Springboot+vue的企业OA管理系统(有报告),Javaee项目,springboot vue前后端分离项目。
    (原创)[C#] MEF 主程序与插件加载不同版本的DLL
    Java之IO概述以及
    Lombok插件介绍、MyBatisPlus分页功能、控制台日志及删除banner
    git入门教程
    Ribbon官网及参考文档
    IDEA页面展示;Module的概念和使用
    【LeetCode:1488. 避免洪水泛滥 | 有序表 & 哈希表】
    2022年济南12行政区高新技术企业补贴政策及认定条件汇总
    Cookie和Session的工作流程是什么样的?5分钟学懂:简易用户登录(前端+后端+数据库)
  • 原文地址:https://blog.csdn.net/zsyyugong/article/details/134488300