1、为什么使用Makefile
-
避免在命令行输入编译命令过长,可以把编译规则写在makefile内,减少工作量
-
在去修改工程时,一些文件没被修改,完全没必要重新编译,makefile可以帮助我们完成这个的检测
2.什么叫make
make是一个可执行文件,位置在/usr/bin/,如果没有,需要安装,sudo apt-get install make,作用时解析Makefile文件中的编译规则,根据规则编译项目
3.makefile应用实例
规则:
目标文件:依赖文件 #目标文件一定要顶格写
编译命令 #编译命令前要有一个tab字符,不是空格
add:add.o main.o
gcc add.o main.o -o add
add.o:add.c
gcc -c add.c -o add.o
main.o:main.c
gcc -c main.c -o main.o
#伪目标
clean:
rm add *.o
执行编译:make
执行伪目标:make clean
all:
gcc -c add.c -o add.o
gcc -c main.c -o main.o
gcc add.o main.o -o add
#伪目标
clean:
rm add *.o
-
Makefile中的变量
注意,makefile中注释也是用#
-
makefile中变量的定义和shell脚本一样
-
makefile变量的引用:
$(变量名) ${变量名}
注意:makefile执行命令时会把执行过程和结果都打印在终端,如果不想让过程显示在终端,需要在命令前+@
var=hahha
all:
@echo $(var)
7.Makefile里变量的赋值方式
-
变量2=$(变量1)
这种方式会把变量1最新的数值赋值给变量2
var1=hahha
var2=$(var1)
var1=nihao
all:
@echo $(var2)
结果:nihao
-
变量1:=$(变量2)
这种赋值方式和c语言赋值一样,把变量2当前的数值赋值给变量1
var1=hahha
var2:=$(var1)
var1=nihao
all:
@echo $(var2)
结果:hahah
-
+=:附加赋值
var1=hahha
var1+=nihao
all:
@echo $(var1)
结果:haha nihao
-
?=:询问赋值
赋值前会判断是否是第一次赋值,如果之前进行了赋值,这一次赋值操作不执行
var1=hahha
var1?=nihao
var2?=nihao
all:
@echo $(var1)
@echo $(var2)
输出结果:
hahha
nihao
8.定义变量方式优化多文件编译
#生成的目标
TARGET:=add
#依赖
OBJS:=main.o add.o
#指定编译器
CC:=gcc
#编译的时候加的参数
CFLAGS:=-c -o
CFLAGSs:=-o
#开始编译步骤编写
$(TARGET):$(OBJS)
$(CC) $(OBJS) $(CFLAGSs) $(TARGET)
main.o:main.c
$(CC) main.c $(CFLAGS) main.o
add.o:add.c
$(CC) add.c $(CFLAGS) add.o
#伪目标用于删除所有的依赖 和目标文件
clean:
rm $(TARGET) $(OBJS)
Makefile里面的通配符:
-
*:用于匹配任意数量的字符
*.o:*.c
$(CC) *.c $(CFLAGS) *.o
-
%:Makefile特有的通配符,用于在编译时替换字符
%.o:%.c
$(CC) $^ $(CFLAGS) $@
9.Makefile里的特殊字符
$@:目标文件
$^:所有的依赖文件
$<:第一个依赖文件
$*:目标去除后缀之后的所有字段
使用特殊字符对多文件编译进行优化:
TARGET:=add
OBJS:=main.o add.o
CC:=gcc
CFLAGS:=-c -o
CFLAGSs:=-o
#开始编译步骤编写
$(TARGET):$(OBJS)
$(CC) $^ $(CFLAGSs) $@
%.o:%.c
$(CC) $< $(CFLAGS) $*.o
clean:
rm $(TARGET) $(OBJS)
补充:
关于Makefile伪目标问题:当makefile目录下有一个名字为clean的文件夹存在时,
make clean无法执行,解决:
通过.PHONY声明伪目标
TARGET:=add
OBJS:=main.o add.o
CC:=gcc
CFLAGS:=-c -o
CFLAGSs:=-o
#开始编译步骤编写
$(TARGET):$(OBJS)
$(CC) $^ $(CFLAGSs) $@
#编译所有的依赖文件生成目标文件
%.o:%.c
$(CC) $< $(CFLAGS) $@
#编译第一个依赖文件,生成目标文件
.PHONY:clean
clean:
rm $(TARGET) $(OBJS)