makefile

 

*和%的区别:
SRCS := $(Wildcard *.c)
OBJS := $(patsubst %.c,%.o,$(SRCS))
*:表示在当前目录下的所有.c文件
%:表示所有的.c文件中的一个.c文件

 

 

Makefile规则

生成目标:make [目标],如果make后面没有跟目标,那就生成makefile中第一个规则的第一个目标(即test);也可以make指定的目标,如make clean

 

命令被执行的 2 个条件:

  1.  依赖文件比目标文件新

  2. 没有目标文件。

为什么要伪目标?

因为在执行像make clean这样的指令时,由于他没有依赖,如果在该目录下有一个clean文件或目录,那么rm *.o test命令就无法执行,因为不满足命令被执行的第一个条件,所以要用PHONY来说明目录下的clean文件或目录不是目标(即现在还有目标文件,所以make clean时,命令Rm *.o test会被执行)

 

a.c b.cc.c三个文件

目标:依赖(一个或多个依赖文件)

[TAB]命令

Test: a.o b.o c.o
    gcc -o test $^($^  表示所有的依赖文件)

%.o : %.c
    gcc -c -o $@ @<($@:表示目标; $<:表示依赖中的第一个文件)

.PHONY:clean (伪目标)
clean:
    Rm *.o test

通配符:

$@ 表示目标

$<  表示依赖的第一个文件

$^  表示所有的依赖文件

 

变量:

:=  #及时变量 如A = XX;A的值即刻确定,在定义时即确定

=   #延时变量 如B :=xx; B的值在使用时才确定

?=  #延时变量,如果第一次定义才起效,如果在前面该变量已定义则忽略这句

+=  #附加,他是及时变量还是延时变量取决于前面的定义

A : = $(C) #A是即使变量,所以在定义时即可确定,但是C还没有定义,所以A为空
B = $(C)#B是延时变量,在使用时才确定,所以下面输出B=ABC123
C = ABC#在定义时C为延时变量
D = 100ASK
D ?=ZJ#这条语句被忽略

all:
  echo A = $(A)#这里输出A =
  echo B= $(B)
  echo D= $(D)

C +=123#附加时,这个就是延时变量,所以在使用时才确定,所以$(C)为ABC123

 

函数($是引用或调用函数)

$(foraech var,list,text)#调用foreach函数,对 list 中的每一个元素,取出来赋给 var,然后把 var改为text所描述 的形式

$(filter pattern...,text)#调用filter 函数,在text中取出符合pattern格式的值

$(filter-out pattern...,text)text中取出不符合pattern格式的值

$(wildcard pattern)pattern定义文件名的格式,wildcard取出当前目录存在的pattern格式文件

$(patsubst pattern,replacement,$(var))替换

 

test下,建立a.cb.c2个文件,在sub目录下,建立sa.csb.c2 个文件

建立一个简单的Makefile
src=$(wildcard .c ./sub/.c)  #输出a.c b.c ./sub/sa.c ./sub/sb.c2
dir=$(notdir $(src)) #输出a.c b.c sa.c sb.c  notdir : 去除路径
obj=$(patsubst %.c,%.o,$(dir) )#输出a.o b.o sa.o sb.o

posted @ 2023-10-24 16:24  踏浪而来的人  阅读(14)  评论(0编辑  收藏  举报