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

embedded/2024/10/22 9:39:49/

标题:[Linux] 项目自动化构建工具-make/Makefile

@水墨不写bug



目录

一、什么是make/makefile

二、make/makefile语法

补充(多文件标识):

三、make/makefile原理

四、make/makefile根据时间对文件选择操作


正文开始:

一、什么是make/makefile

        在Linux下,一切皆文件。在实现大型项目的时候,通常来说,源文件按照其模块、功能、类型放在若干的目录中,难道我们需要把这些文件一一编译再链接吗?为了提高效率,make/makefile就出现了。

        makefile可以按照我们写好的规则来完成自动化编译,一旦项目内容有修改,仅需几条指令,就可以实现整个工程的完全自动化编译,这极大对提高了软件开发的效率。

一句话定义make/makefile:make是一个指令;makefile是一个文件

        我们要做的就是在makefile中编写相关的指令,可以说是提前写好的脚本,当我们需要的时候,再执行相关的命令。 

二、make/makefile语法

        makefile怎么写?

        首先,在执行命令之前,需要表明依赖关系。什么是依赖关系?可以简单的理解为一个文件的生成需要另一个文件存在。

        然后,需要说明依赖方法。 依赖方法就是用命令表明要做的事。

表明依赖关系:在一行的开头写 目标生成文件 +:(冒号)+依赖的文件

        比如:mytest文件需要依赖test.c,则需要表明依赖关系:

mytest:test.c 

        紧接着在下一行,开始需要加一个 “tab”字符,必须是“tab”,其他的都不行。在其后加上依赖方法。这里的依赖方法就是用test.c生成mytest的指令:

gcc -o mytest test.c

 现在,我们已经完成了生成项目,接下来还需要清理项目。清理项目仍然需要用到依赖关系。

        我们一般把清理项目的指令设为clean,由于clean不依赖任何文件,所以:(冒号)的右侧不写任何文件:

clean:

        同样的,在下一行开头“tab”,其后加上依赖方法:

rm -r mytest

         到这里,我们就完整实现了一个简单的makefile。


整体的makefile如下:

mytest:test.cgcc -o mytest test.c
clean:rm -r mytest

        在完整实现makefile之后,我们就可以在含有makefile的目录下使用make命令:

make

        make命令会根据依赖关系的依赖方法,从而令makefile文件的内容而生成mytest;

        如果想要清理mytest,使用命令:

make clean

        make clean会根据 依赖方法,清除mytest。

补充(多文件标识):

        如果一个文件有多个依赖文件,则在“:”后面以此写上文件名即可,文件之间用一个空格分开。而在表明依赖方法的时候,就不必再一个一个写文件名称了,可以用简写标识:

$@   :标识 “:”左侧的目标文件

$^     :标识“:”右侧的所有依赖文件

于是,针对多依赖文件的依赖关系就可以这样写:

gcc -o $@ $^

三、make/makefile原理

        1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。(首字符不区分大小写)

        2. 如果找到,它会找文件中的第一个目标文件(target),一般来说,我们会把目标文件(最终文件)放在第一个位置,然后倒推生成目标文件需要依赖的其他文件,一直推到已存在的文件为止。

比如下面这个makefile例子:

my_test:my_test.og++ -o my_test my_test.o
my_test.o:my_test.sg++ -c my_test.s -o my_test.o
my_test.s:my_test.ig++ -S my_test.i -o my_test.s
my_test.i:test.cppg++ -E test.cpp -o my_test.i

       我们首先发现目标文件my_test,其依赖文件为my_test.o,而my_test.o又依赖my_test.s,但是还没有推到已知的test.cpp,所以要继续寻找;my_test.s依赖my_test.i,而my_test.i就可以由test.cpp生成,test.cpp是已经存在的文件,所以推导结束,并且没有推导过程中的逻辑中断,所以上述的makefile文件是正确的。

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

        这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。(这有点像一个堆栈的过程)

四、make/makefile根据时间对文件选择操作

        当我们在一个项目中make一次之后,再次make,会发现出现这样的错误:

        这个名字叫做“processbar”的项目已经是最新的了。想要理解为什么会发生这样的错误,我们需要理解每一个文件都有三个时间:

Access time

Modify time

Change time

        这三个时间分别是:最后一次访问文件的时间, 最后一次修改文件内容的时间,最后一次修改文件属性的时间。

访问文件:这比较好理解,比如读取文件,打开文件看文件的内容等;

修改文件:

        修改文件分为修改文件的内容修改文件的属性。我们知道,文件有内容(就是我们通常写入的数据)和属性(比如文件的大小,创建时间,文件类型,所有者等)。

        make会根据项目最终文件和源文件的最近修改时间来决定是否要重新编译生成项目文件:

        如果项目最终文件的修改时间比源文件的时间晚,那么说明源文件在编译生成项目文件之后没有修改过,这时make就会出现上述的报错;如果项目最终文件的修改时间比源文件早,那么说明源文件在编译生成项目文件之后源文件修改过,这时make就可以重新编译生成项目文件。

        如果想要不受上述的时间的限制,从而实现在每次make之后都重新编译生成项目文件,我们就需要定义伪目标

        具体的操作为在表明依赖关系之前用 ".PHONY"修饰目标文件。

        一般而言,我们一般不会把最终项目定义为伪目标,一般选择把clean定义为伪目标,这样一来,在每次想要clean的时候,总是可以成功执行clean:

修改后的makefile:

processbar:processbar.c main.c                                                                                      gcc -o $@ $^
.PHONY:clean
clean:rm -f processbar

完~

未经作者同意禁止转载


http://www.ppmy.cn/embedded/108374.html

相关文章

CSS学习11--版心和布局流程以及几种分布的例子

版心和布局流程 一、版心二、布局流程三、一列固定宽度且居中四、两列左窄右宽五、通栏平均分布型 一、版心 版心:是指网页主题内容所在的区域。一般在浏览器窗口水平居中位置,常见的宽度值为960px、980px、1000px、1200px等。 二、布局流程 为了提高…

溜狗牵绳行为检测-目标检测数据集(包括VOC格式、YOLO格式)

溜狗牵绳行为检测-目标检测数据集(包括VOC格式、YOLO格式) 数据集: 链接:https://pan.baidu.com/s/1CwLEAKcdlh9hbcBNh_Awdw?pwdiu6b 提取码:iu6b数据集信息介绍: 共有 1980 张图像和一一对应的标注文件…

五,Spring Boot中的 Spring initializr 的使用

五,Spring Boot中的 Spring initializr 的使用 文章目录 五,Spring Boot中的 Spring initializr 的使用1. 方式1:IDEA创建2. 方式2:start.spring.io 创建3. 注意事项和细节4. 最后: 需要:使用 Spring initi…

「大数据分析」图形可视化,如何选择大数据可视化图形?

​图形可视化技术,在大数据分析中,是一个非常重要的关键部分。我们前期通过数据获取,数据处理,数据分析,得出结果,这些过程都是比较抽象的。如果是非数据分析专业人员,很难清楚我们这些工作&…

图文解析保姆级教程: IDEA里面创建SpringBoot工程、SpringBoot项目的运行和测试、实现浏览器返回字符串

文章目录 一、创建SpringBoot工程(需要联网)二、 定义请求处理类三、运行测试 此教程摘选自我的笔记:黑马JavaWeb开发笔记13——Springboot入门(创建、运行&测试项目)、Http协议(请求&响应协议&…

finalshell 4.5.x在m1mac闪退

使用过程中会出现突然闪退,尤其在定位生产打开一堆窗口的情况下,绝绝子 闪退崩溃日志: Thread 116 Crashed:: Java: pool-4-thread-28 0 libsystem_kernel.dylib 0x18e926600 __pthread_kill 8 1 libsystem_pthread.dyl…

【Dash】feffery_antd_componenet 中的 AntdSpace

一、feffery_antd_componenet 中的 AntdSpace feffery_antd_components(简称fac)中的AntdSpace组件是一个基于Ant Design的Dash第三方组件,它用于在水平或垂直方向上放置多个元素,并提供元素之间的间距。以下是AntdSpace组件的一…

C++常见异常汇总(二): undefined reference to

文章目录 1、undefined reference to A2、undefined reference to vtable2.1 模版函数定义方案1: 定义与实现均一起定义在头文件中2.2 模版函数定义方案2: 定义的同一个文件中,显示声明具体类型 3、multiple definition of 1、undefined refe…