简介

  Gnu Make主要用于构建和管理程序包。Makefile文件描述了整个工程的编译、连接等规则。

其中包括:

    工程中的哪些源文件需要编译以及如何编译;

    需要创建那些库文件以及如何创建这些库文件;

    如何最后产生我们想要得可执行文件。

  make是一个命令工具,它解释Makefile中的指令(应该说是规则),Makefile中描述了工程中所有文件的编译顺序、规则。

Makefile有自己的书写格式、关键字、函数。像C语言有自己的格式、关键字和函数一样。

而且在Makefile中可以使用shell所提供的任何命令来完成你想要的工作。

详细请看《GNU make中文手册》。

1.make规则

 工程中以下几种文件在执行make时将会被编译:

  所有的源文件没有被编译过,则对各个C源文件进行编译并进行链接,生成最后的可执行程序。

每一个在上次执行make之后修改过的C源代码文件在本次执行make时将会被重新编译。

头文件在上一次执行make之后被修改。则所有包含此头文件的C源文件在本次执行make时将会被重新编译。

一个简单的Makefile描述规则组成:

TARGET... : PREREQUISITES...

              COMMAND

              ...

              ...

target:规则的目标。通常是程序中间或者最后需要生成的文件名。可以是.o文件、也可以是最后的可执行程序的文件名。

另外,目标也可以是一个make执行的动作的名称,如目标“clean”,“all”,称为伪目标。

prerequisites:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。

command:规则的命令行。是make程序所有执行的动作(任意的shell命令或者可在shell下执行的程序)。一个规则可以有多个命令行,每一条命令占一行。

注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉make此行是一个命令行

make按照命令完成相应的动作。这也是书写Makefile中容易产生,而且比较隐蔽的错误。

2. make命名

  make工具搜索的makefile名字次序是”GNUmakefile”、”makefile”、”Makefile”。

3.包含其他的makefile文件

include filename

如include $(SD)/config/rules.mk

找不到文件将提示错误,如果用-include 将忽略错误,继续make执行。

4.makefile执行过程

  1. 依次读取一些特殊环境变量
  2. 读取makefile文件内容
  3. 依次读取工作目录makefile文件中使用指示符“include”包含的文件
  4. 查找重建所有已读取的makefile文件的规则(如果存在一个目标是当前读取的某一个makefile文件,则执行此规则重建此makefile文件,完成以后从第一步开始重新执行。
  5. 初始化变量值并展开那些需要立即展开的变量和函数并根据预设条件确定执行分支
  6. 根据“终极目标”以及其他目标的依赖关系建立依赖关系链表
  7. 执行除“终极目标”以外的所有的目标的规则(规则中如果依赖文件中任一个文件的时间戳比目标文件新,则使用规则所定义的命令重建目标文件)
  8. 执行“终极目标”所在的规则

5.makefile语法要点

  1. 变量和函数引用

   $(variable)

2.变量赋值与展开

   := 表示立即展开,其他赋值表示延后展开,目标重建时才展开。

  3.通配符

   *匹配一个或多个的字符

   ?匹配一个字符

   由于变量定义时通配符不会立即展开,需要使用wildcard让其有效。即$(wildcard *.c)即获取所有以.c为后缀的文件名。

  4.搜索路径变量VPATH

   指Makefile中所有文件的搜索路径,包括依赖文件和目标文件。以空格或者“:”隔开。

   当前目录永远都是第一个要搜索的目录。

5.自动化变量

   $@ 表示目标文件

   $% 规则的目标文件是一个静态库文件时,代表静态库的一个成员名

   $< 规则的第一个依赖文件名。如果是隐含规则,则它代表通过目标指定的第一个依赖文件

   $? 所有比目标文件更新的依赖文件列表,空格分割

   $^ 规则的所有依赖文件列表,使用空格分隔

  6.隐含模式

   $(OBJ_C) : %.o : %.c

@echo $(SRC_C)

$(CC) $(CC_OPTS) -o   $@ $<

  表示:重建的目标是$(OBJ_C_32),对目标中的每一个文件,其后缀是.o,将会用对应的.c来重建,重建的命令是$(CC) $(CC_OPTS) -o $@ $<。-o $@表示输出文件名,$<规则的第一个依赖文件名,是.c文件。

7.伪目标

   伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时我们也可以将一个伪目标称为标签。

  如”all”, “clean”等。需用关键字.PHONY定义:

.PHONY : clean

这样,我们可以直接make clean执行这个伪目标。

直接执行make时,会默认执行all这个伪目标,如果all不存在,则执行第一个遇到的目标

8.命令回显

   执行命令前加@即不回显,否则回显。

9.命令行选项

   -B 强制重建所有目标

   -C DIR 在读取makefile之前,把工作目录切换到DIR

   -f=FILE/--file=FILE/--makefile=FILE 指定”FILE”是makefile

   -i 忽略规则命令执行错误

   -k/--keep-going 执行命令错误时不终止make执行,让其一次性编译所有模块后再来修改。

   -n/--just-print只打印执行命令,不执行。

   -t/--touch更新目标文件的时间戳到当前系统时间。

GNU Makeflie的更多相关文章

  1. 感悟 GNU C 以及将 Vim 打造成 C/C++ 的半自动化 IDE

    C 语言在 Linux 系统中的重要性自然是无与伦比.不可替代,所以我写 Linux 江湖系列不可能不提 C 语言.C 语言是我的启蒙语言,感谢 C 语言带领我进入了程序世界.虽然现在不靠它吃饭,但是 ...

  2. 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码

    不可否认,这次的标题有点长.之所以把标题写得这么详细,主要是为了搜索引擎能够准确地把确实需要了解 GCC 生成 16 位实模式代码方法的朋友带到我的博客.先说一下背景,编写能在 x86 实模式下运行的 ...

  3. 在 Linux 中使用 Eclipse 和 Gnu Autotools 管理 C/C++ 项目

    在我该系列的之前的所有随笔中,都是采用 Linux 发行版自带的包管理工具(如 apt-get.yum 等)进行软件的安装和卸载,从来没有向大家展示使用源代码自行编译安装软件的方法.但是长期混迹于 U ...

  4. GNU Readline 库及编程简介

    用过 Bash 命令行的一定知道,Bash 有几个特性: TAB 键可以用来命令补全 ↑ 或 ↓ 键可以用来快速输入历史命令 还有一些交互式行编辑快捷键: C-A / C-E 将光标移到行首/行尾 C ...

  5. GNU Radio Radar Toolbox

    GNU Radio Radar Toolbox Install guide Change to any folder in your home directory and enter followin ...

  6. gnu coreutils-8.25 for win32 static - Beta

    gnu.win32-coreutils-8.25.7z 2.7 Mb bc-1.06.tar.gz coreutils-8.25.tar.xz diffutils-3.5.tar.xz gawk-4. ...

  7. window下搭建c开发环境(GNU环境的安装)

    一.在windows平台上安装GNU环境 windows操作系统不自带GNU环境,如果需要开发跨平台的C语言程序,那么需要给windows安装GNU环境 windows下的两款GNU环境:MinGW和 ...

  8. GNU make使用变量⑤变量的引用、定义等

    在 Makefile 中,变量是一个名字(像是 C 语言中的宏),代表一个文本字符串(变量的值).在 Makefile 的目标.依赖.命令中引用变量的地方,变量会被它的值所取代(与 C 语言中宏引用的 ...

  9. (转)完全用GNU/Linux工作 by 王珢

    完全用GNU/Linux工作 王珢      (看完这篇博文,非常喜欢王珢的这篇博客,也我坚定了学gnu/linux的决心,并努力去按照国外的计算机思维模式去学习编程提高自己.看完这篇文章令我热血沸腾 ...

随机推荐

  1. bzoj1853: [Scoi2010]幸运数字 dp+容斥原理

    在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是 ...

  2. php那些坑

    1.创建数组不是new array(),是$aaa=array(),没有new,数组可以传入键值$aaa=array("key"=>"value"); 2 ...

  3. uva 11995 判别数据类型

    Problem I I Can Guess the Data Structure! There is a bag-like data structure, supporting two operati ...

  4. [MFC] TabControl选项卡的使用

    MFC中,因项目需要使用TabControl ,使用过程中发现,MFC中的TabControl与C#的TabControl不同,不能通过属性来创建选项页,只能代码生成绑定. 以下为具体的实现方法步骤: ...

  5. Java 模板权重随机

    Template templates=...// 所有的模板 final int _weights=1000; // 所有的模板权重 Template _template=null; //随机一个权重 ...

  6. Redis数据结构之字典

    Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对. 一.字典结构定义1. 哈希表节点结构定义: 2. 哈希表结构定义: 3. 字典 ...

  7. Day 7 Linux之系统监控、硬盘分区等

    Linux之系统监控.硬盘分区等 系统监控 系统监视和进程控制工具—top和free 1) 掌握top命令的功能:top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况, ...

  8. Codeforces 451 E Devu and Flowers

    Discription Devu wants to decorate his garden with flowers. He has purchased n boxes, where the i-th ...

  9. 心脏滴血漏洞复现(CVE-2014-0160)

    漏洞范围: OpenSSL 1.0.1版本 漏洞成因: Heartbleed漏洞是由于未能在memcpy()调用受害用户输入内容作为长度参数之前正确进 行边界检查.攻击者可以追踪OpenSSL所分配的 ...

  10. 同一页面引入多个JS文件的编码问题

    原来只是觉得IE解析HTML文件的时候,需要知道其传输编码,才能正确处理,而从来没有在意过JavaScript文件的编码问题.结果今天发现同一页面中的多个JavaScript文件如果保存编码不同,也会 ...