如果有帮助,希望点赞支持,我会更有创作的动力哦

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 文件。

1.2 为何使用 Makefile?

  • 上面提到需要将我们写的大量项目文件管理起来,这里具体讲讲:
  • 如何编写一个Makefile文件(手把手的教你) - 图1
    这个树形图展示了一个项目中的层级关系,如果我们需要变动 3 号文件,会发现,牵一发而动全身,改动一个被迫需要改动一堆,为了解放我们,make 中编写 Makefile 就不再需要考虑这些,你把每个文件的依赖关系以指令的形式说明清楚并且保存下来,改动一个即可,会自动帮你修改关联到的其他文件。

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

2.1.1 创建文件

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

如何编写一个Makefile文件(手把手的教你) - 图2

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

2.1.2 查看创建的文件

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

  1. ls

如何编写一个Makefile文件(手把手的教你) - 图3

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

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

  1. vim * -p

如何编写一个Makefile文件(手把手的教你) - 图4

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 <stdio.h>
  3. #incldue "tool1.h"
  4. # 定义函数
  5. void mytool1(void)
  6. {
  7. printf("tool1 print\n");
  8. }

如何编写一个Makefile文件(手把手的教你) - 图5

只需要稍微修改一下 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 <stdio.h>
  3. #incldue "tool2.h"
  4. # 定义函数
  5. void mytool2(void)
  6. {
  7. printf("tool2 print\n");
  8. }

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

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

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

2.1.4 编译运行

如何编写一个Makefile文件(手把手的教你) - 图6

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

makeile 教学视频
讲前小科普:如何编写一个Makefile文件(手把手的教你) - 图7

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

  1. rm a.out

如何编写一个Makefile文件(手把手的教你) - 图8

2.2.2 创建 makefile

vim 进入编辑模式,系统检测没有名为 makefile 的文件,会自动创建。
如果自己想自定义一个其他名字,比如 makefilebuff-demo,可能在 make 操作时候会有影响。下面会讲。
如何编写一个Makefile文件(手把手的教你) - 图9

接下来的写依赖关系的时候,你可能会疑惑 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文件(手把手的教你) - 图10

保存退出,然后查看一下目录(好习惯),发现有一个 makefile 的文件啦。
如何编写一个Makefile文件(手把手的教你) - 图11

2.2.3 执行 makefile 文件

直接使用 make 命令
如何编写一个Makefile文件(手把手的教你) - 图12

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

make 命令可以通过 -f 执行使用的 makefile。

如果在没有使用 -f 指定的情况下,会按照下面的顺序执行。

GNUmakefile, makefile 和 Makefile

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

可以看到可执行文件已经是其他颜色了,颜色不同代表这文件权限不同。
(./ 文件名)运行!
如何编写一个Makefile文件(手把手的教你) - 图13

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


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

3.1 添加 clean 信息

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

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

  1. clean
  2. rm *.o mytool -rf

如何编写一个Makefile文件(手把手的教你) - 图15

执行 make clean,发现出现了依赖和被依赖的关系
如何编写一个Makefile文件(手把手的教你) - 图16

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
如何编写一个Makefile文件(手把手的教你) - 图17

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文件(手把手的教你) - 图18

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