8.C语言 makefile总结

Makefile | 爱编程的大丙 (subingwen.cn)https://subingwen.cn/linux/makefile/

make命令执行时需要读取Makefile文件中的规则

规则格式

#每条规则的语法格式
目标:依赖(依赖可以没有)
target1,target2...:depend1,depend2..
    命令
    command

make默认只会执行第一条规则,检查第一条规则中依赖文件是否都存在,如果不存在,他就去读其他规则,直到找到目标文件是该依赖文件的规则,如此反复就构建完成了.

如果只想执行其中某条规则,可以用make 目标名,还有一些潜规则

1.make发现所有的依赖都存在,目标不存在,那么就生成目标
2.make发现所有的依赖,目标都存在,但是目标生成时间早于依赖,那么就更新目标
3.make发现所有的依赖,目标都存在,但是目标生成时间晚于依赖,那么就不更新目标 

calc:add.o sub.o mult.o div.o main.o
	gcc add.o sub.o mult.o div.o main.o -o calc

如果一段代码这样的,所有的依赖文件和目标文件都不存在,也没有规则生成这些依赖文件,make就会执行自动推导,找当前目录下的main.c,add.c和sub.c来生成依赖文件


第一种 普通写法

calc:add.o sub.o mult.o div.o main.o
	gcc add.o sub.o mult.o div.o main.o -o calc

add.o:add.c
	gcc -Wall -c add.c  -o add.o
sub.o:sub.c
	gcc -Wall -c sub.c  -o sub.o
mult.o:mult.c
	gcc -Wall -c mult.c -o mult.o
div.o:div.c
	gcc -Wall -c div.c  -o div.o
main.o:main.c
	gcc -Wall -c main.c -o main.o

clean:
	rm -rf add.o sub.o mult.o div.o main.o calc

第二种 变量写法

TAR = calc
OBJ = add.o sub.o mult.o div.o main.o
CC = gcc
CFLAGS += -Wall -c

$(TAR):$(OBJ)
	$(CC) $(OBJ) -o $(TAR)

add.o:add.c
	$(CC) $(CFLAGS) add.c  -o add.o
sub.o:sub.c
	$(CC) $(CFLAGS) sub.c  -o sub.o
mult.o:mult.c
	$(CC) $(CFLAGS) mult.c -o mult.o
div.o:div.c
	$(CC) $(CFLAGS) div.c  -o div.o
main.o:main.c
	$(CC) $(CFLAGS) main.c -o main.o

clean:
	$(RM) -r $(OBJ) $(TAR)

make的预定义变量

变 量 名    含 义    默 认 值
AR    生成静态库库文件的程序名称    ar
AS    汇编编译器的名称as
CCC 语言编译器的名称cc
CPPC 语言预编译器的名称$(CC) -E
CXXC++ 语言编译器的名称g++
FCFORTRAN 语言编译器的名称f77
RM删除文件程序的名称rm -f
ARFLAGS生成静态库库文件程序的选项无默认值
ASFLAGS汇编语言编译器的编译选项无默认值
CFLAGSC 语言编译器的编译选项无默认值
CPPFLAGSC 语言预编译的编译选项无默认值
CXXFLAGSC++ 语言编译器的编译选项无默认值
FFLAGSFORTRAN 语言编译器的编译选项无默认值

第三种 自动变量写法

$@	表示目标文件的名称,包含文件扩展名
    $*	表示目标文件的名称,不包含目标文件的扩展名
$^	依赖项中,所有不重复的依赖文件,这些文件之间以空格分开
    $+	表示所有的依赖文件,这些依赖文件之间以空格分开,按照出现的先后为顺序,其中可能 包含重复的依赖文件
$<	表示依赖项中第一个依赖文件的名称
    $?	依赖项中,所有比目标文件时间戳晚的依赖文件,依赖文件之间以空格分开
TAR = calc
OBJ = add.o sub.o mult.o div.o main.o
CC = gcc
CFLAGS += -Wall -c
 
$(TAR):$(OBJ)
	$(CC) $^ -o $@
//$^:上一句中的依赖文件名字
//$@:上一句中的目标文件名字

add.o:add.c
	$(CC) $(CFLAGS) $^  -o $@
sub.o:sub.c
	$(CC) $(CFLAGS) $^  -o $@
mult.o:mult.c
	$(CC) $(CFLAGS) $^ -o $@
div.o:div.c
	$(CC) $(CFLAGS) $^  -o $@
main.o:main.c
	$(CC) $(CFLAGS) $^ -o $@
 
clean:
	$(RM) -r $(OBJ) $(TAR)

第四种 模式匹配写法

TAR = calc
OBJ = add.o sub.o mult.o div.o main.o
CC = gcc
CFLAGS += -Wall -c

$(TAR):$(OBJ)
	$(CC) $(CFLAGS) $^ -o $@

%o:%c
	$(CC) $(CFLAGS) $^ -o $@
//%:可以认为是在通配符
//根据所有需要需要的.o,推倒出所需要的.c文件

clean:
	$(RM) -r $(OBJ) $(TAR)
%c %o 任意的.c或者.o文件
*.c *.o 所有的.c .o文件

TAR = calc
OBJ = add.o sub.o mult.o div.o main.o
CC = gcc
CFLAGS += -Wall -c

$(TAR):$(OBJ)
	$(CC) $(OBJ) -o $(TAR)

%o:%c
	$(CC) $(CFLAGS) %.c -o %.o     //gcc -c $<

clean:
	$(RM) -r $(OBJ)

第五种 函数写法

src = $(wildcard /home/robin/a/*.c /home/robin/b/*.c *.c)
搜索/home/robin/a/,/home/robin/b/和当前目录下的所有.c文件赋值给src变量
src = a.cpp b.cpp c.cpp e.cpp

# 把变量 src 中的所有文件名的后缀从 .cpp 替换为 .o
obj = $(patsubst %.cpp, %.o, $(src)) 
# obj 的值为: a.o b.o c.o e.o


TAR = main
SRC = $(wildcard *.c)
OBJ = $(patsubst %.cpp, %.o, $(src)) 
CC = gcc

$(TAR):$(OBJ)
	$(CC) -c $^ -o $@

%o:%c
	$(CC) -c $^

clean:
	rm $(OBJ) $(TAR)
如果一个规则没有生成对应的目标文件,那么就称之为伪目标,
在 makefile 中声明一个伪目标需要使用 .PHONY 关键字,声明方式为: .PHONY:伪文件名称

# 添加规则, 删除生成文件 *.o 可执行程序
# 声明clean为伪文件
.PHONY:clean
clean:
        # shell命令前的 - 表示强制这个指令执行, 如果执行失败,也不会终止,继续执行下一条命令
        -rm $(obj) $(target) 
        echo "删除失败"

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值