目录
一、自定义变量
1、定义变量
变量定义有两种方式,一种会在使用的时候递归展开,一种是直接赋值。两种定义方式如下:
- 递归展开:VAR=var1 var2...,如OBJS=main.c、OBJS=test.c main.c
- 如果存在多个值,值和值之间要空格隔开
- 直接赋值:VAR:=var,如OBJ1:=main.c、OBJ2:=test.c
2、使用变量
引用变量的方式: $(变量名)
下面主要比对上面定义的两种变量在使用上有什么不同:
(1) VAR=var
OBJS=test.c main.c
main: $(OBJS)
gcc -o $@ $^
命令行输入make指令以后:
- 创建一个变量OBJS ,并将 test.c main.c赋值给这个变量
- 现在要生成的目标是 main ,提供的依赖是 $(OBJ)
- 此时会递归取出 $(OBJ) 中的值。首先会去找当前目录下有没有 test.c ,如果有就继续;然后再去找当前目录下有没有 main.c ,以递归的方式来遍历变量中的所有值
- 如果依赖项都找到了,然后再执行 gcc -o xxx xxx
(2) VAR:=var
和上面的不同,这里不存在递归,变量名和值是一一对应的关系
OBJ1:=test.c
OBJ2:=main.c
main:$(OBJ1) $(OBJ2)
gcc -o $@ $^
命令行输入make指令以后:
- 依次创建变量 OBJ1、OBJ2,并赋值
- 现在要生成的目标是 main ,提供的依赖是 $(OBJ1)、 $(OBJ2)
- 首先引用变量 OBJ1的值,此时会去找 test.c 文件;上一步没问题再去引用 OBJ2,逐个解析变量
- 如果依赖项都找到了,然后再执行 gcc -o xxx xxx
3、修改变量的值
可以通过+=来为已定义的变量添加新的值。
OBJS=test.c main.c
OBJS+=func.c
# OBJS会变成: OBJS=test.c main.c func.c
二、预定义变量
预定义变量其实就是系统内已经定义好的变量,变量名已经确定了,直接使用的话,使用的是默认值,你也可以重新赋值。下面列出一些常见的:
变量名 | 含义 |
CC | C编译器的名称,默认值为cc,即默认使用gcc编译器 |
RM | 文件删除程序的名称,默认值为rm -f |
CFLAGS | C编译器(gcc)的选项,无默认值,如-Wall、-g、-o |
AR | 库文件维护程序的名称,默认值为ar |
CPP | C预编译器的名称,默认值为$(CC) –E |
CPPFLAGS | C预编译的选项,无默认值 |
CXXFLAGS | C++编译器(g++)的选项,无默认值 |
三、自动变量
自动变量有具体的含义,不可被修改。下面是一些常见自动变量:
自动变量的引用 | 含义 |
$< | 第一个依赖文件的名称 |
$@ | 目标文件的完整名称 |
$^ | 所有不重复的目标依赖文件,以空格分开 |
$? | 所有时间戳比目标文件晚的的依赖文件,并以空格分开 |