学习GNU Make

本文引用 http://hi.baidu.com/flying5/blog/item/2b53308ffdc857ff513d921f.html

学习GNU Make(1)

在GNU/Linux环境下, 使用make编译程序是个不错的选择. 较之IDE, make更灵活, 更健壮, 尤其对平台适应力强. 实际上, make在上实际七十年代就出现了, 它的年纪可比你我大许多. 许多大型项目(最著名的恐怕就是linux内核)都使用make进行管理.

在众多的make版本中, GNU make是最突出的, 它已成了当前的"标准"make. 所有的GNU/Linux平台上都有提供, 一些BSD的变种, Mac OS X甚至cygwin也都使用GNU Make. 所以选择GNU make学习, 编写makefile是不二选择.

关于GNU Make, 可以看看
这篇文章. 它摘录自 o'reilly的《GNU Make项目管理》, 这本书china-pub上有得卖, 薄薄280面, 定价却要¥58, 在此鄙视一下东南大学出版社  

OK, 现在步入正题, 这里假设你使用C语言进行编程.


预备知识


首先我们必须具有一些预备知识: 你知道什么叫编译, 什么叫连接吗? 目标文件和可执行文件有什么区别? 一个C源程序是如何转化为可执行程序的? 以往的IDE往往对C初学者隐藏了这些基础概念. 要使用Make, 这些概念是要清楚的.

另外, 你需要对GNU/Linux上的编译器具有一定的了解——当然是gcc啦! 因为Makefile中的命令实际上是针对编译器的命令.

可以参考本人blog的这两篇文章:
GNU/Linux平台的C程序开发及程序运行环境
GCC笔记

几个要说明的词汇
目标(target): 在makefile指定要生成的目标, 它可以是可执行文件, 目标文件, 也可以只是一个标签.

先决条件(prerequisite): makefile中指定的针对要生成某个target所依赖的文件或标号.

命令(command): Make针对target利用makefile中指定的规则所调用的命令. 它可以是你在shell中能够指定的所有命令.

GNU Make的工作原理


 

Make 通过 makefile文件被告知它的工作: 要生成怎样的目标文件? 由哪些代码编译生成?所以学习GNU Make实际上就是学习Makefile的写法. 下面是一个简单的makefile:

hello: hello.c
    gcc hello.c -o hello


我们熟悉的hello程序,
$ make
gcc hello.c -Wall -o hello

这样我们的hello可执行程序就出来了!

make的规则:
target: prereq1 prereq2
    commands


target就是目标文件, 它可能是,o文件, 可执行文件或标签中的一种.

关于target,有这样的约定:
如果某target被包含在执行make的命令行参数中, 则更新该target; 如果make没带参数, 则将第一个target作为默认目标进行更新.

prerequisites是生成target所需要的文件.

command是make调用gcc执行的指令. 注意, command以Tab键打头, 不能是空格!

到了这里, 就可以理解Make的原理了:

make的基本思想: 对于一个target (由命令行所指定或默认第一个target), 如果它不存在, 或者它的prerequisites中有比它更新的, 那么执行command所指定的命令.
所谓"更新", 是指比别的文件更晚被修改, make通过timestamp来记录谁更新.



makefile文件名


  1. 默认情况下, make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件.

  2. 最好不要用“GNUmakefile”, 这个文件只被GNU make识别. 虽然有些Make只对全小写的“makefile”文件名敏感, 但大多数的make都支持“makefile”和“Makefile”这两种默认文件名.

  3. 可以使用别的文件名来书写makefile, 比如: "Make.Linux", “Make.Solaris”, “Make.AIX”等. 如果要指定特定的Makefile,你可以使用make的“-f”或者“--file”参数,如:make -f Make.Linux 或 make --file Make.AIX.

推荐以 Makefile 作为文件名!



命令行中调用Make命令


(1) $ make target-name
(2) $ make
(3) $ make non-exist-target
(4) $ make -n   or $ make --just-print

(1) 如果在命令行中指定了target, 则make针对该target进行工作
(2) 如果未指定target, 则make对默认target进行操作.(Makefile中出现的第一个target)
(3) 如果指定的target不存在, 则make报错:

make: *** No rule to make target `non-exist-target'. Stop.

(4) 若加上 -n 或者 --just-print选项, make只是列出将要执行的命令, 并不执行它们. 这非常有用!


Makefile 的基本语法


Makefile 采用自上而下 (top-down)的组织, 最开始的target即"终极目标", 也是默认target. 观察make输出的命令可以发现, 它们的顺序与出现在Makefile中的命令刚好相反. 可以把Makefile中针对target的规则想象成C函数. 最开始的是main(), 然后依次调用相关的函数(即针对prereq调用相关的规则).

看看一个比较简单的Makefile规则:

target1 target2 target3 : prereq1 prereq2
    command1
    command2
    command3
  • 第一行列出了targets和prereqs, 注意目标与它们依赖的文件之间以" : "分隔. 目标或prereq之间以空格分隔.

  • 在冒号左边可以有1个或多个targets, 在冒号右边可以有0个或者多个prerequisites. 如果prerequisite的数目为0, 则只有当对应的target不存在时才执行命令.

  • 如果command不和目标, 先决条件在一行,那么它之前必须以Tab开头; 如果command与目标, 先决条件在一行, 那么它要以";"开头. Make将command传递给子shell去执行.

注意: 不要忘了在命令以Tab开头, 也别在不是命令开头的地方输入Tab, 否则Make会将它之后的字符当作命令.
  • Make中的注释符为 "#". #之前可以有空格, 从#开始到行尾的所有字符都会被忽略. 注意: 如果你把#写在了命令中, 包括#在内的行都会传递给shell, 会有什么样的结果取决于你所用的shell.

  • 可以在Makefile中使用转义字符 /, 我们都知道, 在命令行中, 可以使用 / 在下一行输入命令. 同样的, 在Makefile的所有行中, 都可以使用 / 来分割太长的语句.

    学习GNU Make (2): 规则

Makefile中指定了针对某个target的规则(rule). 注意Makefile中可以有多条规则: 即针对Makefile中的一条targets, prerequisites列表, 就有一条对应的规则.

规则指定了target: 要更新的目标, 及目标所依赖的先决条件, 并指定了更新目标所采取的行为: command.

如果prerequisites比target更新, 那么Make就利用Makefile中所指定的命令脚本来更新目标. 同样地, prerequisites也可能是另一条规则中的目标, Make会查看属于它的先决条件是否比它更新以执行它的规则中的命令脚本. 这类似于C中的函数调用, 在Make中, 这些依赖关系建立了"依赖图"(dependency graph).

关于target和prerequisite的依赖性, 我们可以理解它有两方面的含义:
(1) 要生成targets, 先要保证它依赖的prerequisites是最新的
(2) 保证prerequisites在在targets之前被更新.

规则包含两个部分, 一个是依赖关系, 一个是生成目标的方法. GNU Make支持五种规则: Explicit rules, Pattern rules, Implicit rules, Static pattern rules, Suffix rules. 后面会介绍它们. 在了解这些规则之前, 我们先弄清makefile中通配符, 伪目标, 变量, VPATH, vpath的用法.

通配符


在Makefile中可以使用通配符, GNU Make能够识别Bash的通配符(参考《学习Bash》, p22):
~       : 当前用户的home目录
~zp    : 用户zp的home目录
*.o      : 所有的目标文件
?         : 单个字符
[abc]   : a, 或b, 或c
[a-zA-Z]: 所有大小写字母
[!0-9] : 所有的非数字

最好不要使用*通配符, 它可能使你无意引入一些不相关的文件.

出现在targets, prerequisites中的通配符由Make展开, 而出现在commands中的通配符由shell展开.

若想使用通配符所代表字符的原意, 在它之前加上转义字符/: 比如/?表示问号, 而非任意单个字符.

伪目标 (phony targets)


正如前面所说, 目标不仅可以是文件, 也可以标签. 用作标签的目标就是一个伪目标. 伪目标一般用来定义一个代表一条命令脚本的标签(也可以为伪目标指定prerequisites).

GNU Make是无法区别目标文件和伪文件的. 这样就存在一个问题, 如果你在Makefile里用到了一个标签, 如clean, 用以删除生成的中间目标文件:

clean:
   rm -f *.o

如果当前目录刚好有一个名为clean的文件, Make就会把这个你想用作伪目标的clean与clean文件关联起来, 当你运行 $ make clean 时, 由于clean不存在prerequisites, make 会给出这样的信息:
make: `hello' is up to date.

如何解决呢? 这里就引入了.PHONY. 以下面的格式来生命一个伪target:

.PHONY : clean
clean:
    rm -f *.o


.PHONY告诉了Make: 它后面的prerequisite, 也就是clean是一个伪目标.

.PHONY的作用:
(1)告知Make, 该伪目标并不是真正的文件, 不遵循由源代码生成目标文件的规则.
(2)告诉Make, 该伪目标始终需要被更新.

由于伪目标始终需要被更新, 那么如果它作为某个目标文件的prerequisite, 那么在每次调用make时都会执行命令. 所以通常不将伪目标作为prerequisite. 但给伪目标指定prerequisite非常有用(实际上就是让这些prerequisites对应的命令在伪目标被指定为target的时候被执行).

我们来看看这个例子: 该makefile同时生成多个可执行文件, 而且只需输入"make"

all : prog1 prog2 prog3
.PHONY : all

prog1 : prog1.o utils.o
    gcc -o prog1 prog1.o utils.o
prog2 : prog2.o
    gcc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
    gcc -o prog3 prog3.o sort.o utils.o

all是第一个target, 即为默认的target. 由于指定了all是一个伪目标, 所以all总是要被更新. 于是, 它的三个prerequisites: prog1, prog2, prog3所对应的规则也需要被裁决, 看它们各自是否需要被更新. 由此, 一条简单的make语句就可以生成多个可执行target.

注意: all : prog1 prog2 prog3 和 .PHONY : all 出现的前后顺序在这里是无关, 但最好将.PHONY : all放在前面, 这貌似更符合习惯.

注意, 在上述情况下, 如果生成的prog1, prog2, prog3不需要更新, make反馈的信息为:
make: Nothing to be done for `all'. 它不同于(非伪)目标不需要更新的信息: `<target>' is up to date.

变量


变量以这样的形式被定义:

$(variable-name)

它表示我们希望将名为variable-name的变量在makefile中扩展.(可以把它理解成C语言中的宏)

变量能包含所有的字符, 符号. 比如:$( compile.c)

变量的格式: 除了单个字符可以直接跟在$之后外( $?), 其他的变量都必须用()或者{}引起来.

我们可以自己定义变量, 同时, Make也会自动建立一些变量(自动变量).

自动变量(automatic variables)
自动变量一般用来表征target或prerequisites, 这样你就不用显式地指定它们的名称. 一共有7种自动变量:

$@    : target
$%    : archive menmber specification
$<    : 第一个prerequisite
$?     : 所有比target新的prerequisites, 它们之间以空格分隔.
$^    : 所有的prerequisites(但不包括重复的prerequisites).
$+    : 与$?相同, 但包括重复的prerequisites.
$*     : 目标文件名的主干(既不包括后缀), 它一般只用于pattern rules.

针对上面的自动变量, 有的版本的Make还提供了变种: 在变量名之后加上D表示变量的目录部分, 加上F表示变量的文件部分. 如: $(<D). 在GNU Make中提供了更好的表示目录和文件的方法, 所以不提倡用这些变种.

由于自动变量是Make在建立target和prerequisites的对应关系后自动生成的, 所以只能在command中用到它们!

利用VPATH和vpath来查找文件


对于非常简单的项目, 我们可以把所有的源代码, 头文件和Makefile一起放在同一个目录. 但对于比较复杂的情况(有比较多的头文件, 源代码文件. 这往往是现实中经常存在的情况), 我们一般把代码分类, 放在不同的目录中. 一种比较简单的做法就是将源代码文件放在src(或source)目录, 将头文件放在include目录. 然后将Makefile放在它们的父目录.

如果你不在调用make时明确地作出规定, make只在当前目录中搜索targets和prerequisites. make将makefile所在的目录默认为搜索路径优先级最高的目录, 即先在当前目录查找文件, 若找不到, 再到VPATH, vpath指定的目录查找.

下面以2种情况来说明文件查找的问题, 给出了对应的3个Makefile和2个.c文件.

VAPTH

VPATH语法: VPATH = dir1 dir2 ...

在UNIX下, 目录用" " 或 ":"分隔, 在windows下, 目录用 " "或";"分隔. 推荐使用空格!

1, 在当前目录创建一个src目录, 里面放置hello.0.c, 一个Makefile.0. 它们的内容分别如下:

/* hello.0.c */
#include <stdio.h>
int main(void)
{
    printf("hello, world!/n");
    return 0;
}

#Makefile.0
hello: hello.c
    gcc -Wall -o hello hello.c

在Makefile所在的目录运行make -f Makefile.0, 会得到这样的报错信息:

make: *** No rule to make target `hello.0.c', needed by `hello.0'. Stop.

这正是由于Make默认地在当前目录搜索target和prerequisites. 将Makefile改写为如Makefile.1所示, 在其中引入了VPATH变量.

#Makefile.1
VPATH = src

hello.0 : hello.0.c
    gcc -Wall -o hello.0 hello.0.c

运行 $ make -f Makefile.1, 我靠, 还是报错? 没办法, 把命令改为如下:
gcc -Wall -o $@ $<

这下就成功了, 是不是要使用VPATH, 命令行就必须用make的自动变量代替文件名呢?

下面在Makefile所在的目录创建include目录, 在里面放个hello.h (内容很简单: #include <stdio.h>), 并将hello.c改写为:

/* hello.1.c */
#include "hello.h"
int main(void)
{
printf("hello/n");
return 0;
}

Makefile当然要改写:

#Makefile.2
VPATH = src include
CFLAGS = -I include

hello.1 : hello.1.c hello.h
    gcc $(CFLAGS) -Wall -o $@ $<

有两点值得注意的地方:
(1) src, include都包括在VPATH中, 要告诉Make在哪里搜寻source, .c和.h文件的目录都要指定.
(2) VPATH只是告诉了Make在哪里寻找文件, 而gcc并不知道在哪里寻找hello.h (即VPATH只和Makefile中的target, prerequisites相关, 而不和command相关). 所以要声明一个CFLAGS变量. gcc $(CFLAGS) == gcc -I src/ .
还有一个值得注意的地方: 这里使用$<, 指代第hello.1.c. 如果用$^, 会把hello.h也包含进去, 而gcc的命令行中是不带.h文件的. 如果有多个.c文件, 使用变量表征它们的时候就要斟酌一下了.

使用VPATH有一个隐患: VPATH在每个目录中搜索所有的source文件. 如果一个相同的文件名出现在不同的目录中, VPATH将第一个搜索到的文件作为结果.

考虑下面的情况: make搜索hello.1.c和hello.h文件, 它首先在当前目录找到了hello.1.c, 但找不到hello.h, 于是它到VPATH, vpath指定的src和include去查找, 在src目录它又发现了hello.1.c文件, 但它将之前在当前目录找到的的hello.1.c作为优先的prerequist, 随后它又在include目录找到了hello.h: 将原本位于src目录中的hello.1.c拷贝到Makefile.2所在的目录, 修改其printf()语句, 让其显示"from the wrong dir!", 再次执行make -f Makefile.2, 运行新生成的hello.1, 我们会发现是错误的hello.1.c被编译了.

vpath
使用vpath较之VPATH更灵活. 它的基本语法为:

vpath <pattern> <directory-list>

其中<pattern>和<directory-list>都是可选的, 由此有三种使用vpath的方法:
1, vpath <pattern> <directory-list>
指定符合<pattern>模式的文件的搜索路径为<directory-list>.
2, vpath <pattern>
清除符合<pattern>模式的文件的搜索路径.
3, vpath
清除所有通过vpath所设置的文件搜索路径.

<pattern>中需要包含"%"字符, 它类似于扩展符中的"*", 表示匹配0或若干字符. 如: %.c 表示所有以.c结尾的C源文件.

可以利用vpath将Makefile.2改为如下:


"vpath %.c src" 和"vpath %.h include" 告诉Make在src目录搜索.c文件, 在include目录搜索.h文件.
要注意的是, 如果hello.1.c仍位于当前目录, make还是会将它作为首选, 而非vpath所指定的位于src目录中的hello.1.c!

VPATH is good for finding sources, not for finding targets.

还可以利用vpath来指定目标文件的路径, 后面再讨论.

注意使用VPATH和vpath时使用自动变量!

VPATH和vpath的比较
1, VPATH是make的特殊变量, 而path是make的关键字.
2, make首先在当前目录搜索文件, 并将位于当卡那目录的文件作为首选的prerequisites, 若在当前目录找不到该文件, 再到由VPATH或vpath指定的目录去搜索.

(一) 显式规则(Explicit Rules)


在makefile中显式指定了targets, prerequisites. 这即使用了make的显式规则, 它是我们常用的规则.

(二) 模式规则(Pattern Rules)


如果使用的文件比较多(比如需要使用大量的.o), 再使用显式规则, 输入那些.c, .h文件名就有点让人抓狂了. 在这种情况下可利用Make的自动推导(模式规则), 这样就不用针对每个.o文件声明command了.

利用下面的Makefile可以生成前面的hello.1:

#Makefile.4
vpath %.c src
vpath %.h include
CFLAGS = -I include

%: %.c %.h
    $gcc -Wall $(CFLAGS) -o $@ $<
hello.1:

利用Pattern Rules, 可以让Make进行自动推导: Make看到一个finename目标, 就会将filename.c和filename.h加入到prerequisites.


Static Pattern Rules


它和前面的Pattern Rules只有一个区别: 限定了针对那些target使用你给定的命令. 可以将Makefile.4改写为:

#Makefile.5
vpath %.c src
vpath %.h include
CFLAGS = -I include

OBJECTS = hello1

%(OBJECTS): %.c %.h
    $gcc -Wall $(CFLAGS) -o $@ $<
hello.1:

GNU MAKE的详细中文手册,目录如下: 目 录 第一章:概述 1.1 概述 1.2 准备知识 第二章:GNU make 介绍 2.1 Makefile简介 2.2 Makefile规则介绍 2.3 简单的示例 2.4 make如何工作 2.5 指定变量 2.6 自动推导规则 2.7 另类风格的makefile 2.8 清除工作目录过程文件 第三章:Makefile 总述 3.1 Makefile的内容 3.2 makefile文件的命名 3.3 包含其它makefile文件 3.4 变量 MAKEFILES 3.5 变量 MAKEFILE_LIST 3.6 其他特殊变量 3.7 makefile文件的重建 3.8 重载另外一个makefile 3.9 make如何解析makefile文件 3.9.1 变量取值 3.9.2 条件语句 3.9.3 规则的定义 3.10 总结 第四章:Makefile的规则 4.1 一个例子 4.2 规则语法 4.3 依赖的类型 4.4 文件名使用通配符 4.4.1 统配符使用举例 4.4.2 通配符存在的缺陷 4.4.3 函数wildcard 4.5 目录搜寻 4.5.1 一般搜索(变量VPATH) 4.5.2 选择性搜索(关键字vpath) 4.5.3 目录搜索的机制 4.5.4 命令行和搜索目录 4.5.5 隐含规则和搜索目录 4.5.6 库文件和搜索目录 4.6 Makefile伪目标 4.7 强制目标(没有命令或依赖的规则) 4.8 空目标文件 4.9 Makefile的特殊目标 4.10 多目标 4.11 多规则目标 4.12 静态模式 4.12.1 静态模式规则的语法 4.12.2 静态模式和隐含规则 4.13 双冒号规则 4.14 自动产生依赖 第五章:规则的命令 5.1 命令回显 5.2 命令的执行 5.3 并发执行命令 5.4 命令执行的错误 5.5 中断make的执行 5.6 make的递归执行 5.6.1 变量MAKE 5.6.2 变量和递归 5.6.3 命令行选项和递归 5.6.4 -w选项 5.7 定义命令包 5.8 空命令 第六章:Makefile中的变量 6.1 变量的引用 6.2 两种变量定义(赋值 ) 6.2.1 递归展开式变量 6.2.2 直接展开式变量 6.2.3 如何定义一个空格 6.2.4 “?=”操作符 6.3 变量的高级用法 6.3.1 变量的替换引用 6.3.2 变量的套嵌引用 6.4 变量取值 6.5 如何设置变量 6.6 追加变量值 6.7 override 指示符 6.8 多行定义 6.9 系统环境变量 6.10 目标指定变量 6.11 模式指定变量 第七章:Makefile的条件执行 7.1 一个例子 7.2 条件判断的基本语法 7.2.1 关键字“ifeq” 7.2.2 关键字“ifneq” 7.2.3 关键字“ifdef” 7.2.4 关键字“ifndef” 7.3 标记测试的条件语句 第八章:make的内嵌函数 8.1 函数的调用语法 8.2 文本处理函数 8.2.1 $(subst FROM,TO,TEXT) 8.2.2 $(patsubst PATTERN,REPLACEMENT,TEXT) 8.2.3 $(strip STRINT) 8.2.4 $(findstring FIND,IN) 8.2.5 $(filter PATTERN…,TEXT) 8.2.6 $(filter-out PATTERN...,TEXT) 8.2.7 $(sort LIST) 8.2.8 $(word N,TEXT) 8.2.9 $(wordlist S,E,TEXT) 8.2.10 $(words TEXT) 8.2.11 $(firstword NAMES…) 8.3 文件名处理函数 8.3.1 $(dir NAMES…) 8.3.2 $(notdir NAMES…) 8.3.3 $(suffix NAMES…) 8.3.4 $(basename NAMES…) 8.3.5 $(addsuffix SUFFIX,NAMES…) 8.3.6 $(addprefix PREFIX,NAMES…) 8.3.7 $(join LIST1,LIST2) 8.3.8 $(wildcard PATTERN) 8.4 foreach 函数 8.5 if 函数 8.6 call函数 8.7 value函数 8.8 eval函数 8.9 origin函数 8.10 shell函数 8.11 make的控制函数 8.11.1 $(error TEXT…) 8.11.2 $(warning TEXT…) 第九章:执行make 9.1 指定makefile文件 9.2 指定终极目标 9.3 替代命令的执行 9.4 防止特定文件重建 9.5 替换变量定义 9.6 使用make进行编译测试 9.7 make的命令行选项 第十章:make的隐含规则 10.1 隐含规则的使用 10.2 make的隐含规则一览 10.3 隐含变量 10.3.1 代表命令的变量 10.3.2 命令参数的变量 10.4 make隐含规则链 10.5 模式规则 10.5.1 模式规则介绍 10.5.2 模式规则示例 10.5.3 自动化变量 10.5.4 模式的匹配 10.5.5 万用规则 10.5.6 重建内嵌隐含规则 10.6 缺省规则 10.7 后缀规则 10.8 隐含规则搜索算法 第十一章:使用make更新静态库文件 11.1 库成员作为目标 11.2 静态库的更新 11.2.1 更新静态库的符号索引表 11.3 make静态库的注意事项 11.4 静态库的后缀规则 第十二章 : GNU make的特点 12.1 源自System v的特点 12.2 源自其他版本的特点 12.3 GNU make自身的特点 第十三章 和其它版本的兼容 第十四章 Makefile的约定 14.1 基本的约定 14.2 规则命令行的约定 14.3 代表命令变量 14.4 安装目录变量 14.5 Makefile的标准目标名 14.6 安装命令分类 第十五章 make的常见错误信息   附录:关键字索引 1. GNU make可识别的指示 符 2. GNU make函数 3. GNU make的自动化变量 4. GNU make环境变量 后序
GUN make 中文手册 译者:徐海兵 2004-09-11 3.5.6 库文件和搜索目录 .................................................................................................... 36 3.6 Makefile伪目标.............................................................................................................. 37 3.7 强制目标(没有命令或依赖的规则) ............................................................................. 40 3.8 空目标文件..................................................................................................................... 41 3.9 Makefile的特殊目标....................................................................................................... 41 3.10 多目标............................................................................................................................ 44 3.11 多规则目标..................................................................................................................... 44 3.12 静态模式 ........................................................................................................................ 45 3.12.1 静态模式规则的语法 ....................................................................................... 45 3.12.2 静态模式和隐含规则 ....................................................................................... 47 3.13 双冒号规则..................................................................................................................... 48 3.14 自动产生依赖 ................................................................................................................. 49 第四章:规则的命令 .................................................................................................................. 51 4 规则中书写命令 ................................................................................................................... 51 4.1 命令回显 ........................................................................................................................ 51 4.2 命令的执行..................................................................................................................... 52 4.3 并发执行命令 ................................................................................................................. 53 4.4 命令执行的错误.............................................................................................................. 54 4.5 中断make的执行............................................................................................................ 56 4.6 make的递归执行............................................................................................................ 56 4.6.1 变量MAKE ............................................................................................................... 57 4.6.2 变量和递归 ............................................................................................................... 58 4.6.3 命令行选项和递归 .................................................................................................... 61 4.6.4 -w选项...................................................................................................................... 63 4.7 定义命令包..................................................................................................................... 63 4.8 空命令............................................................................................................................ 65 第五章:Makefile中的变量......................................................................................................... 65 5 使用变量 .............................................................................................................................. 65 5.1 变量的引用..................................................................................................................... 66 5.2 两种变量定义(赋值)................................................................................................... 68 5.2.1 递归展开式变量........................................................................................................ 68 5.2.2 直接展开式变量........................................................................................................ 69 5.2.3 如何定义一个空格 .................................................................................................... 70 5.2.4 “?=”操作符 ............................................................................................................. 71 5.3 变量的高级用法.............................................................................................................. 71 5.3.1 变量的替换引用........................................................................................................ 72 5.3.2 变量的套嵌引用........................................................................................................ 72 5.4 变量取值 ........................................................................................................................ 76 5.5 如何设置变量 ................................................................................................................. 76 5.6 追加变量值..................................................................................................................... 77 5.7 override 指示符 ............................................................................................................. 79 5.8 多行定义 ........................................................................................................................ 80 5.9 系统环境变量 ................................................................................................................. 81 5.10 目标指定变量 ................................................................................................................. 83 5.11 模式指定变量 ................................................................................................................. 84 第六章:Makefile的条件执行 ..................................................................................................... 85 6 Makefile的条件判断 ............................................................................................................. 85 6.1 一个例子 ........................................................................................................................ 85 6.2 条件判断的基本语法 ...................................................................................................... 86 2004年9月11日 3GUN make 中文手册 6.3 标记测试的条件语句 ...................................................................................................... 89 第七章:make的内嵌函数.......................................................................................................... 89 7 make的函数 ......................................................................................................................... 89 7.1 函数的调用语法.............................................................................................................. 90 7.2 文本处理函数 ................................................................................................................. 91 7.2.1 $(subst FROM,TO,TEXT) ....................................................................................... 91 7.2.2 $(patsubst PATTERN,REPLACEMENT,TEXT) ..................................................... 91 7.2.3 $(strip STRINT)....................................................................................................... 92 7.2.4 $(findstring FIND,IN) .............................................................................................. 92 7.2.5 $(filter PATTERN...,TEXT) ..................................................................................... 93 7.2.6 $(filter-out PATTERN...,TEXT) ............................................................................... 93 7.2.7 $(sort LIST) ............................................................................................................. 94 7.2.8 $(word N,TEXT) ...................................................................................................... 94 7.2.9 $(wordlist S,E,TEXT).............................................................................................. 94 7.2.10 $(words TEXT) .............................................................................................. 94 7.2.11 $(firstword NAMES...) .................................................................................. 95 7.3 文件名处理函数.............................................................................................................. 95 7.3.1 $(dir NAMES...) ...................................................................................................... 95 7.3.2 $(notdir NAMES...)................................................................................................. 96 7.3.3 $(suffix NAMES...) ................................................................................................. 96 7.3.4 $(basename NAMES...) ......................................................................................... 96 7.3.5 $(addsuffix SUFFIX,NAMES...) ............................................................................. 97 7.3.6 $(addprefix PREFIX,NAMES...) ............................................................................. 97 7.3.7 $(join LIST1,LIST2)................................................................................................. 98 7.3.8 $(wildcard PATTERN) ............................................................................................ 98 7.4 foreach 函数................................................................................................................. 98 7.5 if 函数 ......................................................................................................................... 100 7.6 call函数 ....................................................................................................................... 100 7.7 value函数 .................................................................................................................... 102 7.8 eval函数 ...................................................................................................................... 103 7.9 origin函数 ................................................................................................................... 104 7.10 shell函数 ..................................................................................................................... 106 7.11 make的控制函数.......................................................................................................... 106 7.11.1 $(error TEXT...) ........................................................................................... 107 7.11.2 $(warning TEXT...)...................................................................................... 107 第八章:执行make .................................................................................................................. 108 8 执行make .......................................................................................................................... 108 8.1 指定makefile文件 ........................................................................................................ 108 8.2 指定终极目标 ............................................................................................................... 109 8.3 替代命令的执行............................................................................................................ 111 8.4 防止特定文件重建 ........................................................................................................ 112 8.5 替换变量定义 ............................................................................................................... 113 8.6 使用make进行编译测试............................................................................................... 114 8.7 make的命令行选项 ...................................................................................................... 115 第九章:make的隐含规则........................................................................................................ 119 9 使用隐含规则 ..................................................................................................................... 119 9.1 隐含规则的使用............................................................................................................ 119 9.2 make的隐含规则一览 .................................................................................................. 121 9.3 隐含变量 ...................................................................................................................... 124 9.3.1 代表命令的变量...................................................................................................... 124 9.3.2 命令参数的变量...................................................................................................... 125 9.4 make隐含规则链.......................................................................................................... 126 2004年9月11日 4GUN make 中文手册 9.5 模式规则 ...................................................................................................................... 128 9.5.1 模式规则介绍 ......................................................................................................... 128 9.5.2 模式规则示例 ......................................................................................................... 129 9.5.3 自动化变量 ............................................................................................................. 130 9.5.4 模式的匹配 ............................................................................................................. 133 9.5.5 万用规则 ................................................................................................................ 133 9.5.6 重建内嵌隐含规则 .................................................................................................. 134 9.6 缺省规则 ...................................................................................................................... 135 9.7 后缀规则 ...................................................................................................................... 135 9.8 隐含规则搜索算法 ........................................................................................................ 137 第十章:使用make更新静态库文件 ......................................................................................... 138 10 更新静态库文件............................................................................................................ 138 10.1 库成员作为目标............................................................................................................ 138 ARCHIVE(MEMBER) .............................................................................................................. 138 10.2 静态库的更新 ............................................................................................................... 139 10.2.1 更新静态库的符号索引表 .............................................................................. 140 10.3 make静态库的注意事项............................................................................................... 141 10.4 静态库的后缀规则 ........................................................................................................ 141 第十一章 : GNU make的特点............................................................................................... 142 11 GNU make的一些特点 ................................................................................................. 142 11.1 源自System v的特点 ................................................................................................... 142 11.2 源自其他版本的特点 .................................................................................................... 143 11.3 GNU make自身的特点 ................................................................................................. 143 第十二章 和其它版本的兼容 .................................................................................................... 144 12 不兼容性 ...................................................................................................................... 144 第十三章 Makefile的约定 ........................................................................................................ 146 13 书写约定 ...................................................................................................................... 146 13.1 基本的约定................................................................................................................... 146 13.2 规则命令行的约定 ........................................................................................................ 147 13.3 代表命令变量 ............................................................................................................... 149 13.4 安装目录变量 ............................................................................................................... 150 13.5 Makefile的标准目标名 ................................................................................................. 154 13.6 安装命令分类 ............................................................................................................... 159 第十四章 make的常见错误信息............................................................................................... 161 14 make产生的错误信息 .......................................................................................................... 161 附录1:关键字索引................................................................................................................. 163 GNU make可识别的指示符:.............................................................................................. 163 GNU make函数: ............................................................................................................... 164 GNU make的自动化变量..................................................................................................... 165 GNU make环境变量 ............................................................................................................ 166 后序 ......................................................................................................................................... 166
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值