• 手把手教你如何编写一个Makefile文件


    一、概念理解(彩蛋藏在某个地方)

    1.1 什么是Makefile?

    • C语言中,我们使用visual studio开发软件时候,写程序开始时候都会创建一个project项目文件,然后在文件里面编译 .h 和 .c 的文件。
    • 在Linux中,有一个叫make的东西,就相当于C语言的集成开发环境,我们只需要在make里面创建文件,写代码,make会帮我们管理这些文件。
    • 不过我们创建的项目不叫project,而是称为Makefile,打开一个make源程序包,发现很多Makefile的文件,说明里面有很多的项目。
    • 在源程序包里面,也有名为makefile的文件(m是小写),两个命名同时存在,这是合理的,在开发一个项目的时候,工程师一般都会命名为Makefile然后打包交给用户,用户觉得某个Makefile需要改动,用户改动后或者新建后的项目定义为makefile,并且在运行时候,先执行makefile,再执行Makefile文件。

    【文章福利】小编在群文件上传了一些个人觉得比较好得学习书籍、视频资料,有需要的可以进群【977878001】领取!!!额外赠送一份价值699的内核资料包(含视频教程、电子书、实战项目及代码)

    内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料

    学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

    1.2 为何使用Makefile?

    上面提到需要将我们写的大量项目文件管理起来,这里具体讲讲:

    这个树形图展示了一个项目中的层级关系,如果我们需要变动3号文件,会发现,牵一发而动全身,改动一个被迫需要改动一堆,为了解放我们,make中编写Makefile就不再需要考虑这些,你把每个文件的依赖关系以指令的形式说明清楚并且保存下来,改动一个即可,会自动帮你修改关联到的其他文件。

    二、实战代码演示与讲解

    2.1 没有makefile的项目是怎么创建运行的

    2.1.1 创建文件

    touch main.c tool1.c tool1.h  tool2.c tool2.h 

    使用指令"touch"时,如果指定的文件不存在,则将创建一个新的空白文件。例如,在当前目录下,使用该指令创建一个空白文件"file",输入如下命令:

    $ touch file #创建一个名为“file”的新的空白文件**

    2.1.2 查看创建的文件

    要有优秀的编程习惯,创建完了之后看一下时候创建成功

    ls
    ls 查看当前目录下的文件,发现成功创建了5个文件。

    2.1.3 给创建的文件放一点内容

    vim * -p
    vim就是进入文本编辑的命令,按键 i 进入编辑模式,Esc退出编辑模式,:wq 保存退出到终端界面
    1. "tool1.h"
    2. #ifndef TOOL1_H__
    3. #define TOOL1_H__
    4. # 声明函数
    5. void mytoo1(void);
    6. #endif

    1. "tool1.c"
    2. #include
    3. #incldue "tool1.h"
    4. # 定义函数
    5. void mytool1(void)
    6. {
    7. printf("tool1 print\n");
    8. }

    只需要稍微修改一下 tool2.h 和 tool2.c 的文件就好啦。

    1. "tool2.h"
    2. #ifndef TOOL2_H__
    3. #define TOOL2_H__
    4. # 声明函数
    5. void mytoo2(void);
    6. #endif

    1. "tool1.c"
    2. #include
    3. #incldue "tool2.h"
    4. # 定义函数
    5. void mytool2(void)
    6. {
    7. printf("tool2 print\n");
    8. }

    现在还剩下一个主函数main了,测试代码如下

    1. #include
    2. #include "tool1.h"
    3. #include "tool2.h"
    4. int main(){
    5. mytool1();
    6. mytool2();
    7. return 0;
    8. }

    :wa退出编辑模式(保存所有打开的文件)

    2.1.4 编译运行

    2.2 有makefile的项目如何创建运行

    makeile教学视频

    讲前小科普:

    2.2.1 删掉自动生成的a.out文件

    rm a.out

    2.2.2 创建makefile

    vim进入编辑模式,系统检测没有名为makefile的文件,会自动创建。

    如果自己想自定义一个其他名字,比如makefilebuff-demo,可能在make操作时候会有影响。下面会讲。

    接下来的写依赖关系的时候,你可能会疑惑gcc命令的一些参数,nb我已经预判到了,我的这篇文章可以帮你解决一小部分疑惑
    Linux——gcc -c -o 等参数的解释.
    1. # 自定义依赖关系,源文件(后缀为.c)经过编译汇编生成目标文件(后缀为.o)
    2. # 目标文件执行生成可执行文件(类似与mytool
    3. mytool:main.o tool1.o tool2.o
    4. # 写gcc命令时候,前面要tab按键一下
    5. # 不写-o参数,生成默认的可执行文件名为a.out,这里我们修改为mytool
    6. gcc main.o tool1.o tool2.0 -o mytool
    7. main.o:main.c
    8. #-Wall 可以看到所有的警告
    9. #-g 可以调试
    10. #-c 只允许执行到汇编步骤,不允许链接。
    11. gcc main.c -c -Wall -g -o main.o
    12. tool1.o:tool1.c
    13. gcc main.c -c -Wall -g -o tool1.o
    14. tool2.o:tool2.c
    15. gcc main.c -c -Wall -g -o tool2.o

    保存退出,然后查看一下目录(好习惯),发现有一个makefile的文件啦。

    2.2.3 执行makefile文件

    直接使用make命令

    科普:如果你的文件名字不是makefile,而是makefilebuff-demo这样自定义的,那么需要这么操作

    make -f makefilebuff-demo
    make 命令可以通过 -f 执行使用的makefile。
    如果在没有使用 -f 指定的情况下,会按照下面的顺序执行。
    GNUmakefile, makefile 和 Makefile

    2.2.4 查看目录并运行可执行文件

    可以看到可执行文件已经是其他颜色了,颜色不同代表这文件权限不同。

    (./文件名)运行!

    第一阶段就可以完结撒花啦!!!!!

    实际上,这里的makefile文件的信息写的并不是十分的规范,有的东西还没有写,有的写的太麻烦。接下来逐步完善一下

    三、代码优化

    3.1 添加clean信息

    _实际上,正如上面介绍的流程我们已经基本处理完了项目,这个时候我修改了某文件代码保存退出后,就需要重新的执行make指令,但是跟第一次不同的是,这次make指令执行后界面如图,不再展示依赖和被依赖关系。

    _但是我们还是希望每次执行make,都展示一下依赖和被依赖关系,需要添加 clean 信息

    1. clean:
    2. # rm 删除指令,删除所有后缀为.o文件,删除mytool这个可执行文件
    3. # -rf 强制删除并且递归删除,否则的话会一直询问我们是否需要删除
    4. rm *.o mytool -rf

    执行make clean,发现出现了依赖和被依赖的关系

    3.2 简化makefile信息

    3.2.1 简化第一版

    1. # OBJS 代替 依赖文件
    2. # CC 代替 gcc
    3. # CFLAGS 代替 编译命令
    4. OBJS=main.o tool1.o tool2.o
    5. CC=gcc
    6. CFLAGS=-c -Wall -g
    7. mytool:$(OBJS)
    8. $(CC) $(OBJS) -o mytool
    9. main.o:main.c
    10. $(CC) main.c $(CFLAGS) -o main.o
    11. tool1.o:tool1.c
    12. $(CC) main.c $(CFLAGS) -o tool1.o
    13. tool2.o:tool2.c
    14. $(CC) main.c $(CFLAGS) -o tool2.o
    15. clean:
    16. rm *.o mytool -rf

    3.2.2 简化第二版

    1. # $^ 代替 上面的指令
    2. # RM 代替 rm -f
    3. # $@ 代替 目标文件
    4. OBJS=main.o tool1.o tool2.o
    5. CC=gcc
    6. CFLAGS=-c -Wall -g
    7. mytool:$(OBJS)
    8. $(CC) $^ -o mytool
    9. main.o:main.c
    10. $(CC) $^ $(CFLAGS) -o $@
    11. tool1.o:tool1.c
    12. $(CC) $^ $(CFLAGS) -o $@
    13. tool2.o:tool2.c
    14. $(CC) $^ $(CFLAGS) -o $@
    15. clean:
    16. $(RM) *.o mytool -r

    这个 $(RM) 运行下来可以看到,替代了 rm和 -f

    3.2.3 简化第三版

    1. # 6-11行代码相似性很强,可以提取出一个公式模版
    2. # %.o:%.c
    3. # $(CC) $^ $(CFLAGS) -o $@
    4. # 百分号相当于一个通配符
    5. OBJS=main.o tool1.o tool2.o
    6. CC=gcc
    7. CFLAGS=-c -Wall -g
    8. mytool:$(OBJS)
    9. $(CC) $^ -o mytool
    10. %.o:%.c
    11. $(CC) $^ $(CFLAGS) -o $@
    12. clean:
    13. $(RM) *.o mytool -r

    四、总结一下

    这次从零开始接触makefile,先查阅文本资料简单的接触一下makefile,留下了印象是好难读懂什么意思,痛苦几天后找到和视频资料并且写下了这篇总结,基本上可以对makefile有个较为全面的认识。

  • 相关阅读:
    DHCP原理与配置
    二分专题训练
    机器学习(一)——递归特征消除法实现SVM(matlab)
    java基础巩固15
    React Hook - 自定义Hook的基本使用和案例练习
    当MySQL想恋爱,java和navicate抢着做媒婆 ------ java连接MySQL数据库 & navicat for MySQL 连接
    Qt应用开发(基础篇)——输入对话框 QInputDialog
    和百度AI探讨“存在者存在”哲学问题
    双线服务器有哪些安全防御措施?
    【云原生 | 20】Docker运行Web服务实战之Apache
  • 原文地址:https://blog.csdn.net/m0_74282605/article/details/127921569