ominous2012的个人空间 https://blog.eetop.cn/934213 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

makefile1

已有 727 次阅读| 2016-1-9 20:12 |个人分类:makefile

1.$<:所有的依赖目标
$@:目标集


2.$(filter %.o,$file) 将$file中所有以.o结尾的文件取出
makefile 中的-M选线支持自动查找源文件include的头文件,并生成一个依赖关系如:
cc -M main.c
输出:
main.o:main.c def.h
如果使用GNU的c/c++编译器,则用 -MM 参数,-M会把一些标准的库文件也包含进来
 %.d:%.c  表示所有的.d 文件依赖.c 文件

3.@字符在命令行前,那么这个名利将不被make显示出来。
如:@echo “abc"
在make执行时,输出 abc,不输出命令,如果没有@
输出
echo “abc"
abc

如果make 执行带参数 ”-n" 或“--just-print” 那么直显示命令,但不会执行命令
-s 或 --silent 全面禁止命令的显示

4.在makefile的命令行前加“-”,将会忽略命令的出错,(加在tab键之后)如:
-rm -f *.o
忽略全局的错误,给make加上“-i” 或“--ignore-errors",那么makefile中所有的命令都会忽略错误。
 如果一个规则以”.IGNORE"作为目标,那么这个规则中的所有命令将会忽略错误。
-k或是 --keep-going 表示如果某个规则中的命令出错了,那么种植该规则的执行,但继续执行其他规则。

5.subsystem: 
cd subdir && $(MAKE)
等价于
subsystem:
$(MAKE) -C subdir
表示先进入subdir,然后执行make命令
这个makefile叫做总控makefile,总控makefile的变量可以传递到下级的makefile,但不会覆盖下层的makefile中所定义的变量,除非指定了 -e参数

6.export
如果你要传递变量到下级的makefile中,那么你可以使用如下这样的声明:
export <variable ..>
如果不行传递,那么可以这样声明:
unexport <variable ..>

eg1:
export var=value
等价于:
var=value
export var
等价于
export var:=value
等价于
var:=value
export var

eg2:
export var += value
等价于
var +=value
export var

注意:有两个变量SHELL,MAKEFLAGS这两个变量不管你是否export,总要传递到下层的Makefile中,其中包含了make的参数信息
但是make命令中的有几个参数并不往下传递,它们是“-C”,“-f”,“-h”“-o”和“-W” 
(有关Makefile参数的细节将在后面说明),如果你不想往下层传递参数,那么,你可以
这样来:
subsystem: 
cd subdir && $(MAKE) MAKEFLAGS= 
如果你定义了环境变量MAKEFLAGS,那么你得确信其中的选项是大家都会用到的,如果
其中有“-t”,“-n”,和“-q”参数,那么将会有让你意想不到的结果,或许会让你异常地恐慌。
还有一个在“嵌套执行”中比较有用的参数,“-w”或是“--print-directory”会在make的过程中输
出一些信息,让你看到目前的工作目录。比如,如果我们的下级make目录是
“/home/hchen/gnu/make”,如果我们使用“make -w”来执行,那么当进入该目录时,我们会看
到:
make: Entering directory `/home/hchen/gnu/make'. 
而在完成下层make后离开目录时,我们会看到:
make: Leaving directory `/home/hchen/gnu/make' 
当你使用“-C”参数来指定make下层Makefile时,“-w”会被自动打开的。如果参数中有“-s”
(“--slient”)或是“--no-print-directory”,那么,“-w”总是失效的。

7.定义命令包 
如果Makefile中出现一些相同命令序列,那么我们可以为这些相同的命令序列定义一个变
量。定义这种命令序列的语法以“define”开始,以“endef”结束,如:
define run-yacc 
yacc $(firstword $^) 
mv y.tab.c $@ 
endef 
这里,“run-yacc”是这个命令包的名字,其不要和Makefile中的变量重名。在“define”和“endef”
中的两行就是命令序列。这个命令包中的第一个命令是运行Yacc程序,因为Yacc程序总
是生成“y.tab.c”的文件,所以第二行的命令就是把这个文件改改名字。还是把这个命令包放
到一个示例中来看看吧。
foo.c : foo.y 
$(run-yacc) 
我们可以看见,要使用这个命令包,我们就好像使用变量一样。在这个命令包的使用中,命
令包“run-yacc”中的“$^”就是“foo.y”,“$@”就是“foo.c”(有关这种以“$”开头的特殊变量,我
们会在后面介绍),make在执行命令包时,命令包中的每个命令会被依次独立执行。
8.变量
    如果使用真实的$,那么需要用$$
9.条件表达式
ifeq(0,$(MAKELEVEL))
    cur-dir : = $(shell pwd)
    whoami := $(shell whoami)
    host_type := $(shell arch)
endif

MAKELEVEL,为系统变量,其意思是如果我们的make有一个嵌套执行的动作(参见前面的“嵌套使用make”),那么,这个变量会记
录了我们的当前Makefile的调用层数。
下面再介绍两个定义变量时我们需要知道的,请先看一个例子,如果我们要定义一个变量,
其值是一个空格,那么我们可以这样来:
nullstring := 
    space := $(nullstring) # end of the line  
nullstring是一个Empty变量,其中什么也没有,而我们的space的值是一个空格。因为在操
作符的右边是很难描述一个空格的,这里采用的技术很管用,先用一个Empty变量来标明
变量的值开始了,而后面采用“#”注释符来表示变量定义的终止,这样,我们可以定义出其
值是一个空格的变量。请注意这里关于“#”的使用,注释符“#”的这种特性值得我们注意,如
果我们这样定义一个变量:
    dir := /foo/bar     # directory to put the frobs in  
dir这个变量的值是“/foo/bar”,后面还跟了4个空格,如果我们这样使用这样变量来指定别
的目录——“$(dir)/file”那么就完蛋了。
还有一个比较有用的操作符是“?=”,先看示例:
FOO ?= bar 
其含义是,如果FOO没有被定义过,那么变量FOO的值就是“bar”,如果FOO先前被定义
过,
那么这条语将什么也不做,其等价于:
ifeq ($(origin FOO), undefined) 
FOO = bar 
endif 

10.变量的替换
格式是“$(var:a=b)”或是“${var:a=b}”,其意思是,
把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾” 意思是“空格”或是
“结束符”。
foo := a.o b.o c.o 
bar := $(foo:.o=.c) 
这个示例中,我们先定义了一个“$(foo)”变量,而第二行的意思是把“$(foo)”中所有以
“.o”字串“结尾”全部替换成“.c”,所以我们的“$(bar)”的值就是“a.c b.c c.c”  
另外一种变量替换的技术是以“静态模式”(参见前面章节)定义的,如:
foo := a.o b.o c.o 
bar := $(foo:%.o=%.c) 
这依赖于被替换字串中的有相同的模式,模式中必须包含一个“%”字符,这个例子同样让$ 
(bar)变量的值为“a.c b.c c.c”。
11.override 指示符 
如果有变量是通常make的命令行参数设置的,那么Makefile中对这个变量的赋值会被忽略。
如果你想在Makefile中设置这类参数的值,那么,你可以使用“override”指示符。其语法
是:
    override <variable> = <value>  
    override <variable> := <value>  
当然,你还可以追加:
override <variable> += <more text> 
对于多行的变量定义,我们用define指示符,在define指示符前,也同样可以使用ovverid 
e指示符,如:
override define foo 
bar 
endef 

12.多行变量 
还有一种设置变量值的方法是使用define关键字。使用define关键字设置变量的值可以
有换行,这有利于定义一系列的命令(前面我们讲过“命令包”的技术就是利用这个关键字)。
define指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef关键字结
束。其工作方式和“=”操作符一样。变量的值可以包含函数、命令、文字,或是其它变量。
因为命令需要以[Tab]键开头,所以如果你用define定义的命令变量中没有以[Tab]键开头,
那么make就不会把其认为是命令。
下面的这个示例展示了define的用法:
define two-lines 
echo foo 
echo $(bar) 
endef 



点赞

全部作者的其他最新日志

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 2

    粉丝
  • 0

    好友
  • 0

    获赞
  • 1

    评论
  • 529

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-21 19:45 , Processed in 0.029582 second(s), 15 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部