makefile 的一些知识
来源:互联网 发布:windows 任务计划程序 编辑:程序博客网 时间:2024/04/26 03:37
命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集,“$@”表示目标集。
$(filter %.o,$(files))表示调用 Makefile 的 filter 函数,过滤“$filter”集,只要其中模式为“%.o”的内容。
makefile中所有的自动化变量
$@
表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于
目标中模式定义的集合。
$%
仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a
(bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。如果目标不是函数库文件(Unix
下是[.a],Windows 下是[.lib]),那么,其值为空。
$<
依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将
是符合模式的一系列的文件集。注意,其是一个一个取出来的。
$?
所有比目标新的依赖目标的集合。以空格分隔。
$^
所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量
会去除重复的依赖目标,只保留一份。
$+
这个变量很像"$^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。
$*
这个变量表示目标模式中"%"及其之前的部分。如果目标是"dir/a.foo.b",并且目标的
模式是"a.%.b",那么,"$*"的值就是"dir/a.foo"。这个变量对于构造有关联的文件名是比
较有较。如果目标中没有模式的定义,那么"$*"也就不能被推导出,但是,如果目标文件的
后缀是 make 所识别的,那么"$*"就是除了后缀的那一部分。例如:如果目标是"foo.c",因
为".c"是 make 所能识别的后缀名,所以,"$*"的值就是"foo"。这个特性是 GNU make 的,很有可能不兼容于其它版本的 make,所以,你应该尽量避免使用"$*",除非是在隐含规则
或是静态模式中。如果目标中的后缀是 make 所不能识别的,那么"$*"就是空值。
当你希望只对更新过的依赖文件进行操作时,"$?"在显式规则中很有用,例如,假设有
一个函数库文件叫"lib",其由其它几个 object 文件更新。那么把 object 文件打包的比较
有效率的 Makefile 规则是:
lib : foo.o bar.o lose.o win.o
ar r lib $?
在上述所列出来的自动量变量中。四个变量($@、$<、$%、$*)在扩展时只会有一个文
件,而另三个的值是一个文件列表。这七个自动化变量还可以取得文件的目录名或是在当前
目录下的符合模式的文件名,只需要搭配上"D"或"F"字样。这是 GNU make 中老版本的特性,
在新版本中,我们使用函数"dir"或"notdir"就可以做到了。"D"的含义就是 Directory,就
是目录,"F"的含义就是 File,就是文件。
------------------------------------------
但是,如果是一个比较大型的工程,你必需清楚哪些 C 文件包含了哪些头文件,并且,
你在加入或删除头文件时,也需要小心地修改 Makefile,这是一个很没有维护性的工作。
为了避免这种繁重而又容易出错的事情,我们可以使用 C/C++编译的一个功能。大多数的
C/C++编译器都支持一个“-M”的选项,即自动找寻源文件中包含的头文件,并生成一个依
赖关系。例如,如果我们执行下面的命令:
cc -M main.c
其输出是:
main.o : main.c defs.h
如果你使用 GNU 的 C/C++编译器,你得用
“-MM”参数,不然,“-M”参数会把一些标准库的头文件也包含进来。
gcc -M main.c 的输出是:
main.o: main.c defs.h /usr/include/stdio.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
/usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \
/usr/include/bits/sched.h /usr/include/libio.h \
/usr/include/_G_config.h /usr/include/wchar.h \
/usr/include/bits/wchar.h /usr/include/gconv.h \
/usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stdarg.h \
/usr/include/bits/stdio_lim.h
gcc -MM main.c 的输出则是:
main.o: main.c defs.h
---------------------------------------------------
每当命令运行完后,make 会检测每个命令的返回码,如果命令返回成功,那么 make 会
执行下一条命令,当规则中所有的命令成功返回后,这个规则就算是成功完成了。如果一个
规则中的某个命令出错了(命令退出码非零),那么 make 就会终止执行当前规则,这将有可
能终止所有规则的执行。
有些时候,命令的出错并不表示就是错误的。例如 mkdir 命令,我们一定需要建立一个
目录,如果目录不存在,那么 mkdir 就成功执行,万事大吉,如果目录存在,那么就出错了。
我们之所以使用 mkdir 的意思就是一定要有这样的一个目录,于是我们就不希望 mkdir 出错
而终止规则的运行。
为了做到这一点,忽略命令的出错,我们可以在 Makefile 的命令行前加一个减号“-”
(在 Tab 键之后),标记为不管命令出不出错都认为是成功的。如:
clean:
-rm -f *.o
还有一个全局的办法是,给 make 加上“-i”或是“--ignore-errors”参数,那么,
Makefile 中所有命令都会忽略错误。而如果一个规则是以“.IGNORE”作为目标的,那么这
个规则中的所有命令将会忽略错误。这些是不同级别的防止命令出错的方法,你可以根据你
的不同喜欢设置。
还有一个要提一下的 make 的参数的是“-k”或是“--keep-going”,这个参数的意思
是,如果某规则中的命令出错了,那么就终目该规则的执行,但继续执行其它规则。
---------------------------------------------------
说明:本文是学习《跟我一起写makefile》的知识笔记。
如果需要请搜索《跟我一起写makefile》
这是初学makefile非常好的教材。
- makefile 的一些知识
- linux kernel makefile的一些背景知识
- Makefile编写的一些小知识
- Makefile一些知识
- Makefile知识的记录
- makefile 的相关知识
- Makefile 的相关知识
- Makefile的入门知识
- makefile的相关知识
- makefile的一些技巧
- makefile的一些技巧
- makefile的一些技巧
- Makefile的一些说明
- Makefile的一些小结
- makefile的一些笔记
- makefile文件的简单知识
- 12-3-10关于gcc一些知识,如何编写makefile
- .net的一些知识
- 【转】MySql错误:error :Can't connect to MySQL server (10060)解决办法
- Trafficserver Cluster模式
- TrafficServer一致性hash实现
- IPhone 之 UIView的一些基本方法理解
- Elance(外国版猪八戒)网上兼职 新手入门
- makefile 的一些知识
- Linux下通过进程名获得进程号
- JasperReport 导出PDF时使用其他字体
- 游戏引擎剖析
- 字符与Unicode互转
- 正则表达式(包括?的用法)
- Oracle学习总结-用户管理
- 中移动苹果合作难题:iPhone需要融合7种制式
- Android 监听ContentProvider中数据的变化