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

简介: Linux项目自动化构建工具-make/Makefile

1.背景


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

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中, makefile 定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作

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

make 是一个命令工具,是一个解释 makefile 中指令的命令工具,一般来说,大多数的 IDE 都有这个命 令,比如:Delphi 的 make , Visual C++ 的 nmake , Linux 下 GNU 的 make 。可见, makefile 都成为了一 种在工程方面的编译方法。

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

如果在vs中写程序的时候,有100个源文件,那么我们是要把每个.c文件或者.cpp文件经过预处理,编译,汇编编译成.o文件 ,然后再把这些.o文件链接起来,生成1个或者多个可执行程序。那么这些事情是编译器帮我们做的,那么在linux中就需要我们手动去做了,在linux中自动化构建项目的工具就是make/makefile。


2.理解

那么make是什么呢?makefile又是什么呢?


make是一个命令,makefile是一个文件。make是系统为我们提供的一个命令,而makefile是需要用户在当前工作目录下自己写的一个文件。makefile是保存依赖关系和目标的一个东西。


3.依赖关系

如果我们要编译一个mytest.c的文件,首先我们要创建一个名为makefile的文件,名字必须是Makefile/makefile,那么第一行需要我们写上我们需要创建的可执行程序的名称以及这个目标文件所需要的依赖文件名称,在下面这个例子中我们想创建一个名为mytest的可执行程序,那么我需要一个名叫mytest.c的源文件,这就是依赖关系。


4.依赖方法

第二行就是依赖方法,使用gcc编译mytest.c这个源文件,生成一个名叫mytest.c的目标文件,这一步骤可以参考我的这一篇博客http://t.csdnimg.cn/yAdih


那么这两步就是依赖关系和依赖方法。


e5dc79769345451dad503b1c7097f9ae.png 然后我们退出之后,在命令行使用make这个命令,会自动进行编译,生成mytest这个可执行程序。

b2cbc3f489384c30a779205f69a28307.png

05e9eef25bb540078e4936916d22efd0.png


5.原理

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


1. make 会在当前目录下找名字叫 “Makefile” 或 “makefile” 的文件。

2. 如果找到,它会找文件中的第一个目标文件( target ),在上面的例子中,他会找到 “hello” 这个文件, 并把这个文件作为最终的目标文件。

3. 如果 hello 文件不存在,或是 hello 所依赖的后面的 hello.o 文件的文件修改时间要比 hello 这个文件新(可 以用 touch 测试),那么,他就会执行后面所定义的命令来生成 hello 这个文件。

4. 如果 hello 所依赖的 hello.o 文件不存在,那么 make 会在当前文件中找目标为 hello.o 文件的依赖性,如果 找到则再根据那一个规则生成hello.o 文件。(这有点像一个堆栈的过程)

5. 当然,你的 C 文件和 H 文件是存在的啦,于是 make 会生成 hello.o 文件,然后再用 hello.o 文件声明 make的终极任务,也就是执行文件 hello 了。

6. 这就是整个 make 的依赖性, make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文 件。

7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么 make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make 根本不理。

8. make 只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

6.项目清理

此时我将这个程序运行起来,就可以直接运行了,因为这是一个编译好的可执行程序,但是这是一个临时文件,这就意味着我们也需要一个方法能够清理掉这个文件。

5bbc1015f02e45718189bd6a0e3c0cdc.png

那么我们就需要在makefile里面定义一个clean,它的依赖关系为空,因为不需要依赖任何文件,依赖方法如下,也就是删除mytest这个临时文件,-f的意思是强制删除,就不会询问了。


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

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

8d2a9ec53e374adea0019bb958469125.png

在命令行中使用make clean这个命令就可以删掉了.

4e6243e8c7484f35bb667231a7c15d6c.png

需要注意的是在写完makefile之后,使用make这个命令默认执行的是第一行的代码,因为是从上到下扫描makefile这个文件的,如果我们把clean写在第一行,那么make就是删除命令,想执行gcc编译命令,那么就需要make mytest才行。并且make命令默认只执行一个依赖方法。


大家注意看,当我们已经形成可执行程序mytest后,如果再次使用make命令,那么系统会提示我们当前文件已经是最新的了。那么make/makefile是如何直到可执行程序是最新的呢?其实是通过对比时间来确定的,只要可执行程序的最新修改时间比源文件的修改时间新,就说明它是最新的。

0307fff2ac4b4a0887280e79149a76dc.png

7.文件时间

使用stat这个指令就能看到一个文件的三个时间,modify是修改的时间,change是改变的时间,当我们再次在mytest.c这个文件中写入内容是,我们会发现,modify和change都会改变,这是为什么呢?此时我们要知道的是文件=内容+属性,modify是内容的修改时间,change是属性的修改时间,那么属性包括文件的大小,拥有者,所属组.....其实ll这条指令查看到的所有内容都是文件的属性,那么为什么改变内容会导致change发生改变呢?因为内容的改变会导致文件的大小发生变化,那么就意味着属性发生了改变。


结论:通常内容和属性是一起改变的,而属性是单独改变的。


那么access是文件的访问时间,当我们使用cat命令的时候,就会修改access的时间,但是当我们短时间内多次的访问一个文件的话,它的access是不会一直改变的。

38f4a719c8364fcbb3317895bdb14173.png

那么想知道一个可执行程序是否是最新的,对比源文件和可执行程序的时间是哪个时间呢?对比的时间其实是modify的时间,因为主要是内容的更新。


今天的分享到这里就结束了,感谢大家的阅读!  

相关文章
|
18天前
|
测试技术
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
本文介绍了如何使用Pytest和Allure生成自动化测试报告。通过安装allure-pytest和配置环境,可以生成包含用例描述、步骤、等级等详细信息的美观报告。文章还提供了代码示例和运行指南,以及重构项目时的注意事项。
80 1
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
|
18天前
|
测试技术 Python
自动化测试项目学习笔记(四):Pytest介绍和使用
本文是关于自动化测试框架Pytest的介绍和使用。Pytest是一个功能丰富的Python测试工具,支持参数化、多种测试类型,并拥有众多第三方插件。文章讲解了Pytest的编写规则、命令行参数、执行测试、参数化处理以及如何使用fixture实现测试用例间的调用。此外,还提供了pytest.ini配置文件示例。
17 2
|
18天前
|
测试技术 Python
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
本文主要介绍了自动化测试中setup、teardown、断言方法的使用,以及unittest框架中setUp、tearDown、setUpClass和tearDownClass的区别和应用。
40 0
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
|
3月前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
45 8
|
2月前
|
安全 Linux 测试技术
Kali Linux预装的自动化渗透测试工具
Kali Linux预装的自动化渗透测试工具
119 2
|
3月前
|
Ubuntu Linux 持续交付
在Linux中,如何在Linux中使用Ansible进行自动化部署?
在Linux中,如何在Linux中使用Ansible进行自动化部署?
|
3月前
|
运维 Linux 持续交付
在Linux中,如何进行配置管理和自动化部署?
在Linux中,如何进行配置管理和自动化部署?
|
3月前
|
存储 监控 Linux
|
3月前
|
存储 Linux 测试技术
在Linux中,如何使用expect进行自动化交互式应用程序测试?
在Linux中,如何使用expect进行自动化交互式应用程序测试?
|
3月前
|
jenkins Linux 持续交付
在Linux中,如何使用Jenkins和Ansible进行虚拟化环境的自动化和持续集成/持续部署(CI/CD)?
在Linux中,如何使用Jenkins和Ansible进行虚拟化环境的自动化和持续集成/持续部署(CI/CD)?