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

news/2024/11/15 5:47:37/

目录

背景

实例代码

依赖关系

依赖方法

原理

项目清理

可重复执行的依据


 

背景

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

实例代码

C代码
  myfile:myfile.ogcc -o myfile myfile.omyfile.o:myfile.sgcc -c  -o myfile.o myfile.smyfile.s:myfile.igcc -S -o myfile.s myfile.imyfile.i:myfile.cgcc -E -o myfile.i myfile.c         
  myfile:myfile.cgcc -o myfile myfile.c

 

依赖关系

上面的文件
myfile ,它依赖 myfile.o
myfile.o , 它依赖 myfile.s
myfile.s , 它依赖 myfile.i
myfile.i , 它依赖 myfile.c

依赖方法

gcc myfile.* -option myfile.* ,就是与之对应的依赖关系

原理

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

项目清理

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

       

  •          clean 后指令会被执行,也可以执行echo等指令

 

        
     
  •         调换一下顺序:make 执行第一part的指令
  1 clean:2   rm -f myfile.i myfile.s myfile.o myfile3 4 myfile:myfile.o5   gcc -o myfile myfile.o                                                                                            6 myfile.o:myfile.s7   gcc -c -o myfile.o myfile.s8 myfile.s:myfile.i9   gcc -S -o myfile.s myfile.i10 myfile.i:myfile.c11   gcc -E -o myfile.i myfile.c

 

 

       但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。 可以将我们的 myfile 目标文件声明成伪目标,测试一下
  •         未加.PHONY

 

  •         加了.PHONY

    1 

  1 myfile:myfile.o2   gcc -o myfile myfile.o3 myfile.o:myfile.s4   gcc -c -o myfile.o myfile.s5 myfile.s:myfile.i6   gcc -S -o myfile.s myfile.i7 myfile.i:myfile.c8   gcc -E -o myfile.i myfile.c9 10 11 .PHONY:clean12 clean: 13   rm -f myfile.i myfile.s myfile.o myfile 

 2

 

  1 .PHONY:myfile2 myfile:myfile.c3   gcc -o myfile myfile.c4 5 .PHONY:clean6 clean:7   rm -f myfile 

         一般只clean部分总是执行

可重复执行的依据

touch已存在的文件,更新其时间 

[root@VM-12-17-centos lesson7]# vim myfile.c
[root@VM-12-17-centos lesson7]# make
gcc -o myfile myfile.c
[root@VM-12-17-centos lesson7]# ll
total 20
-rw-r--r-- 1 root root  359 Jan 12 21:59 Makefile
-rwxr-xr-x 1 root root 8360 Jan 12 22:01 myfile
-rw-r--r-- 1 root root  100 Jan 12 22:01 myfile.c
[root@VM-12-17-centos lesson7]# stat myfileFile: ‘myfile’Size: 8360      	Blocks: 24         IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 790145      Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-01-12 22:01:58.304080944 +0800
Modify: 2023-01-12 22:01:58.002078678 +0800
Change: 2023-01-12 22:01:58.002078678 +0800Birth: -
[root@VM-12-17-centos lesson7]# stat myfile.cFile: ‘myfile.c’Size: 100       	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 790102      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-01-12 22:01:52.357036316 +0800
Modify: 2023-01-12 22:01:52.355036301 +0800
Change: 2023-01-12 22:01:52.355036301 +0800Birth: -
[root@VM-12-17-centos lesson7]# touch myfile.c
[root@VM-12-17-centos lesson7]# stat myfile.cFile: ‘myfile.c’Size: 100       	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 790102      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-01-12 22:02:42.314411188 +0800
Modify: 2023-01-12 22:02:40.966401073 +0800
Change: 2023-01-12 22:02:40.966401073 +0800Birth: -


http://www.ppmy.cn/news/11555.html

相关文章

华为交换机、路由器设备批量配置端口方法步骤

华为交换机、路由器批量配置端口方法步骤 在现实工作中,如果要对多个端口做同样的配置,每个接口逐一进行相同的配置,很容易出错,而且造成大量重复工作。 配置端口组功能就可以解决这个问题啦。 你只需要将这些以太网接口加入同一…

RocketMQ部署详解

上篇文章已经介绍过RocketMQ,这里就不再写了,下面直入主题,介绍RocketMQ安装 因为RocketMQ是基于Java开发的,所以安装RocketMQ之前,我们需要先安装JDK,因为服务器一般采用Linux,所以本文只介绍基…

【C/C++】静态顺序表详解(附完整源码)

本章内容 1.什么是线性表 2.什么是顺序表 3.静态顺序表结构的定义 4.静态顺序表的函数接口实现 5.静态顺序表的问题及思考 1.什么是线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&…

Mybatis-plus(上)

1.什么是mybatis-plus升级版的mybatis,目的是让mybatis更易于使用, 用官方的话说“为简化而生”官网:https://baomidou.com/初体验按照官网中的快速开始即可1.准备数据库脚本数据库 Schema 脚本如下: DROP TABLE IF EXISTS user; …

pytest-pytest插件之测试覆盖率pytest-cov

简介 测试覆盖率是指项目代码被测试用例覆盖的百分比,使用pytest-cov插件可以统计测试覆盖率 添加链接描述 安装插件pytest-cov pip install pytest-cov用法 基本用法 –cov的参数是要统计代码覆盖率的源码,我将源码放在mysrc中,test_s…

Kotlin的lateinit和by lazy的区别

一、lateinit1.lateinit的使用由于kotlin有严格的语法要求变量需要声明是否可以为null,但由于在实际的业务场景中,这个变量必须在某些时候才能做初始化操作,并且这个变量肯定不为null,如果为null,就是逻辑有问题了。这…

xilinx srio ip学习笔记之再识srio

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 xilinx srio ip学习笔记之再识srio前言SRIO的理解IP核的理解前言 这段时间,随着对SRIO的学习,又有了更深的一点认识,不像一开始这么慌张了…

nodejs——MongoDB模块

MongoDB 是一个面向文档,schema 无关(schema-less)的数据库,它非常适合于 Node.js 应用以及云端部署。 与 MySQL 及 PostgreSQL 是根据固定的结构设计(schema)将数据存储在表中不同,MongoDB 可以…