Makefile基础

目录

一 、makefile规则

1.1 makefile文件名        

1.2 规则格式

二、makefile组成元素

2.1 显式规则

2.2 变量

2.3 运算符的使用

2.4 特殊变量/符号

2.5 条件判断语句        

2.6 隐晦规则

伪目标

2.7 文件指示

2.8 注释

三 、makefile函数

3.1 匹配具体目录下的文件函数:wildcard函数

3.2 取文件名函数:notdir函数

3.3 模式替换函数:patsubst函数

3.4 反过滤函数:filter-out函数


一 、makefile规则

1.1 makefile文件名        

          默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,可使用make -f 文件名make --file 文件名 查找运行特定makefile文件。

1.2 规则格式

        Target(目标) : prerequisites(依赖)

        (TAB)Command(命令) 

        Target: 是一个目标文件,可以是Object File,也可以是执行文件,还可以是一个标签(Label)。

        Prerequisites: 是要生成那个target所需要的文件或是目标。

        Command: 是make需要执行的命令。

app:main.o led.o lcd.o key.o
	gcc main.o led.o lcd.o key.o -o app
main.o:main.c
	gcc -c main.c -o main.o
led.o:led.c
	gcc -c led.c -o led.o
key.o:key.c
	gcc -c key.c -o key.o
lcd.o:lcd.c
	gcc -c lcd.c -o lcd.o
规则执行顺序:main.o led.o lcd.o key.o app  

注意:1)命令行前必须用TAB(每行)      

           2)第一条规则为终极目标

           3)除第一条规则外其余规则之间无必然的顺序

           4)每一个规则中的目标,不一定要有依赖

           5)每一个规则,不一定非得有命令列表

           6)每个规则中可以有多条命令规则

二、makefile组成元素

        Makefile主要有五部分组成:显式规则、隐晦规则、变量定义、文件指示和注释。

2.1 显式规则

        显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

app:main.o led.o lcd.o key.o
	gcc main.o led.o lcd.o key.o -o app
main.o:main.c
	gcc -c main.c -o main.o
led.o:led.c
	gcc -c led.c -o led.o
key.o:key.c
	gcc -c key.c -o key.o
lcd.o:lcd.c
	gcc -c lcd.c -o lcd.o

2.2 变量

        在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。

        变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,用小括号“()”或是大括号“{}”把变量给包括起来。如果要使用真实的“$”字符,需要用“$$”来表示。变量类型为字符串  

inc=./
A=123
ABC=456
all:
    #输出./
	echo $(inc)
    #123      
	echo $A
    #456
	echo $(ABC)
    #456
	echo ${ABC}

2.3 运算符的使用

运算符

功能

举例

=

延迟展开赋值:最后进行赋值

ABC=$(A)

A=123

all:

         echo $A

         echo $(ABC)

         echo ${ABC}

用时再取值

:=

立即展开赋值

ABC:=$(A)

A=123

all:

         echo $A

         echo $(ABC)

         echo ${ABC}

ABC:=$(A)时必须赋值 没有即为空

?=

条件赋值:如果运算符前的变量没有被赋值,则把运算符后的值赋给该变量

(经常出现在make传参)

B=999

A=123

B?=$A

all:

         echo $A

         echo $(B)

         echo ${B}

+=

追加赋值:把运算符后的值追加到变量上

B:=123

B+=456

B+=789

all:

         echo $(B)

         echo ${B

2.4 特殊变量/符号

变量

功能

$@

当前这条规则的“目标名”

$^

当前规则中所有 “依赖”

$<

规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表由隐含规则加入的第一个依赖文件。

$$

代表当前执行的进程的进程编号

@

告诉make在执行命令前不要将命令显示在标准输出上

app:main.o led.o 
	gcc $^ -o $@
main.o:main.c
	gcc -c $^ -o $@
led.o:led.c
	gcc -c $^ -o $@

2.5 条件判断语句        

关键字

功能

ifeq

判断参数是否相等,相等为true,否则为false

ifneq

判断参数是否不相等,不相等为true,否则为false

ifdef

判断变量是否有值,有值则为ture,否则为false

ifndef

判断变量是否没有值,没有值则为ture,否则为false

条件判断语句使用情况

        1)判断语句不在规则中变量赋值

AAA=100
BBB=101

ifeq (${AAA},${BBB})
	CCC=888
else
	CCC=999
endif
all:
	echo $(CCC)

        2)标签在判断语句中

AAA=100
BBB=101
ifeq (${AAA},${BBB})
all:
	echo "AAAA"
else
all:
	echo "BBBB"
endif

        3)判断语句在命令行中

AAA=100
BBB=101
all:
ifeq (${AAA},${BBB})
	echo "AAAA"
else
	echo "BBBB"
endif

        如果条件语句不是出现在命令规则中,则不能使用相关命令,只能做赋值处理,例如情况1。

2.6 隐晦规则

        由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。

        使用模式规则来定义一个隐含规则。一个模式规则就好像一个一般的规则,只是在规则中,目标的定义需要有"%"字符。"%"的意思是表示一个或多个任意字符。在依赖目标中同样可以使用"%",只是依赖目标中的"%"的取值,取决于其目标。"%"的展开发生在变量和函数的展开之后,变量和函数的展开发生在make载入Makefile时,而模式规则中的"%"则发生在运行时。

CC=gcc
inc=../inc/
app:main.o led.o        可以添加路径(./src/mian.o)      main.o等同于当前目录下main.o 
	$(CC) $^ -o $@   -I $(inc)
# %.o等同于main.o led.o   %.c等同于main.c led.c
%.o:%.c
	$(CC) -c $< -o $@ -I $(inc)

伪目标

        伪目标:不是一个真正的目标,仅仅是为了执行其规则下的命令,使用 .PHONY:来声明,

        执行:make 标签名,例:make clean

CC=gcc
inc=../inc/
app:main.o led.o lcd.o key.o
	$(CC) $^ -o $@   -I $(inc)
%.o:%.c
	$(CC) -c $^ -o $@ -I $(inc)
clean:
	rm *.o app
.PHONY:clean

2.7 文件指示

        ①是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;

        ②是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;

        ③定义一个多行的命令。Makefile使用include关键字可以把别的Makefile包含进来,被包含的文件会原模原样的放在当前文件的包含位置。  

        如果有文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误。它会继续载入其它的文件,一旦完成makefile的读取,make会再重试这些没有找到,或是不能读取的文件,如果还是不行,make才会出现一条致命信息。如果你想让make不理那些无法读取的文件,而继续执行,你可以在include前加一个减号“-”。如:-include<filename>

include 1.mk
CC=gcc
app:main.o led.o 
	$(CC) $^ -o $@   
%.o:%.c
	$(CC) -c $^ -o $@ 

2.8 注释

        Makefile中只有行注释,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果要在Makefile中使用“#”字符,可以用反斜框进行转义,如:“\#”。

三 、makefile函数

3.1 匹配具体目录下的文件函数:wildcard函数

格式:sources= $(wildcard *.c)

返回值:<具体目录下文件>匹配当前目录下 所有.c文件 ; 也可以自定具体目录

#遍历出指定目录下所有文件

#allsrc = $(wildcard ./*.c)

allsrc = $(wildcard *.c)

#终极规则

all:

         echo  ${allsrc}

3.2 取文件名函数:notdir函数

格式:$(notdir NAMES) 

函数功能:从文件名序列“NAMES”中取出非目录部分。目录部分是指最后一个斜线( /”) (包括斜线)之前的部分。删除所有文件名中的目录部分,只保留非目录部分。 

返回值:文件名序列“NAMES”中每一个文件的非目录部分。 

#遍历出指定目录下所有文件

allsrc = $(wildcard ./src/*.c)

#去除路径部分的文件名

notdirsrc = $(notdir ${allsrc})

#终极规则

all:

         echo $(allsrc)

         echo  ${notdirsrc}

3.3 模式替换函数:patsubst函数

格式:obj=$(patsubst <pattern>,<replacement>,<text>)

函数功能:查找text中的单词,如果匹配pattern,那么就用replacement的内容替换

返回值为:生成的所有replacement文件名;

#遍历出指定目录下所有文件

allsrc = $(wildcard ./src/*.c)

#去除路径部分的文件名

notdirsrc = $(notdir ${allsrc})

#模式匹配

objsrc=$(patsubst %.c,%.o,${notdirsrc})

#终极规则

all:

         echo $(allsrc)

         echo  ${notdirsrc}

         echo $(objsrc)

3.4 反过滤函数:filter-out函数

格式:$(filter-out <pattern...>,<text> )

功能:以<pattern>模式过滤<text>字符串中的单词,去除符合模式<pattern>的单词。可以有多个模式。存在多个模式时,模式表达式之间使用空格分割。

返回:返回不符合模式<pattern>的字串。

#遍历出指定目录下所有文件

allsrc = $(wildcard ./src/*.c)

#去除路径部分的文件名

notdirsrc = $(notdir ${allsrc})

#过滤掉指定源文件

#filter-out改为filter,则为过滤函数,功能为保留符合模式的单词 

filterfilename=$(filter-out key.c,${notdirsrc})

#终极规则

all:

         echo ${filterfilename}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值