Linux Makefile

Makefile的基本概念

GNU make最初是Unix系统下的一个工具,设计之初是为了维护C程序文件不必要的重新编译,他是一个自动生成和维护目标程序的工具
make是一个解释Makefile文件中指令的命令工具,其最基本的功能就是通过Makefile文件来描述源程序之间的相互关系并自动维护编译工作,他会告知系统以何种方式编译和链接程序。
Makefile写好之后,每次改变了某些源文件只要执行make命令($ make
所有必要的重新编译将执行,make程序利用Makefile中的数据和每个文件的最后修改时间来确定哪个文件需要更新,对于需要更新的文件,make程序执行Makefile数据中的定义的命令来更新。

GNU make的主要功能是读进一个文本文件Makefile,并根据Makefile的内容执行一系列工作。

Makefile的默认文件名为GNUmakefile、makefile或Makefile,当然也可以在make命令行中指定别的文件名。如果不特别指定,make命令在执行时,将按照顺序查找默认的makefile文件。

Makefile是一个文本形式的数据库文件,其中包含了一些规则,来告诉make处理哪些文件以及如何处理这些文件。

这些规则主要是描述哪些文件(target目标文件)是从哪些别的文件(dependency依赖文件)中产生而来的,以及用什么命令(command)来执行这个过程

依靠这些信息,make会对磁盘上的文件进行检查,如果目标文件的生成或被改动时的时间(文件的时间戳)至少比它的一个依赖文件还旧的话,make就执行相应的命令,已更新目标文件。目标文件不一定是最后的可执行文件,可以是任何一个中间文件并可以作为其他目标文件的依赖文件。

GNU make工作流程

  1. 查找当前目录下的Makefile文件
  • 初始化文件中的变量
  • 分析Makefile中的所有规则
  • 为所有的目标文件创建依赖关系
  • 根据依赖关系,决定哪些文件重新生成
  • 执行生成命令

一个Makefile文件主要有一系列规则,每条规则都必须包含以下内容:

  1. 一个目标(target),即make最终需要创建的文件,如可执行文件或目标文件,目标也可以是要执行的动作,如clean
  • 一个或多个依赖文件(dependency)列表,通常是编译目标文件所需要的其他文件
  • 一系列命令(command),是make执行的动作,通常是把指定的相关文件编译成目标文件的编译命令,每个命令占一行,并且每个命令的起始字符必须为Tab字符。
Makefile文件

图中,蓝绿色的为目标,白色的为依赖文件,红色的为命令,蓝色的为注释

目录文件结构
执行make后生成的文件以及可执行程序
执行makefile中定义的clean
修改了部分文件,只会对编辑的文件进行修改
重复编译会提示

make命令

标准形式:$ make [选项] [宏定义] [目标文件]

  • 常用选项
    1. -f:file,指定Makefile的文件名
指定Makefile文件
  • -n:打印出所有的执行命令,但事实上不执行这些命令

    显示命令,但不执行

  • -s:在执行时不打印命令名

不显示执行信息
  • -w:如果在make执行时要改变目录,则打印当前的执行目录
  • -d:打印调试信息
  • -I <dirname> :指定所用Makefile所在的目录
  • -h:help文档

Makefile目标文件

参数“目标文件”,对于make命令来说,也是一个可选项,如果在执行make命令时带有该参数,可以输入一下命令:$ make 目标文件
如果省略目标文件参数,就会生成Makefile中定义的第一个目标文件。因此,常见的用法就是经常把用户最终想要的目标文件(可执行程序)放在Makefile文件的首要位置,这样用户只需要执行make命令即可。

单独执行hello.o的相关指令

Makefile规则语法

  • 语法规则
#注释
目标文件:依赖文件列表
<Tab>命令列表
#.......

注释:和shell脚本一样,Makefile语句行的注释采用"#"符号
目标:目标文件的列表,通常指程序编译过程中生成的目标文件(.o文件)或最终的可执行程序,有时也可以是要执行的动作,如“clean”这样的目标

Makefile中变量的使用

Makefile中的变量就像一个环境变量。事实上,环境变量在make中也被解释为make的变量。这些变量对大小写敏感,一般使用大写字母。几乎可以从任何地方引用定义的变量。

  • 变量的主要作用:
    • 保存文件名列表。
      在前面的例子里,作为依赖文件的一些目标文件出现在可执行文件的规则中,而在这个规则的命令行里同样包含这些文件并传递个gcc作为命令参数。如果使用一个变量来保存所有的目标文件名则可以方便的加入新的目标文件而且不易出错。
    • 保存可执行命令名(如编译器)
      在不同的Linux系统中,存在着很多相似的编译器系统,这些系统在某些地方会有细微的差别,如果项目被用在一个非gcc的系统里,则必须将所有出现编译器名的地方改成用新的编译器名。但是如果使用一个变量来替代编译器名,那么只需要修改变量的值。其他所有地方的命令就都改变了。(有点类似与C/C++中的typedef,程序中将int定义为num,后期需要更换为short或者double,只需要修改typedef的值,而不需要修改所有的变量定义)
    • 保存编译器的参数
      在很多源代码编译时,gcc需要很长的参数选项,在很多情况下,所有的编译器命令使用一组相同的选项,如果把这组选项使用一个变量代表,那么可以把这个变量放在所有的引用编译器的地方,当药修改选项的时候,只需要修改一次这个变量的内容即可。
  • Makefile文件中变量的使用
    Makefile中的变量是一个用文本串在Makefile中定义的,这个文本串就是变量的值。只要在一行开始写下这个变量的名字,后面跟一个“=”好,以及要设定这个变量的值,即可定义变量,下面是定义变量的语法:VAENAME=string
    使用是,把变量用括号括起来,并在前面加上“$”符号,就可以引用变量的值:$(VARNAME)
使用变量来写的Makefile文件

make命令执行结果

make工具还有一些特殊的内部变量,根据每一个规则内容定义。
$@:指代当前规则下的目标文件列表
$<:指代以来文件列表中的第一个依赖文件
$^:指代以来文件中的所有依赖文件
$?:纸袋以来列表中新于对应目标文件的列表
使用特殊的内部变量修改Makefile文件

使用特殊内部变量来make项目测试

Make自动推导

GNU的make功能很强大,它可以自动推导文件以及文件的依赖关系后面的命令,浴室我们就没必要去为每一个".o"文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。
只要make看到一个.o文件,他就会自动的把“.c”文件加在依赖关系中,如果马克找到一个test.o,那么test.c就会是test.o的依赖文件,并且在gcc -c test.c也会被推导出来。

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

推荐阅读更多精彩内容

  • 来自陈浩的一片老文,但绝对营养。 示例工程:3 个头文件*.h,和 8 个 C 文件*.c。 初 编译过程,源文件...
    周筱鲁阅读 4,605评论 0 17
  • makefile关系到整个工程的编译规则,一个工程中的源文件不计其数,按其类型、功能、模块分别放在若干的目录当中,...
    Joe_HUST阅读 1,841评论 0 3
  • @(linux 编程)[开发技能, 工具使用] What is GNU Make Make 是控制工程中通过源码生...
    orientlu阅读 11,264评论 0 26
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 98,514评论 9 468
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,016评论 2 34