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中,一个文件可以作为多个规则的目标,这种情形就是多规则目标。

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

all:hello.o

all:hello.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依赖关系。

makefile 必知必会的更多相关文章

  1. makefile 必知必会以及Makefile是怎样炼成的

    Make必知必会原文链接 Makefile 必知必会 Makefile的根本任务是根据规则生成目标文件. 规则 一条规则包含三个:目标文件,目标文件依赖的文件,更新(或生成)目标文件的命令. 规则: ...

  2. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  3. 读书笔记--SQL必知必会--建立练习环境

    书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL in 10 Minutes - Fourth Edition> MyS ...

  4. 读书笔记--SQL必知必会12--联结表

    12.1 联结 联结(join),利用SQL的SELECT在数据查询的执行中联结表. 12.1.1 关系表 关系数据库中,关系表的设计是把信息分解成多个表,一类数据一个表,各表通过某些共同的值互相关联 ...

  5. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  6. 《MySQL 必知必会》读书总结

    这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...

  7. 《SQL必知必会》学习笔记(一)

    这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...

  8. SQL 必知必会

    本文介绍基本的 SQL 语句,包括查询.过滤.排序.分组.联结.视图.插入数据.创建操纵表等.入门系列,不足颇多,望诸君指点. 注意本文某些例子只能在特定的DBMS中实现(有的已标明,有的未标明),不 ...

  9. .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)

    Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会.尽管这一系列是使用.NET/C# ...

随机推荐

  1. UVA 270 Lining Up 共线点 暴力

    题意:给出几个点的位置,问一条直线最多能连过几个点. 只要枚举每两个点组成的直线,然后找直线上的点数,更新最大值即可. 我这样做过于暴力,2.7s让人心惊肉跳...应该还能继续剪枝的,同一直线找过之后 ...

  2. 设计模式 - 单例模式mysql数据库操作类

    待续... index.php 调用方法: <?php header('Content-Type:text/html; charset=utf8'); require 'instance.php ...

  3. 已经上架的app(可供销售)在AppStore上搜不到的解决办法

    这两天很是头大, 因为3天前手动发布的app到现在都还没在AppStore上看到,打了无数电话给苹果和发邮件给review团队. 下面说说怎么解决我们在iTunes后台看到是绿灯(可供销售)但是就是在 ...

  4. 直播时代--IOS直播客户端SDK,美艳直播【开源】

    看到该文章我非常喜欢,为了方便自己查看和参考所以将其复制过来,源文地址:http://www.cnblogs.com/runner42/p/5241407.html 请支持原作者.原作者如看到请原谅复 ...

  5. C++中,引用作为函数参数

    引用作为函数参数 C++之所以增加引用类型, 主要是把它作为函数参数,以扩充函数传递数据的功能. ———————————————————— c++,函数传参:(1)将变量名作为实参和形参.这时传给形参 ...

  6. Android 中 关闭部分 Activity 的方法总结

    每一个activity都有自己的生命周期,被打开了最终就要被关闭. 四种结束当前的activity方法 但如果已经启动了四个Activity:A,B,C和D, 在D Activity里,想再启动一个A ...

  7. 基于visual Studio2013解决算法导论之046广度优先搜索

     题目 广度优先搜索 解决代码及点评 // 图的邻接表表示.cpp : 定义控制台应用程序的入口点. // #include <iostream> #include <stac ...

  8. TCP和UDP的"保护消息边界" (经典)

    在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有 ...

  9. busybox 致命错误: curses.h:没有那个文件或文件夹

    $:~/dd/busybox-1.19.3$ make menuconfig   HOSTCC  scripts/basic/fixdep   HOSTCC  scripts/basic/split- ...

  10. C#如何在panl控件上添加Form窗体

    . if (treeView1.SelectedNode.Text == "个人信息") { Form1 f4 = new Form1(); f4.TopLevel = false ...