本文脉络
一、编写规则
Makefile是make读入的惟一配置文件,其编写规则通常包含如下内容:
- 需要由make工具创建的目标体(target),通常是目标文件或可执行文件;
- 要创建的目标体依赖的文件(dependency_file);
- 创建每个目标体时需要运行的命令(command),这一行必须以制表符(tab键)开头
- 注释:一行#字符后面的为注释
Makefile格式
目标文件: 依赖文件
< TAB > 由依赖文件到目标文件的代码 /* 该行必须以tab键开头*/
make命令选项
make运行规则
make [目标] [-f makefile文件名] [-C 目录]
当“[-C 目录]”存在时,makefile目录为指定目录,否则为当前目录;
当“[-f makefile文件名]”省略时,在makefile目录下找makefile,如果不存在,再继续找Makefile;
当“[目录]”不存在时,从makefile的文件的第一个目标开始解析,否则从指定目标开始解析。
ckean伪目标:垃圾文件清理
每个Makefile中都应该写一个清空目标文件(.o和执行文件)或过程文件的规则,这不仅便于重编译,也很利于保持文件的清洁
#一般风格:
clean:
rm *.o
#clean从来都是放在文件最后,更为稳健的做法是:
.PHONY:clean
clean:
rm *.o
#防止当clean文件存在时,make不执行clean操作
示例
以输出test可执行性文件为例(除test.c文件外,还需要sub_add.c、unsgn_pow.c文件的支持)
使用步骤
#1、建立Makefile文件
vim Makefile
#2、输入Makefile文件信息:
test:test.o sub_add.o unsgn_pow.o #终极目标test的输出需要test.o sub_add.o unsgn_pow.o等目标文件的支持。(目标文件从何而来??)
gcc -o test test.o sub_add.o unsgn_pow.o #注意命令前要有<tab>键
test.o:test.c
gcc -c test.c #编译成.o文件
sub_add.o:sub_add.c
gcc -c sub_add.c
unsgn_pow.o:unsgn_pow.c
gcc -c unsgn_pow.c
.PHONY:clean #声明一个伪目标(并不需要检测clean这个文件)
clean:
rm *.o test
执行方法:
若文件名就为Makefile——>直接执行make
否则——>make -f 文件名
若要得到最终目标可直接执行make
,后无需跟目标名
否则——>make 目标名
,如make clean
二、Makefile文件的简化
1、用户自定义变量
变量作用:用来代替一个文本字符串(目标体、依赖文件、命令等)
变量名不包括 “:”、“#”、“=”结尾空格的任何字符串
变量定义的两种方式
递归展开方式:VAR = var //替代
简单方式 VAR := var //追加
引用变量$(VAR)
示例
OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g
david : $(OBJS)
$(CC) $(OBJS) -o david
kang.o : kang.c kang.h
$(CC) $(CFLAGS) -c kang.c -o kang.o
yul.o : yul.c yul.h
$(CC) $(CFLAGS) -c yul.c -o yul.o
2、预定义变量
make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量
如果用户在makefile中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量
3、自动变量
4、隐含规则
隐含规则告诉make怎样使用传统的规则完成任务,这样,当用户使用它们时就不必详细指定编译的具体细节,而只需把目标文件列出即可
示例
OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g
david : $(OBJS)
$(CC) $^ -o $@
5、模式规则
模式规则的格式类似于普通规则,这个规则中的相关文件前必须用“%”标明
模式规则是用来定义相同处理规则的多个文件的。它不同于隐式规则,隐式规则仅仅能够用make默认的变量来进行操作,而模式规则还能引入用户自定义变量,为多个文件建立相同的规则,从而简化了makefile的编写
示例
OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g
david : $(OBJS)
$(CC) $^ -o $@
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@