MakeFile 快速入门--读完就能用

前言

格式:编译工具链 -o 可执行文件名 待编译文件名 -编译选项

例:gcc -o test test.c

或:编译工具链 待编译文件名 -o 可执行文件名 -编译选项

例:arm-linux-gnueabihf-gcc server.c -o server -pthread

每次编译时都需要打一长串是很麻烦的,尤其是当待编译文件众多时。此时需要制作Makefile文件,只需make 一下即可。MakeFile文件的写作等级大致分为五级,级别越高越难理解,此处仅做入门教学。

第一层 显式规则

将上述格式直接照搬,执行后只会编译已更新内容
目标:依赖
[TAB缩进]上述格式
示例说明:将main.c 与hello.c (依赖)编译成名为test的可执行文件(目标)。
注意目标为可执行文件时依赖需为.o文件,目标为.o文件时依赖才为.c文件。
执行make clean可将所有编译生成文件清除,clean文件实际不存在,故利用.PHONY声明clean为伪目标。

test:hello.o main.o                   #此符号为注释
	gcc hello.o main.o -o test
hello.o:hello.c
	gcc -c hello.c -o hello.o
main.o:main.c
	gcc -c main.c -o main.o
.PHONY
clear:
	rm -rf main.o hello.o test

第二层 变量替换

类似于C语言中的宏定义,以简略字符替换经常使用的变量,方便移植和修改
变量赋值:

 	:=  即时变量
	=   延时变量
	?=  延时变量,仅第一次定义才有效,如果前边有同名定义则忽略此句
	+=  附加变量,是即时变量还是延时变量取决于前面定义

调用:$(变量)

CC:=gcc
OBJ:=main.o hello.o
TAR:=test
$(TAR):$(OBJ)
	$(CC) $(OBJ) -o $(TAR)
main.o:main.c
	$(CC) -c main.c -o main.o
hello.o:hello.c
	$(CC) -c hello.c -o hello.o
.PHONY
clear:
	rm -rf main.o hello.o test

第三层 隐式规则

将所有文件名省略,以 *、% 模糊代替,除了宏定义其他地方不会出现文件名,更易于维护

%c, %o:任意的.c和.o,对应的.c生成对应的.o,此条可能会多次执行,取决于OBJ个数
*.c *.o:所有的.c和.o,常用于clear语句

CC:=gcc
OBJ:=main.o hello.o
TAR:=test
$(TAR):$(OBJ)
	$(CC) $(OBJ) -o $(TAR)
%.o:%.c
	$(CC) -c %.c -o %.o
.PHONY
clear:
	rm -rf *.o $(TAR)

第四层 通配符

进一步省略,此处列举少量通配符
$^ :所有的依赖文件
$@:所有目标文件
$< :所有的依赖文件的第一个文件

CC:=arm-linux-gnueabihf-gcc -pthread
TAR:=main
OBJ:=main.o init.o send.o recv.o
$(TAR):$(OBJ)
   $(CC) -o $@ $^         # $^表示所有依赖
%.o:%.c     //符合此格式的上述依赖都会代入
   $(CC) -c -o $@ $^      # $@表示目标%.o,$<表示第一个依赖%.c
.PHONY:
clean:
   rm -rf *.o $(TAR)      # make clean清除所有.o文件

第五层 函数

非专业基本不会用到,但作用超多,此处仅举例说明

$(foreach var,list,text)            #对于list的每一个值,都执行text操作
$(filter pattern...,text)           #在text中提取符合pattern格式的值
$(filter-out pattern...,text)       #与上函数相反,提取不符合该格式的字符
$(wildcard pattern)                 #pattern定义了文件名的格式,wildcard取出其中存在的文件
$(patsubst pattern,replacement,text)#在列表中将pattern格式替换为replacement格式

对应示例:

A = a b c
B = $(foreach f,$(A),$(f).o)         #将A中所有加上.o后缀
all:
     @echo B = $(B)                  #输出结果B = a.o b.o c.o
C = a b c d/
D = $(filter %/,$(C))                #将符合%/格式的字符挑选出来
E = $(filter-out %/,$(C))            #将不符合的挑选出来
all:
      @echo D = $(D)
      @echo E = $(E)                 #D = d/ E = a b c
files = @(wildcard *.c)
all:
    @echo files = $(files)    #将所有符合.c格式的文件提取出来,利用此函数取出真实存在的文件
file2 = a.c b.c c.c e.c
file3 = $(wildcard $(files2))
all:
    @echo files2 = $(files3)  #由于e.c并不存在,故只有前三项打印出来       
file = a.c b.c c.c e.c abc
dep_files = $(patsubst %.c,%.d,$(files)
all:
    @echo dep_files = $(dep_files)   #dep_files = a.d b.d c.d e.d abc abc不符合格式不替换

抛砖引玉,欢迎纠错补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值