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的时间,因为主要是内容的更新。


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

相关文章
|
2月前
|
关系型数据库 MySQL Linux
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
406 3
|
2月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
519 3
|
2月前
|
算法 Java Linux
java制作海报五:java 后端整合 echarts 画出 折线图,项目放在linux上,echarts图上不显示中文,显示方框口口口
这篇文章介绍了如何在Java后端整合ECharts库来绘制折线图,并讨论了在Linux环境下ECharts图表中文显示问题。
48 1
|
2月前
|
Linux C++
Linux c/c++之makefile的基础使用
Linux下C/C++项目中makefile的基本使用,包括基础、进阶和高级用法,以及如何创建和使用makefile来自动化编译过程。
21 0
Linux c/c++之makefile的基础使用
|
2月前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
|
2月前
|
机器学习/深度学习 人工智能 运维
构建高效运维体系:从自动化到智能化的演进
本文探讨了如何通过自动化和智能化手段,提升IT运维效率与质量。首先介绍了自动化在简化操作、减少错误中的作用;然后阐述了智能化技术如AI在预测故障、优化资源中的应用;最后讨论了如何构建一个既自动化又智能的运维体系,以实现高效、稳定和安全的IT环境。
78 4
|
2月前
|
运维 Linux Apache
,自动化运维成为现代IT基础设施的关键部分。Puppet是一款强大的自动化运维工具
【10月更文挑战第7天】随着云计算和容器化技术的发展,自动化运维成为现代IT基础设施的关键部分。Puppet是一款强大的自动化运维工具,通过定义资源状态和关系,确保系统始终处于期望配置状态。本文介绍Puppet的基本概念、安装配置及使用示例,帮助读者快速掌握Puppet,实现高效自动化运维。
66 4
|
24天前
|
机器学习/深度学习 运维 监控
智能化运维:从自动化到AIOps的演进之路####
本文深入探讨了IT运维领域如何由传统手工操作逐步迈向高度自动化,并进一步向智能化运维(AIOps)转型的过程。不同于常规摘要仅概述内容要点,本摘要将直接引入一个核心观点:随着云计算、大数据及人工智能技术的飞速发展,智能化运维已成为提升企业IT系统稳定性与效率的关键驱动力。文章详细阐述了自动化工具的应用现状、面临的挑战以及AIOps如何通过预测性分析和智能决策支持,实现运维工作的质变,引领读者思考未来运维模式的发展趋势。 ####
|
24天前
|
机器学习/深度学习 数据采集 人工智能
智能化运维:从自动化到AIOps的演进与实践####
本文探讨了智能运维(AIOps)的崛起背景,深入分析了其核心概念、关键技术、应用场景及面临的挑战,并对比了传统IT运维模式,揭示了AIOps如何引领运维管理向更高效、智能的方向迈进。通过实际案例分析,展示了AIOps在不同行业中的应用成效,为读者提供了对未来智能运维趋势的洞察与思考。 ####
59 1
|
1月前
|
机器学习/深度学习 数据采集 人工智能
智能运维:从自动化到AIOps的演进与实践####
本文探讨了智能运维(AIOps)的兴起背景、核心组件及其在现代IT运维中的应用。通过对比传统运维模式,阐述了AIOps如何利用机器学习、大数据分析等技术,实现故障预测、根因分析、自动化修复等功能,从而提升系统稳定性和运维效率。文章还深入分析了实施AIOps面临的挑战与解决方案,并展望了其未来发展趋势。 ####