什么是 Makefile

make是一个构建工具,主要用于C/C++项目。
Makefile本质上就是一个脚本文件,通常使用make来解释该脚本文件中的指令,来对我们的项目进行编译。
当项目非常复杂时,Makefile能够建立各个文件之间的依赖关系,根据文件的时间戳来判断文件是否修改,是否需要重新编译,从而减少编译的工作量。

规则

  1. #目标: 依赖
  2. # 命令 # 前面是一个 tab
  3. main: main.c
  4. gcc main.c -o main

变量

定义一个变量需要对它赋值,有如下 4 中赋值方式:

变量的赋值

简单赋值

  1. a := 1 # 1
  2. b := $(a)2 # 12
  3. a := 2 # b is 12

变量的值会在使用处展开;赋值后,前后两个变量的值不再具有联系。

递归赋值

  1. a := 1 # a is 1
  2. b = $(a)2 # b is 12
  3. a := 2 # b is 22

=后的变量值改变后,会影响到前面的变量;这种联系一直存在。

条件赋值

  1. a ?= 1 # a is 1
  2. b = $(a)2 # b is 12
  3. a ?= 2 # a is 1, b is 12

如果变量为定义,则使用后面的内容赋值,否则变量的值不改变。

追加赋值

  1. a := 1 # a is 1
  2. a += 2 # a is 1 2
  3. a += 3 # a is 1 2 2

在原变量尾部添加空格,将新值追加上去。有点像字符串的拼接规则。

内置变量

**CC** C 语言编译器的名称
**CXX** C++ 语言编译器的名称
**CFLAGS** C 语言编译器的编译选项,无默认值

https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html

分支判断

image.png

  1. ARCH ?= x86
  2. ifeq ($(ARCH), x86)
  3. CC := gcc
  4. else
  5. CC := arm-linux-gcc
  6. endif

可以用来根据不同的 CPU 架构选择合适的编译器,在执行make时,可以灵活设置:

  1. make print ARCH=arm

显式规则与隐式规则

显式规则是说,用Makefile生成文件时,所有具体的文件都由我们直接写出来。
隐式规则:如果我们不指明规则,Makefile自己有一套规则来完成目标文件的生成(自动推导依赖关系)。