Makefile的使用

一、第一代

main: main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o
main.o: main.c
    gcc -c main.c
input.o: input.c
    gcc -c input.c
calcu.o: calcu.c
    gcc -c calcu.c

clean:
    rm *.o
    rm main

总结:最上面是.o结尾的目标文件,接下来是对每一个目标文件的编写,看似比单独用gcc还要麻烦,这是二代进阶版的使用规则。

Makefile 里面是由一系列的规则组成的,这些规则格式如下:

目标…... : 依赖文件集合……
命令 1
命令 2 ……

二、第二代(Makefile 变量 )

#Makefile 变量的使用
objects = main.o input.o calcu.o
main: $(objects)
    gcc -o main $(objects)

#为注释

第二行是对objects变量进行了赋值,其值为字符串“main.o input.o calcu.o”。 第 3 和 4行使用到了变量 objects, Makefile 中变量的引用方法是“$(变量名)”,比如本例中的“$(objects)”就是使用变量 objects。

1、赋值符“=”

name = zzk
curname = $(name)
name = zuozhongkai

print:
    echo curname:$(curname)
curname:zuozhongkai

第 6 行 中的“echo”前面加了个“@”符号,因为 Make 在执行的过程中会自动输出命令执行过程,在 命令前面加上“@”的话就不会输出命令执行过程,大家可以测试一下不加“@”的效果。

2、赋值符“:=”

name = zzk
curname := $(name)
name = zuozhongkai

print:
    echo curname:$(curname)
curname:zzk

赋值符“:=”不会使用后面定义的变量,只能使用前面已经定义好的,这就是“=”和“:=”两个的区别。

3、赋值符“?=”

如果变量 curname 前面没有被赋值,那么此变量就是“zuozhongkai”,如果前面已经赋过值了,那么就使用前面赋的值。

4、变量追加“+=”

objects = main.o inpiut.o
objects += calcu.o

三、Makefile 模式规则

main: main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o
main.o: main.c
    gcc -c main.c
input.o: input.c
    gcc -c input.c
calcu.o: calcu.c
    gcc -c calcu.c

clean:
    rm *.o
    rm main
objects = main.o input.o calcu.o
 
main: $(objects)
    gcc -o main $(objects)
%.o : %.c
    #命令

clean:
    rm *.o
    rm main

目标中“%”所代表的值决定了依赖中的“%”值 。但是上文中的第6行命令并没有执行生成我们想要的目标文件,这就要借助强大的自变量。

4 Makefile 自动化变量

自动化变量

描述

$@

规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模 式中定义的目标集合。

$%

当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件, 那么其值为空。

$<

依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么 “$<”就是符合模式的一系列的文件集合。

$?

所有比目标新的依赖目标集合,以空格分开。

$^

所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件, “$^”会去除重复的依赖文件,值保留一份。

$+

和“$^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。

$*

这个变量表示目标模式中"%"及其之前的部分,如果目标是 test/a.test.c,目标模 式为 a.%.c,那么“$*”就是 test/a.test。

objects = main.o input.o calcu.o
 
main: $(objects)
    gcc -o main $(objects)
%.o : %.c
    gcc -c $<

clean:
    rm *.o
    rm main

Makefile 伪目标

Makefile 有一种特殊的目标——伪目标,一般的目标名都是要生成的文件,而伪目标不代 表真正的目标名,在执行 make 命令的时候通过指定这个伪目标来执行其所在规则的定义的命 令。

.PHONY : clean
objects = main.o input.o calcu.o
main: $(objects)
    gcc -o main $(objects)

    .PHONY : clean

%.o : %.c
    gcc -c $<

clean:
    rm *.o
    rm main

上述代码第 5 行声明 clean 为伪目标,声明 clean 为伪目标以后不管当前目录下是否存在名 为“clean”的文件,输入“make clean”的话规则后面的 rm 命令都会执行。

Makefile 条件判断

<条件关键字> <条件为真时执行的语句> endif
<条件关键字>
<条件为真时执行的语句>
else
<条件为假时执行的语句>
endif

其中条件关键字有 4 个:ifeq、ifneq、ifdef 和 ifndef,这四个关键字其实分为两对、ifeq 与 ifneq、ifdef 与 ifndef,先来看一下 ifeq 和 ifneq,ifeq 用来判断是否相等,ifneq 就是判断是否不相等,ifeq 用法如下:

ifeq (<参数 1>, <参数 2>) ifeq ‘<参数 1 >’,‘ <参数 2>’ ifeq “<参数 1>”, “<参数 2>” ifeq “<参数 1>”, ‘<参数 2>’ ifeq ‘<参数 1>’, “<参数 2>”
ifdef <变量名>

Makefile 函数使用

Makefile 支持函数,类似 C 语言一样,Makefile 中的函数是已经定义好的,我们直接使用, 不支持我们自定义函数。make 所支持的函数不多,但是绝对够我们使用了,函数的用法如下:

$(函数名 参数集合) 或者: ${函数名 参数集合}

可以看出,调用函数和调用普通变量一样,使用符号“$”来标识。参数集合是函数的多个 参数,参数之间以逗号“,”隔开,函数名和参数之间以“空格”分隔开,函数的调用以“$”开 头。接下来我们介绍几个常用的函数,其它的函数大家可以参考《跟我一起写 Makefile》这份 文档。

1、函数 subst

函数 subst 用来完成字符串替换,调用形式如下: $(subst<from>,<to>,<text>)

此函数的功能是将字符串中的内容替换为,函数返回被替换以后的字符串,比如如下示例:

$(subst zzk,ZZK,my name is zzk)

把字符串“my name is zzk”中的“zzk”替换为“ZZK”,替换完成以后的字符串为“my name is ZZK”

2、函数 patsubst

函数 patsubst 用来完成模式字符串替换,使用方法如下: $(patsubst<pattern>,<replacement>,<text>)

此函数查找字符串<text>中的单词是否符合模式<pattern>,如果匹配就用<replacement>来替换掉,<pattern>可以使用通配符“%”,表示任意长度的字符串,函数返回值就是替换后的字符串。如果<replacement>中也包涵“%”,那么<replacement>中的“%”将是<pattern>中的那个“%”所代表的字符串,比如:

$(patsubst %.c,%.o,a.c b.c c.c)

将字符串“a.c b.c c.c”中的所有符合“%.c”的字符串,替换为“%.o”,替换完成以后的字符串为“a.o b.o c.o”。

3、函数 dir

函数 dir 用来获取目录,使用方法如下:

$(dir <names…>)

此函数用来从文件名序列<names>中提取出目录部分,返回值是文件名序列<names>的目录部分,比如:

$(dir </src/a.c>)

提取文件“/src/a.c”的目录部分,也就是“/src”。

4、函数 notdir

函数 notdir 看名字就是知道去除文件中的目录部分,也就是提取文件名,用法如下:

$(notdir <names…>)

此函数用与从文件名序列<names>中提取出文件名非目录部分,比如:

$(notdir</src/a.c> )

提取文件“/src/a.c”中的非目录部分,也就是文件名“a.c”。

5、函数 foreach

foreach 函数用来完成循环,用法如下:

$(foreach<var>,<list> ,<text>)

此函数的意思就是把参数<list>中的单词逐一取出来放到参数<var>中,然后再执行<text>所包含的表达式。每次<text>都会返回一个字符串,循环的过程中,<text>中所包含的每个字符串会以空格隔开,最后当整个循环结束时,<text>所返回的每个字符串所组成的整个字符串将会是函数 foreach 函数的返回值。

6、函数 wildcard

通配符“%”只能用在规则中,只有在规则中它才会展开,如果在变量定义和函数使用时,通配符不会自动展开,这个时候就要用到函数 wildcard,使用方法如下:

$(wildcard PATTERN…)

比如:

$(wildcard *.c)

上面的代码是用来获取当前目录下所有的.c 文件,类似“%”。

关于 Makefile 的相关内容就讲解到这里,本节只是对 Makefile 做了最基本的讲解,确保大家能够完成后续的学习,Makefile 还有大量的知识没有提到,有兴趣的可以自行参考《跟我一起写 Makefile》这份文档来深入学习 Makefile。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值