规则明确在什么情况下,使用什么方法,重构文件,该文件称为目标。

  make的唯一目的是重构终极目标。终极目标默认是第一个目标。

1.

2.规则语法

TARGETS : PREREQUISITES
COMMAND
或者:
TARGETS : PREREQUISITES ; COMMAND
COMMAND

  TARGETS 和 PREEQUISITES 可以是多对多的关系,但通常TARGETS 只代表单个目标。

  每一行COMMAND(没有用;链接情况),make会fork一个进程去执行该命令,命令运行在shell系统之上。  

  规则的中心思想是: 目标文件的内容是由依赖文件文件决定, 依赖文件的任何一处改动,都将导致已经存在的目标文件过期。

  $是特殊字符,代表变量或函数,$$表示$字符。

3.依赖类型

  依赖类型分为普通类型和 order-only 类型。

  普通类型依赖,当这种依赖文件被改动或新增,则认为目标文件已过期。

  order-only类型依赖,这种依赖文件被改动,不会认为目标文件过期。

  格式如下

TARGETS : NORMAL-PREREQUISITES | ORDER-ONLY-PREREQUISITES

  示例

LIBS = libtest.a
foo : foo.c | $(LIBS)
$(CC) $(CFLAGS) $< -o $@ $(LIBS)

4.文件名使用通配符

  可用的通配符有:*,[...],?

  意义和shell的通配符相同。

  make的通配符只能用在两个场景:

(1)目标和依赖处,make在解析阶段展开目标和依赖处的通配符

(2)规则处,在make执行阶段展开。

  其他上下文不能使用通配符,只能用 函数 $(wildcard ) 实现。

5.目录搜索

  (1)VPATH变量(一般性搜索)

  make搜索文件时,现在当前目录搜索,若没有,则在VPATH指定的目录搜索。

  定义VPATH,目录间用空格或冒号分隔

VPATH = src:../headers

  通过VPATH指定的目录,对所有文件都有效,当需要为特定类型文件指定搜索路径时,应使用 vpath

  (2)vpath关键字(选择性搜索)

  vpath不是变量,而是关键字,path有3种使用方式

1、 vpath PATTERN DIRECTORIES
为所有符合模式“ PATTERN”的文件指定搜索目录“ DIRECTORIES”。多个目
录使用空格或者冒号(:)分开。类似上一小节的“ VPATH”变量。
2、 vpath PATTERN
清除之前为符合模式“ PATTERN”的文件设置的搜索路径。
3、 vpath
清除所有已被设置的文件搜索路径。

  PATTERN 表示模式,其中可以使用%,%表示匹配一个或多个字符,如%.h表示所有以.h结尾的文件。如果PATTERN中没有包含%,那他就是明确的文件名。

  vpath示例

vpath %.h ../headers
vpath %.c foo
vpath % blish
vpath %.c bar
表示对所有的.c 文件, make 依次查找目录:“ foo”、 blish”、“ bar”。
而:
vpath %.c foo: bar
vpath % blish
对于所有的.c 文件 make 将依次查找目录:“ foo”、“ bar”、“ blish”

  (3)-INAME(依赖库)

  -INAME 表示以目录搜索的方法添加依赖。

  来看一下详细的过程。 1. make 在执行规则时会在当前目录下搜索一个名字为“ libNAME.so”的文件;

2. 如果当前工作目录下不存在这样一个文件,则make 会继续搜索使用“ VPATH”或者“ vpath”指定的搜索目录。

3. 还是不存在, make将搜索系统库文件存在的默认目录,顺序是:“ /lib”、“ /usr/lib”和“ /usr/local/lib”

                                         如果“ libNAME.so”通过以上的途径最后还是没有找到的话,那么 make 将会按照以上的搜索顺序查找名字为“ libNAME.a”的文件。 

  可以这样使用:

假设你的系统中存在“ /usr/lib/libcurses.a”(不存在“ /usr/lib/libcurses.so”)这个
库文件。看一个例子:
foo : foo.c -lcurses
cc $^ -o $@

  如果libcurses.a更新了,make就会认为 foo过期需要更新。

  之所以 -INAME 会先寻找 libNAME.so ,若没找到再寻找 libNAME.a,是因为环境变量 .LIBPATTERNS

  .LIBPATTERNS 默认值为 lib%.so lib%.a

6.伪目标

  伪目标的目的:

  (1)避免make的目标(只为了执行命令,不生成文件)和工作目录的文件重名。

  (2)提高make的工作效率

   当一个规则的目标为伪目标时,当运行到该规则时,规则的命令一定会被执行。

   且make不会查找伪目标的隐含规则,意味提高了效率。

  伪目标用于并行

SUBDIRS = foo bar baz
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done

  上面的make无法并行,因为只有一行,且$(MAKE)出错也不知道。

SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
foo: baz

  如此就能多线程。

  foo: baz 只是为了确定 foo 和 baz的执行顺序,所以无需命令。

7.强制目标

  一个规则没有命令或依赖,并且他的目标不是存在的文件名。在执行此规则时,目标总被认为是最新的,即刚更新过。

  将这个刚更新过的目标做其他目标的依赖,其他目标就一定会被更新。

clean: FORCE
rm $(objects)
FORCE:

  强制目标和.PHONY效果一样,不过.PHONY更好。

8.

9.

10.

11.

12. 静态规则

  语法

TARGETS ...: TARGET-PATTERN: PREREQ-PATTERNS ...
COMMANDS
TAGET-PATTERN”和“ PREREQ-PATTERNS”说明了如何为每一个目标文件
生成依赖文件。从目标模式( TAGET-PATTERN)的目标名字中抽取一部分字符串(称
为“茎”)。使用“茎”替代依赖模式( PREREQ-PATTERNS)中的相应部分来产生对
应目标的依赖文件。下边详细介绍这一替代的过程。

  示例

objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte-compile $<
bigoutput littleoutput : %output : text.g
generate text.g -$* > $@
当执行此规则的命令时,自动环变量“ $*”被展开为“茎”。在这里就是“ big”和“ little”。

静态规则通常被其他makefile重复使用,

通常的做法是将生成同一类目标的模式定义在一个 make.rules 的文件中。在工程各个模块的 Makefile 中包含此文件。 

 

13. 双冒号规则

Newprog :: foo.c
$(CC) $(CFLAGS) $< -o $@
Newprog :: bar.c
$(CC) $(CFLAGS) $< -o $@

  当foo.c更新时,第一个规则的命令会被执行,当bar.c更新时,第二条规则的命令会被执行。

  而如果使用单冒号,则会报错,必须将这两条规则合并,意味只能一种执行命令路线。

《GNU_Makefile》第4章——makefile规则的更多相关文章

  1. Makefile规则③规则语法、依赖、通配符、目录搜寻、目标

    规则语法 通常规则的语法格式如下: TARGETS : PREREQUISITES COMMAND ... 或者: TARGETS : PREREQUISITES ; COMMAND COMMAND ...

  2. Makefile 规则的使用

    1.Makefile格式 //最终目标 all: led.o //依赖 arm-linux-ld -Tled.lds -o led.elf led.o //命令 arm-linux-objcopy - ...

  3. 编写Makefile规则

    一个工程中的源文件不计其数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作 ...

  4. makefile规则整理

    makefile规则整理 实际开发中,makefile改的多,写的少. 为了后面不要在编译链接这种地方花费太多的时间,在这里系统性的整理其规则: 基本格式 TARGET : PREREQUISITES ...

  5. 《GNU_makefile》第五章——为规则书写命令

    1. 使用make的命令行参数-n或--just-print,make会只显示要执行的命令,不执行,这样方便调试makefile. 2.执行命令 每写一行命令,make会fork出一个shell进程来 ...

  6. 《GNU_makefile》第七章——makefile的条件执行

    条件执行即,通过变量的值,来控制make的执行和忽略. 条件执行只能控制makefile的make语法部分,不能控制shell部分 1.一个例子 - libs_for_gcc = -lgnu norm ...

  7. make的使用和Makefile规则和编程及其基本命令(简单)

      转自:http://blog.chinaunix.net/uid-23929712-id-2650328.html   概述: make从Makefile中文件中获取模块间的依赖关系,判断哪些文件 ...

  8. 【ASM C/C++】 Makefile 规则说明

    make 命令会自动读取当前目录下的 Makefile 文件[31],完成相应的编译步骤.Makefile 由一组规则(Rule)组成,每条规则的格式是:target ... : prerequisi ...

  9. 自动构建Makefile(1)--C/C++编译流程&Makefile规则简介

      前言: 大家在Windows上使用VS构建C/C++程序时,不需要自己编辑略显晦涩的Makefile文件,而对于初学者而言, 他们甚至没意识到它的存在.VS是自动生成Makefile文件, 并构建 ...

随机推荐

  1. 基于python实现顺序存储的队列代码

    """ 队列-顺序存储 seqqueue.py 代码实现 """ # 自定义异常类 class QueueError(Exception): ...

  2. jenkins:配置密钥时报错的解决:Failed to add SSH key. Message invalid privatekey(Jenkins 2.257)

    一,报错的现象: 1,提示信息: jenkins.plugins.publish_over.BapPublisherException: Failed to add SSH key. Message ...

  3. 经典剪枝算法的例题——Sticks详细注释版

    这题听说是道十分经典的剪枝算的题目,不要问我剪枝是什么,我也不知道,反正我只知道用到了深度搜索 我参考了好多资料才悟懂,然后我发现网上的那些大神原理讲的很明白,但代码没多少注释,看的很懵X,于是我抄起 ...

  4. spring-boot-route(二十二)实现邮件发送功能

    在项目开发中,除了需要短信验证外,有时候为了节省 短信费也会使用邮件发送.在Spring项目中发送邮件需要封装复杂的消息体,不太方便.而在Spring Boot项目中发送邮件就太简单了,下面一起来看看 ...

  5. C++类模板声明与定义为何不能分开

    我们用C++写类的时候,通常会将.cpp和.h文件分开写,即实现和声明分开写了:但在C++的类模板中,这种写法是错误的. 在<C++编程思想>的第16章的"16.3模板语法&qu ...

  6. C语言之 判断语句基础与if语句反汇编

    0x01.判断语句介绍以及用法 判断语句有哪些? 1.If 用法1: if (条件) { //代码块 } 当条件成立,也就是为True时,执行{}中的代码 用法2: if(条件) { //代码块 } ...

  7. 关于nodejs中的增删改查

    1.增加 router.post('/insert',function(req,res){  var name = req.body.name;  var num = req.body.num;  v ...

  8. 在 k8S 中搭建 SonarQube 7.4.9 版本(使用 PostgreSQL 数据库)

    搭建 SonarQube 和 PostgreSQL 服务 本文搭建的 SonarQube 版本是 7.4.9-community,由于在官方文档中声明 7.9 版本之后就不再支持使用 MySQL 数据 ...

  9. Kubernetes 搭建 ES 集群(存储使用 cephfs)

    一.集群规划 使用 cephfs 实现分布式存储和数据持久化 ES 集群的 master 节点至少需要三个,防止脑裂. 由于 master 在配置过程中需要保证主机名固定和唯一,所以搭建 master ...

  10. 隐马尔科夫模型 HMM(Hidden Markov Model)

    本科阶段学了三四遍的HMM,机器学习课,自然语言处理课,中文信息处理课:如今学研究生的自然语言处理,又碰见了这个老熟人: 虽多次碰到,但总觉得一知半解,对其了解不够全面,借着这次的机会,我想要直接搞定 ...