• 【Linux】项目自动化构建工具:make/Makefile的使用



    一、背景

    1、make和makefile是什么?

    make是一个命令,是一个解释makefile中指令的命令。它可以简化编译过程所使用的命令,例如我们有一百个源文件,那我们就要敲一百条命令进行编译。所以,使用make进行自动编译会更方便。
    makefile是一个文件,其中定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

    2、为什么要使用make和makefile?

    1. 会不会写makefile,从侧面反映了一个人是否具备完成大型工程的能力。
    2. 一个工程中的源文件数不胜数,其按类型、功能、模块分别放在若干个目录中。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完成自动编 译,极大的提高了软件开发的效率。
    3. 一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。

    可见,make和makefile成为了一种在工程方面有效的编译手段。make是一条命令,makefile是一个文件,两者搭配使用,完成项目自动化构建。


    二、原理

    1、使用make和makefile

    源文件test.c中有如下一段代码:

    在这里插入图片描述
    Makefile文件:
    在这里插入图片描述
    执行make命令

    在这里插入图片描述

    我们发现只需一个make命令,便能自动执行makefile(或Makefile)中定义的命令,进而完成源文件的编译。那么makefile中如何正确定义规则呢?

    2、依赖关系和依赖方法

    makefile文件必须包含依赖关系和依赖方法。

    makefile的规则:

    目标(target):依赖文件列表(目标文件1 目标文件2……)
    gcc -o 欲生成的可执行文件 目标文件1 目标文件2……

    1. List item

    例:
    Makefile文件如下:

    在这里插入图片描述

    依赖关系
    上面的文件test ,它依赖test.o
    test.o , 它依赖 test.s
    test.s , 它依赖 test.i
    test.i , 它依赖 test.c

    依赖方法
    gcc test.* -option test.* ,就是与之对应的依赖方法

    3、具体原理

    make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,

    1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
    2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,它会找到“test”这个文件, 并把这个文件作为最终的目标文件。
    3. 如果test文件不存在,或是test所依赖的后面的test.o文件的文件修改时间要比test这个文件新(可 以用 touch 测试),那么,它就会执行后面所定义的命令来生成test这个文件。
    4. 如果test所依赖的test.o文件不存在,那么make会在当前文件中找目标为test.o文件的依赖性,如果 找到则再根据那一个规则生成test.o文件。(这有点像一个堆栈的过程)
    5. 当然,你的C文件和H文件是存在的,于是make会生成 test.o 文件,然后再用 test.o 文件生成 make的终极任务,也就是可执行文件test。
    6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
    7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错, 而对于所定义的命令的错误,或是编译不成功,make不理会。
    8. make只管文件的依赖性,即如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起, 我就不工作啦

    不能重复make:

    在这里插入图片描述

    比较时间:可执行文件的修改时间比源文件新就不能make

    在这里插入图片描述

    修改源文件的Modify Time:

    在这里插入图片描述

    4、项目清理

    • 工程是需要被清理的

    在这里插入图片描述

    • clean这种,与第一个目标文件没有直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显式要make执行。即命令——“make clean” ,以此来清除所有的目标文件,以便重新编译。

    在这里插入图片描述

    • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的
    • 如果将我们的 test 目标文件声明成伪目标,那么就可以重复make了,当然make只会执行伪目标对应的依赖方法。

    在这里插入图片描述

    在这里插入图片描述


  • 相关阅读:
    函数定义与调用
    用户登录功能
    微信小程序云开发 | 赠、删、改城市名称信息的应用实现
    产品经理考PMP有用吗?
    中高级Java程序员,你不得不掌握的基本功,挑战20k+
    好文学作品的鉴赏标准
    DDD的简单落地实现
    JS 的 splice 与 delete 介绍
    接口自动化测试框架搭建详解
    磁盘存储链式的B树与B+树
  • 原文地址:https://blog.csdn.net/m0_68609336/article/details/127991730