一起来看神奇的Makefile

什么是Makefile?如果你是熟练运用各大集成开发环境的程序猿可能对这个不是太了解,因为Makefile的工作IDE都已经给你做了,如果你是在Linux下编程,那Makefile你就再熟悉不过了。什么?你说你不是程序猿?那你点进来干嘛,出去出去!
Makefile主要就是管理整个工程的编译、链接,比如说一个.c文件你要先用GCC编译成.o,然后多个.o再链接成可执行文件,如果你写好一个Makefile,那么你只需要在控制台输入一个make回车就好了。虽然各个厂商的Makefile语法会有写区别,但大体是类似的,这里就不多做区分了,本文是一个大杂烩。

结构

一般在工程是根目录下会有一个主Makefile文件作为编译入口,在控制台输入make后执行的就是这个文件,在子目录中也有一个Makefile文件,每个Makefile文件管理自己所在的目录(当然,这不是绝对的)。

语法

符号

**\ **: 反斜杠,指下一行还算本行,有时单行太长会进行换行,但Makefile语法上换行就是一条语句的结束了,为了代码阅读方便会在行末使用一个“\”来进行换行
$:取变量的值,如var := 123 那么 $(var)就表示var这个变量的值,也就是123(变量可以不加括号,但一般都加)若要表示$时则用两个$表示($$)
=: 是最基本的赋值,但值是整个文件最后一次赋值的值,如a=1 b=$(a) a=2,此时b的值为2(比较奇葩所以一般不用)
:=: 是覆盖之前的值,依赖与当前所在位置,如a:=1 b=$(a) a:=2,此时b的值为1(比较常见的赋值逻辑,常用的赋值方式)
?=: 是如果没有被赋值过就赋予等号后面的值,如果赋值过就不再赋值(一般用于参数的默认值,Makefile间可以传参)
+=: 是添加等号后面的值,连接之后中间会有一个空格,如 a=abc a+=def,a的值为abc def(一般用于添加依赖文件)

关键字

ifeq ifneq ifdef ifndef else endif 想必这些不用解释吧
include:包含文件,即在所在位置展开文件,和c文件包含头文件类似,如果找不到且Makefile不会创建这个文件,那么编译报错(No such file or directory)
-include:类似include,但找不到文件时不报错
sinclude:同-include,GNU所支持的书写方式

函数

函数的调用方法:很像变量的使用,也是以“$”来标识的,参数间用“,”隔开
$(<function> <arguments1>,<arguments2>... )
$(subst <from>,<to>,<text>):字符串替换,把字串<text>中的<from>字符串替换成<to>,返回替换后的字符串
$(strip <string>):去掉<string>字串中开头和结尾的空字符
$(findstring <find>,<in>):在字串<in>中查找<find>字串,如果找到,那么返回<find>,否则返回空字符串
$(filter <pattern>,<text>):过滤器,将<text>集中符合<pattern>的过滤出来。如$(filter %.o,a.o a.c a.h)结果为a.o
$(dir <names...>):从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之
前的部分。如果没有反斜杠,那么返回“./”。如$(dir src/foo.c hacks)返回值是“src/ ./”
$(notdir <names...>):从文件名序列<names>中取出文件名。即最后一个反斜杠“/”之后的部分
$(suffix <names...>):从文件名序列<names>中取出各个文件名的后缀
$(basename <names...>):从文件名序列<names>中取出各个文件名的前缀。如$(basename src/foo.c)结果为src/foo
$(foreach <var>,<list>,<text>):把参数<list>中的单词逐一取出放到参数<var>变量中,然后再执行<text>表达式。每一次<text>会返回一个字符串,循环结束后,<text>的所返回字符串以空格分隔连接成新的字符串返回。如names:= a b c d $(foreach n,$(names),$(n).o)结果为“a.o b.o c.o d.o”
$(if <condition>,<then-part>,<else-part>):if函数,<condition>为空时返回<then-part>否则返回<else-part>
$(wildcard <string>):基于当前目录使用通配符列出所有文件
$(patsubst <pattern>,<replacement>,<text>):使用通配符替换字符串。如$(patsubst %.c,%.o,a.c b.c)结果为a.o b.o
$(shell <cmd>):执行Linux的shell命令
$(lastword <names...>):返回最后一个字串。如$(lastword foo bar)返回bar
$(call <expression>,<parm1>,<parm2>,<parm3>...):函数调用,<expression>中的变量,如$(1),$(2),$(3)等,会被参数<parm1>,<parm2>,<parm3>取代。<expression>的返回值就是call函数的返回值。如$(call $(1) $(2),a,b)结果为“a b”
$(eval <text>):将text放回Makefile文件当成Makefile脚本再解析一遍。这个有点绕,如$(eval aa:aa.c)相当于直接写aa:aa.c,这个的意义在于aa:aa.c这个字串是可以由Makefile脚本生成的
$(error <text ...>):产生一个致命的错误,<text ...>是错误信息
$(warning <text ...>):产生一个警告,<text ...>是警告信息

命令的变量

Makefile会有一些隐含规则,如.o文件依赖于.c文件,这个我们可以不写,会自动调用编译C程序的隐含规则的命令“$(CC) –c $(CFLAGS) $(CPPFLAGS)”来生成,这里用到的变量值是可以设置的(一般用来更改默认编译器)

AR 函数库打包程序。默认命令是“ar”。
AS 汇编语言编译程序。默认命令是“as”。
CC C语言编译程序。默认命令是“cc”。
CXX C++语言编译程序。默认命令是“g++”。
CO 从 RCS文件中扩展文件程序。默认命令是“co”。
CPP C程序的预处理器(输出是标准输出设备)。默认命令是“$(CC) –E”。
FC Fortran 和 Ratfor 的编译器和预处理程序。默认命令是“f77”。
GET 从SCCS文件中扩展文件的程序。默认命令是“get”。
LEX Lex方法分析器程序(针对于C或Ratfor)。默认命令是“lex”。
PC Pascal语言编译程序。默认命令是“pc”。
YACC Yacc文法分析器(针对于C程序)。默认命令是“yacc”。
YACCR Yacc文法分析器(针对于Ratfor程序)。默认命令是“yacc –r”。
MAKEINFO 转换Texinfo源文件(.texi)到Info文件程序。默认命令是“makeinfo”。
TEX 从TeX源文件创建TeX DVI文件的程序。默认命令是“tex”。
TEXI2DVI 从Texinfo源文件创建军TeX DVI 文件的程序。默认命令是“texi2dvi”。
WEAVE 转换Web到TeX的程序。默认命令是“weave”。
CWEAVE 转换C Web 到 TeX的程序。默认命令是“cweave”。
TANGLE 转换Web到Pascal语言的程序。默认命令是“tangle”。
CTANGLE 转换C Web 到 C。默认命令是“ctangle”。
RM 删除文件命令。默认命令是“rm –f”。
MAKE 即make

ARFLAGS 函数库打包程序AR命令的参数。默认值是“rv”。
ASFLAGS 汇编语言编译器参数。(当明显地调用“.s”或“.S”文件时)。
CFLAGS C语言编译器参数。
CXXFLAGS C++语言编译器参数。
COFLAGS RCS命令参数。
CPPFLAGS C预处理器参数。( C 和 Fortran 编译器也会用到)。
FFLAGS Fortran语言编译器参数。
GFLAGS SCCS “get”程序参数。
LDFLAGS 链接器参数。(如:“ld”)
LFLAGS Lex文法分析器参数。
PFLAGS Pascal语言编译器参数。
RFLAGS Ratfor 程序的Fortran 编译器参数。
YFLAGS Yacc文法分析器参数。

MAKEFILE_LIST make程序在读取makefile文件的时候将文件名加入此变量,多个文件用空格隔开

显示命令

在命令前面加@符号表示执行时不显示命令只显示输出。如"@echo 这是输出字符"在样在控制台只输出"这是输出字符"如果不加@则会输出"echo 这是输出字符"后换行再输出"这是输出字符"

注:未完待续

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,657评论 18 139
  • 来自陈浩的一片老文,但绝对营养。 示例工程:3 个头文件*.h,和 8 个 C 文件*.c。 初 编译过程,源文件...
    周筱鲁阅读 4,696评论 0 17
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,168评论 2 33
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,271评论 9 467
  • 需要按照互联网的逻辑进行相关的用户运营即可,而已经积累下来的很多的运营经验完全能够胜任共享出行的用户运营工作。但是...
    营养学大百科阅读 187评论 0 0