• Linux项目自动化构建工具-make/Makefile


    背景

    ·会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
    ·一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
    ·makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
    ·make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
    ·make是一条
    命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

    实例代码

    首先创立一个Makefile的文件

    1. [yyh@ecs-86081 lesson2]$ touch Makefile
    2. [yyh@ecs-86081 lesson2]$ ll
    3. total 8
    4. -rw-rw-r-- 1 yyh yyh 0 Jul 28 23:13 Makefile
    5. -rw-rw-r-- 1 yyh yyh 281 Jul 28 22:14 mytest.c
    6. -rw-rw-r-- 1 yyh yyh 90 Jul 27 23:04 mytest.cpp

    然后编写Makefile文件,用以表明依赖关系和依赖方法

    也可以像这样编写Makefile:

    1. [yyh@ecs-86081 lesson2]$ cat Makefile
    2. mytest:mytest.c
    3. gcc -o $@ $^

    其中$@表示的是目标生成文件,$^表示的是参与编译的源文件

    直接使用make命令就可直接为我们生成可执行文件mytest

    1. [yyh@ecs-86081 lesson2]$ make
    2. gcc mytest.c -o mytest -std=c99
    3. [yyh@ecs-86081 lesson2]$ ll
    4. total 24
    5. -rw-rw-r-- 1 yyh yyh 50 Jul 28 23:16 Makefile
    6. -rwxrwxr-x 1 yyh yyh 8392 Jul 28 23:16 mytest
    7. -rw-rw-r-- 1 yyh yyh 281 Jul 28 22:14 mytest.c
    8. -rw-rw-r-- 1 yyh yyh 90 Jul 27 23:04 mytest.cpp

    Makefile实际就是表明依赖关系和依赖方法。比如举一个生活中非常形象的例子:到月底了,给家里人打电话“爸,我是你的儿子,月底了,没钱了,给我打一千块钱。”这句话里,首先表明了依赖关系,没钱了要钱表明了依赖方法。这就说明了,只有依赖关系和依赖方法共同作用才能达成某种目的

    依赖关系(文件和文件之间的相互依赖关系)

    1. 1 mytest:mytest.o
    2. 2 gcc -o mytest mytest.o
    3. 3 mycode.o:mytest.s
    4. 4 gcc -c mytest.s -o mytest.o
    5. 5 mycode.s:mytest.i
    6. 6 gcc -S mytest.i -o mytest.s
    7. 7 mycode.i:mytest.c
    8. 8 gcc -E mytest.c -o mytest.i
    9. 9 .PHONY:clean
    10. 10 clean:
    11. 11 rm -f mytest mytest.i mytest.s mytest.o

    原理

    ·make是如何工作的?在默认的方式下,也就是我们只输入make命令即可运行成功。那么,

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

    项目清理

    ·工程是需要被清理的

     

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

    1. [yyh@ecs-86081 lesson2]$ ll
    2. total 24
    3. -rw-rw-r-- 1 yyh yyh 50 Jul 28 23:18 Makefile
    4. -rwxrwxr-x 1 yyh yyh 8392 Jul 28 23:16 mytest
    5. -rw-rw-r-- 1 yyh yyh 281 Jul 28 22:14 mytest.c
    6. -rw-rw-r-- 1 yyh yyh 90 Jul 27 23:04 mytest.cpp
    7. [yyh@ecs-86081 lesson2]$ make clean
    8. rm -f mytest
    9. [yyh@ecs-86081 lesson2]$ ll
    10. total 12
    11. -rw-rw-r-- 1 yyh yyh 83 Jul 28 23:20 Makefile
    12. -rw-rw-r-- 1 yyh yyh 281 Jul 28 22:14 mytest.c
    13. -rw-rw-r-- 1 yyh yyh 90 Jul 27 23:04 mytest.cpp

    执行上面的"make clean"命令过后可执行文件mytest就被清除了
    ·但是一般我们这种clean的目标文件,我们将它设置为伪目标用 .PHONY 修饰,伪目标的特性是,总是被执行的

  • 相关阅读:
    20220701
    在不同操作系统上如何安装符号表提取工具(eu-strip)
    Vue | Vue 核心 +
    QT事件说明
    永热爱 敢向前 | Paraverse平行云的2023 年终总结
    数字IC笔试千题解--单选题篇(二)
    数据结构 - 逻辑结构和物理结构
    【算法竞赛01】leetcode第363场周赛
    北京建工携手法大大,电子签名赋能智能绿色建筑
    我的docker随笔38:用 registry 搭建私有仓库
  • 原文地址:https://blog.csdn.net/weixin_56054625/article/details/126045910