第二十八节(MakeFile语法)

新建一个目录编写几个c文件,然后利用gcc命令将其链接为可执行程序

image.png

首先利用gcc -c将这些c文件编译为.o文件
例如:

gcc -c divi.c

编译完成后

image.png

利用 gcc -o 命令将这些.o文件链接为可执行文件

gcc divi.o main.o minus.o multi.o plus.o -o app

链接完成后会生成一个app可执行文件

image.png

运行命令,可以看到正确的输出结果:

hhh:makefile huozhenpeng$ ./app
ret:10

现在利用makefile语法来完成上述所有的步骤
新建一个文件,名字就叫做makefile

image.png
app:divi.o plus.o main.o minus.o multi.o
    gcc divi.o plus.o main.o minus.o multi.o -o app
divi.o:divi.c
    gcc -c divi.c
plus.o:plus.c
    gcc -c plus.c
main.o:main.c
    gcc -c main.c
minus.o:minus.c
    gcc -c minus.c
multi.o:multi.c
    gcc -c multi.c

在命令行窗口输入命令make

hhh:makefile huozhenpeng$ make

然后就会生成中间文件(.o)并利用.o文件生成可执行文件app

image.png

运行app可执行文件

hhh:makefile huozhenpeng$ ./app
ret:10

一个简单的makefile语法的格式:

一个简单的 Makefile 描述规则组成:
TARGET... : PREREQUISITES... 
        COMMAND
...
...

target:规则的目标。通常是最后需要生成的文件名或者为了实现这个目的而必需 的中间过程文件名。可以是.o文件、也可以是最后的可执行程序的文件名等。另外,目 标也可以是一个make执行的动作的名称,如目标“clean”,我们称这样的目标是“伪目标”

还是上面的程序,我们修改makefile文件

app:divi.o plus.o main.o minus.o multi.o
    gcc divi.o plus.o main.o minus.o multi.o -o app
divi.o:divi.c
    gcc -c divi.c
plus.o:plus.c
    gcc -c plus.c
main.o:main.c
    gcc -c main.c
minus.o:minus.c
    gcc -c minus.c
multi.o:multi.c
    gcc -c multi.c
clean:
    rm -f *.o
image.png

执行make命令,生成了.o和app可执行文件

image.png

执行make clean命令,成功删除了.o文件

image.png

但是如果我们在这个目录中有个clean文件的时候,make clean 命令就不会起作用了

image.png

执行make命令:

image.png

执行make clean 命令:

image.png

无法删除.o文件
如果我们需要书写这样一个规则:规则所定义的命令不是去创建目标文件,而是通过 make 命令行明确指定它来执一些特定的命令。像常见的 clean 目标:

clean:
        rm *.o temp

规则中“rm”不是创建文件“clean”的命令,而是删除当前目录下的所有.o 文件和 temp 文件。当工作目录下不存在“clean”这个文件时,我们输入“make clean”,“rm *.o temp”总会被执行。这是我们的初衷。
但是如果在当前工作目录下存在文件“clean”,情况就不一样了,同样我们输入 “make clean”,由于这个规则没有任何依赖文件,所以目标被认为是最新的而不去执 行规则所定义的命令,因此命令“rm”将不会被执行。这并不是我们的初衷。为了解 决这个问题,我们需要将目标“clean”声明为伪目标。将一个目标声明为伪目标的方 法是将它作为特殊目标.PHONY”的依赖
修改makefile文件:

app:divi.o plus.o main.o minus.o multi.o
    gcc divi.o plus.o main.o minus.o multi.o -o app
divi.o:divi.c
    gcc -c divi.c
plus.o:plus.c
    gcc -c plus.c
main.o:main.c
    gcc -c main.c
minus.o:minus.c
    gcc -c minus.c
multi.o:multi.c
    gcc -c multi.c
.PHONY:clean
clean:
    rm -f *.o

然后make clean命令就可以正常工作了,就是目录中存在一个名字为clean的文件。

定义变量与通配符

定义变量

在实际工作中大家都比较认同的方法是,使用一个变量 “objects”、“OBJECTS”、“objs”、“OBJS”、“obj”或者“OBJ”来作为所有的.o 文 件的列表的替代。

模式规则

在模式规则中,目标文件是一个带有模式字符“%”的文件,使用模式来匹配目标文件。文件名中的模式字符“%”可以匹配任何非空字符串,除模式字符以外的部分要 求一致。例如:“%.c”匹配所有以“.c”结尾的文件(匹配的文件名长度最少为3个字 母),“s%.c”匹配所有第一个字母为“s”,而且必须以“.c”结尾的文件,文件名长度 最小为5个字符(模式字符“%”至少匹配一个字符)。

自动化变量

$@
表示规则的目标文件名,如果目标是一个文档文件(Linux中,一般称.a文件为 文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式 规则中,它代表的是哪个触发规则被执行的目标文件名

$%
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则 的目标是“foo.a(bar.o)”,那么,“$%”的值就为“bar.o”,“$@”的值为“foo.a”。 如果目标不是静态库文件,其值为空。

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

$?
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代表的是库成员(.o文件)。

$^
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的 只能是所有库成员(.o文件)名。一个文件可重复的出现在目标的依赖中,变量 “$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件

还有好多,就简单了解这几个吧。
现在利用定义变量、通配符、自动化变量的方式来简化上面的makefile文件。
于是上面的makefile就可以简化为:

objects=divi.o plus.o main.o minus.o multi.o
app:$(objects)
    gcc $(objects) -o app
%.o:%.c
    gcc -c $^ -o $@
.PHONY:clean
clean:
    rm -f *.o
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容