makefile 必知必会

原创 2013年12月02日 22:54:39

Makefile 必知必会

Makefile的根本任务是根据规则生成目标文件。

规则

一条规则包含三个:目标文件,目标文件依赖的文件,更新(或生成)目标文件的命令。

规则:                

<目标文件>:<依赖文件>

         <更新目标的命令 

PS:更新目标命令必须以tab开头,这个有点恶心。

Example     

             hello.o: hello.chello.h   

                      gcc -c hello.c -o hello.o

      目标hello.o 依赖于hello.c,hello.h. 生成hello.o的命令时是“gcc -c hello.c -o hello.o”

 

伪目标

一般情况下目标文件是一个具体的文件,但有时候我们只需要一个标签,如目标clean。

声明伪目标:   

.PHONY:  <伪目标>

伪目标只是一个标签,这意味着伪目标的时间戳总是最新的,结果就是makefile每次都会去执行更新伪目标的命令。

 

终极目标

makefile并不会更新所有规则中的目标,它只会更新终极目标以及终极目标依赖的目标。

默认情况下makefile的第一个目标是终极目标,而且大家约定俗成的总是将all作为第一个目标。环境变量MAKECMDGOALS记录着终极目标。

 

PS:你也可以在make的命令行参数中指定终极目标。如make clean表示以clean作为终极目标。

 

多规则目标

Makefile中,一个文件可以作为多个规则的目标,这种情形就是多规则目标。

多规则目标下,以这个文件为目标的所有规则的依赖文件将会被合并成此一个依赖文件列表,但是命令不会合并,而且实际上,这多个规则中至多只能有一个规则定义了更新命令。

allhello.o            

allhello.h            

等价于  all: hello.o hello.h

 

什么时候更新目标

如果目标不存在或者依赖文件中至少有一个文件的时间戳比目标新,则执行目标更新命令。

 

 

包含其他makefile

类似于C语言中的头文件包含,makefile也可以包含其他makefile。

格式:        

include<makefile>

与C语言不同的是,包含其他makefile不只是把其他makefile中的内容导入到当前makefile中,而且它还有一个附加行为,具体参看下面makefile执行步骤:

1.  依次读取变量“MAKEFILES”定义的makefile文件列表

2.  读取工作目录下的makefile文件(根据命名的查找顺序“GNUmakefile”,“makefile”,“Makefile”,首先找到那个就读取那个)

3.  依次读取工作目录makefile文件中使用指示符“include”包含的文件

4.  查找重建所有已读取的makefile文件的规则
  (如果存在一个目标是当前读取的
某一个makefile文件,则执行此规则重建此makefile文件, 完成以后从第一步开始重新执行)

 

 

自动生成头文件依赖关系

C,C++的源文件编译依赖于头文件,手工维护这个头文件依赖列表无疑是琐碎而易错。这里可以利用gcc自带命令自动产生依赖文件列表,然后利用include命令导入即可。

%.o: %.c

    $(GCC) -MMD -MP -MF"$(@:%.o=%.d)"-MT"$@" -MT"$(@:%.o=%.d)" -o "$@""$<"

这个命令比较复杂,有兴趣的同学可以自己私下搜索一下。这里我只说一下结果:

如果我们要编译 hello.o,  而hello.c中包含头文件hello.h。那么执行上面命令的结果是生成hello.d,其内容是

         hello.o hello.d : hello.c hello.h

于是只要再加上include  hello.d,自然而然地就有hello.o依赖关系。


GCC -M,-MM,-MMD,-MF,-MT

GCC的命令参数有很多,下面主要介绍几个M相关的:-M生成文件关联的信息。包含目标文件所依赖的所有源代码,下面是测试log:jack@jxes-VirtualBox:~/samba_share/tmp...
  • js_gary
  • js_gary
  • 2017年07月17日 11:21
  • 1675

通用makefile是如何炼成的(IV)

要解决这个头文件依赖关系的自动推导问题,呵呵,GNU中直接有尚方宝剑MMD,MF, MT。 走到这里,感觉人生已经无欲无求了,通用makefile真的已经通用了。However,我又是看得太远,看这段...
  • crylearner
  • crylearner
  • 2013年12月24日 22:05
  • 1678

Makefile 实际用例分析(一) ------- 比较通用的一种架构

这里不再说Makefile的基本知识,如果需要学习,那么请参考: 下载:makefile 中文手册 或者 点击打开链接 或者 跟我一起写Makefile( 陈皓 ) 这里说的是一般的实际的一个工...
  • shanshanpt
  • shanshanpt
  • 2013年12月08日 12:20
  • 5457

Linux Makefile生成*.d依赖文件及 gcc -M -MF -MP等相关选项说明

1. 为什么要使用*.d依赖文件?在 Makefile 中, 我们的依赖关系可能会需要包含一系列的头文件,比如, main.c 中有一句“#include “defs.h””,那么我们的依赖关系应该是...
  • QQ1452008
  • QQ1452008
  • 2016年03月11日 14:21
  • 2357

makefile自动生成依赖关系

手工编写依赖关系不仅工作量大而且极易出现遗漏,更新也很难
  • heron804
  • heron804
  • 2012年04月04日 20:23
  • 6715

makefile .d的解释

在学写makefile时候,如果要写的好一点高手建议要用个.d文件.我那时候也是非常迷糊,我写的测试代码不用这个也照样运行的很好啊,为什么要写这个东西呢?下面先看这个情况.我们写的这个Makefile...
  • shareyao
  • shareyao
  • 2010年05月20日 11:25
  • 10279

通用makefile是如何炼成的(IV)

要解决这个头文件依赖关系的自动推导问题,呵呵,GNU中直接有尚方宝剑MMD,MF, MT。 走到这里,感觉人生已经无欲无求了,通用makefile真的已经通用了。However,我又是看得太远,看这段...
  • crylearner
  • crylearner
  • 2013年12月24日 22:05
  • 1678

makefile 自动生成头文件依赖关系

在使用makefile 自动生成头文件依赖是,大家多半使用了下面这个方法。 sinclude $(CUR_OBJS:.o=.d) %.d:%.c @set -e; rm -f $@; \ ...
  • maxzero
  • maxzero
  • 2016年10月26日 16:20
  • 832

Linux Makefile生成*.d依赖文件及 gcc -M -MF -MP等相关选项说明

1. 为什么要使用*.d依赖文件?在 Makefile 中, 我们的依赖关系可能会需要包含一系列的头文件,比如, main.c 中有一句“#include “defs.h””,那么我们的依赖关系应该是...
  • QQ1452008
  • QQ1452008
  • 2016年03月11日 14:21
  • 2357

Unity3D游戏开发之MMD For Unity插件研究

今天想来说说MMD。MMD是MikuMikuDance的简称,是由日本人樋口优开发的一组3D动画制作软件。该软件最初希望能够将3D建模软件完成的VOCALOID的初音未来等角色模型制作成可以随着音乐跳...
  • qinyuanpei
  • qinyuanpei
  • 2015年04月21日 14:34
  • 10852
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:makefile 必知必会
举报原因:
原因补充:

(最多只允许输入30个字)