makefile简介

1. 什么是make

简单来说,make是一个自动化构建工具,帮助我们来完成一些任务。make需要一个叫makefile的文件来自动完成任务。我们可以把make看作一个炒菜机器人,把makefile看作一个菜谱,我们把食材准备好,然后把菜谱(makefile)交给炒菜机器人(make),按下开始按钮,机器人就会按照菜谱开始做饭。
不论多么复杂的菜,只要我们把菜单给炒菜机器人,他就可以帮我们完成工作,但我们一定要给机器人菜谱,不然它不知道它需要干什么,同时,我们也应该准备好原材料,不然机器人做到一半,忽然发现少东西,这饭没法做了啊!

通过上面的描述你应该对make能做的事大致有了一点了解,那make所应用的领域到底有那些呢?
make最常用的领域就是C/C++项目中,当然,make发展到现在也可以在别的使用。尽管现在已经有了如CMake等的更好使用工具,但我认为make依旧是你在C/C++领域学习的道路上必须会的一个技能,不一定精通,但你一定要能看懂。

2.环境搭建

系统:Ubuntu20.4LTS
make:GNU Make 4.2.1
gcc:gcc version 9.4.0

make的版本现在有很多,如:Delphi 的 make,Visual C++ 的 nmake,Linux 下 GNU 的 make,本文使用的为Linux下的GNU make。

由于是使用C语言编写示例工程,我们还需要安装gcc,Ubuntu下安装gcc的指令为sudo apt install gcc

3.程序的编译链接

既然是C/C++项目中常被用到,那就不可避免的需要一些C/C++编译链接的知识。这是我们以C语言为例,简单介绍C语言编译链接的过程。
我们使用下面这个代码作为示例。

#include <stdio.h>

int main(int argc,char **argv){
printf("hello world\n");
return 0;
}

这段代码是我们学习C语言时的第一个编写的程序,只不过大多数人都是使用Devc++/Codeblocks等的IDE(集成开发环境),并不知道从源程序到可执行文件的过程。
从源文件到可执行文件的大致过程为:
源文件 ->目标文件 -> 可执行文件
我们需要把源文件翻译成目标文件,再把多个目标文件链接为可执行程序。

demo.c -> demo.o -> demo

gcc -c demo.c   # 把源文件翻译成目标文件demo.o
gcc -o demo demo.o # 把目标文件进行链接,生成可执行文件demo

我们可以通过gcc -o demo demo.c来直接生成可执行程序,这是因为gcc是编译工具链,gcc里包含了编译链接所需要的程序,gcc是一个组合的程序。
那既然可以直接生成可执行文件,我们为什么还要生成中间文件?在实际的项目中会有很多很多的源文件,如果你编译过Linux内核,你就会明白这个道理,编译是很耗时的。想象一下,我们写项目的过程中,找到一个因为遍历时候的次数多了1导致的Bug,我们在修改这个Bug后想看看程序是否正常,但项目太大,我们需要编译半个小时,这是不可接受的一件事。那怎么办呢?那就用空间换时间呗,我们把编译过程中的目标文件保留下来,重新生成项目的时候,只需要重新生成这个被修改的文件,编译的时间就大大缩短了,这似乎是一个不错的解决办法。

4. makefile

make按照makefile里的规则执行,那么这个菜谱的名称一定是makefile吗?
当然不是!
GNU make会自动在当前目录下依次查找 GNUmakefile 、makefile 和 Makefile这三个文件,GNUmakefile是GNU特有的,其他版本的make不一定会查找这个文件,剩下两个则是大多数make都会去查找的文件名。推荐使用Makefile这个名称,因为大写的字典序比较靠前。这也是业界通常的做法,使用Makefile这个文件名来编写make的规则。
当然你也可以按照自己的喜好来给它起名字,只需要再执行make的时候加上参数即可。

make -f mymakefile
make --file mymakefile

makefile的内容

  • 显示规则
  • 隐式规则
  • 变量
  • 指令
  • 注释
    注释使用#开头