• Linux make/Makefile详解


    会不会写makefile,从侧面说明了一个人是否具备完成大型工程的能力。

    一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作。(虽然目前还没有接触过大型项目,但其实这段话是可以理解的。)

    makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发的效率。

    make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命 令

    make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。


    好了好了,不CV了


     起初存在这些文件,下面的makefile的作用是自动化构建项目。 main.c test.c test.h 构建出test可执行程序。  yzl.c 构建出yzl可执行程序

    1. 1 test: test.o main.o
    2. 2 gcc test.o main.o -o test
    3. 3 yzl: yzl.o
    4. 4 gcc yzl.o -o yzl
    5. 5 test.o: test.c
    6. 6 gcc -c test.c -o test.o
    7. 7 main.o: main.s
    8. 8 gcc -c main.s -o main.o
    9. 9 main.s: main.i
    10. 10 gcc -S main.i -o main.s
    11. 11 main.i: main.c
    12. 12 gcc -E main.c -o main.i
    13. 13 yzl.o: yzl.c
    14. 14 gcc -c yzl.c -o yzl.o
    15. 15
    16. 16 .PHONY: clean
    17. 17 clean:
    18. 18 rm -f main.i main.s main.o test.o test
    19. 19
    20. 20 .PHONY: ll
    21. 21 ll:
    22. 22 ls
    23. 23
    24. 24 .PHONY: cleanyzl
    25. 25 cleanyzl:
    26. 26 rm -f yzl yzl.o

    依赖关系,依赖方法

    编写makefile。两个核心是依赖关系和依赖方法

    依赖关系:为了生成某个目标文件,此目标文件依赖于其他文件。比如上图makefile中的生成test依赖于test.o main.o 而test.o又依赖于test.c  依赖方法:生成test目标可执行文件,依赖关系是依赖于test.o 和main.o 而依赖方法就是下面的命令行,表示执行此命令(方法)之后即可生成目标文件。

    在makefile中,依赖关系是层层依赖的,比如test依赖于test.o main.o ,如下test.o 依赖于test.c main.o依赖于main.s main.s 依赖于main.i   make处理makefile时,默认进行第一个依赖关系和依赖方法。 也就是只有main.o 和 test.o不存在时,才会往下查找是否有某个依赖关系的目标文件是main.o 和 test.o 。所以编写makefile时,一定要从后往前,以程序形成的逆序来编写makefile。
    所以,第二个依赖关系yzl : yzl.o  不主动执行的情况下,是无法自动自动进行的,因为第一个依赖关系中不依赖于yzl文件。所以,如果想生成yzl,比如主动执行make :  make yzl

    我们现在知道了make指令默认从makefile的第一个依赖关系开始,而重复进行make时,

    make失效时,依据的是什么。

    就会出现如上情况,make: 'test' is up to date  意思是此时的目标文件test已经是最新的了,再次构建项目是没有意义的,那么,make是如何知道此时test是最新的呢?其实是依据目标文件test和其依赖的文件的修改时间,来判断是否需要进行此次make。 当所有的依赖文件的修改时间都比test的时间早时,表示test目标文件是最新的,也就没有必要进行make操作。一旦修改其中任何一个依赖文件,下一次的make就会生效。

    make clean

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

    但是一般clean这种的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被 执行的。

    总是被执行:每次make clean时,不会按照文件的修改时间来判断此时make clean是否执行,而是每次make clean都生效,这就是总是被执行。

    再比如上方的yzl目标文件,因为它不是第一个依赖关系依赖的文件,所以它不会自动执行,我们可以make yzl 而执行这个依赖关系。 make cleanyzl即执行清理yzl相关文件的工作。

    .PHONY

    1. 如上的clean声明为.PHONY 除了让其总是被执行,还有一个原因是.PHONY是一个伪目标,可以防止在Makefile中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突。也就是如果工作目录下存在clean文件,那么make就会不执行此依赖关系。而.PHONY声明clean后可以理解为clean并不是一个目标文件,只是一个操作。

    2. 目标确实是一个文件,但是目标文件的构建很复杂,其构建是通过其他方式完成的,在当前makefile中没有包含其完整的依赖关系和构建方式。默认方式下makefile检查依赖后可能不执行目标的构建命令。这时使用.PHONY表示目标不是当前makefile直接构建的,不要通过检查依赖来决定是否执行命令,必须执行其构建命令来完成构建。

    需要注意的是虽然.PHONY目标不通过依赖来决定目标是否要执行命令,但是还是会检查依赖的,依赖的文件不存在时仍然会尝试构建或报错。

    总结一下:.PHONY目标一定会执行构建命令。一般用于目标非实体文件,或目标文件不受makefile管理、依赖关系不完整的情况。

  • 相关阅读:
    centos7下安装elasticsearch7.8.1并配置远程连接
    数据分析:数据预处理流程及方法
    离谱的 CSS!从表盘刻度到艺术剪纸
    github desktop 设置 git 项目调用(链接、引用)外部 repo
    【Shell学习笔记】Bash的模式扩展
    电脑播放超声波
    Vue3+elementplus搭建通用管理系统实例八:通用表格实现中
    找不到msvcp110.dll是什么意思?总结msvcp110.dll丢失修复方法分享
    基于车联网的车辆编队标准现状及展望
    HALCON联合C#机械手视觉定位——界面代码
  • 原文地址:https://blog.csdn.net/i777777777777777/article/details/126078765