Knowing makefile in linux
来源:互联网 发布:6x6摇头矩阵灯 编辑:程序博客网 时间:2024/05/01 20:49
1. compilation and linking
compilation (object file): .obj files in windows; .o files in linux
编译时, 编译器会检查语法, 函数, 及变数的宣告正确与否, 正确则编译成功, 反之则失败!
linking: 告知编译器 head file 的位置, 链接函数和全局变数, so 可使用 object files 来链接应用程式.
当 object file 太多时通常习惯将其打包, 如 .lib in windows; .a in linux.
2. makefile rule
target : prerequisites
<Tab>command
或是
target : prerequisites ; command
prerequisites 中如果有一个以上的档案比 taget 还新, command 就会被执行, command 是一个 linux shell script.
3. The example of GNU make user guild
supposed that we have an application with 8 c files and 3 head files, we can write a makefile to meet below condictions.
1) All c files have to be compliered and linked if the application was never complied.
2) Just complie these c files and link them to the application if some c files were modified.
3) Just complie those c files that included these head files and link them to the application if some head files were modified.
makefile -
4. 隐晦规则与变量使用
make 可自动识别寻找 <filename>.c 来编译 <filename>.o,这称为 makefile 的隐晦规则.
将上例的所有的 object files 都以一个变量 objects 表示, 相当于 string variable. 于是 makefile 可简化成:
上例中 ".PHONY" 的用法表示 clean 是一个伪目标文件, 上例中的 makefile 也可以写成:
clean 一个比较 safe 的写法是: ("-" 表示当文件出现问题时, ignore 继续作后面的事)
5. 引用其他的 makefile
若要引用其他的 makefile, 可用 "include <filename>", 如 include a.mk b.mk c.mk
mak 执行时, 有 "-I" or "--include-dir" 参数, 则 make 会在指定的目录寻找, 如果有 <prefix>/include, 通常是 /usr/include or /usr/local/bin 存在的话, 也会寻找.
若希望忽略这个错误可用 "-include <filename>", 在其他 make 版本兼容的语法为 sinclude.
另环境变数 MAKEFILES, 亦等同此作用, 不同的是不同的档案以 "," 分开表示.
6. 搜寻的目录
vpath, 如 vpath %.h foo:bar, 表示先在 foo 目录下寻找, 若找不到, 再到 bar 下寻找
7. 多目标与自动化变量
往下看一个例子:
等价于
$< 表示所有依赖的文件, 而 $@ 表示需生成的目标
$%: 目标中的规则成员名, 如目标是 foo.a, 则 $% = foo.a, 如果目标不是库文件, 则 $% 为空
$?: 所有比目标新的依赖文件集合
$^: 所有依赖目标的集合
$+: 不去除重复的依赖目标
$*: 目标样式中 "%" 及 "%" 之前的部分, 如目标是 "dir/a.foo.c", 样式为 "a.%.c", 则 $* = "dir/a.foo"
可以在自动化变量中指定是目录还是档案, 使用关键字 "D" 与 "F", 如 $(@D) 列举所有目标的目录
8. 调试
使用 "@" 在命令之前, 则命令将不会被 make 显示出来, 只会执行.
另 make -n or make --just-print, 只会显示命令, 而不执行命令, 而 make -s or make --silent, 则不显示命令.
有时候的命令出错, 并不一定是真正的错误, 如 mkdir, 此时则可在命令前加个 "-", 另外有个全局的做法, make -i or make --ignore-errors.
还有一个用法是 make -k or make --keep-going, 指的是若某个规则出错, 则往下执行其他规则.
9. 嵌套与变量传递
如有一个子目录为 subdir, 要进入 subdir 执行 make, 则 makefile 可写为:
subsystem:
cd subdir && $(MAKE)
相等于
subsystem:
$(MAKE) -C subdir
在此的 makefile 所定义的变量是不会覆盖到下层 makefile 所使用的变量, 除非用 "-e" (如果是 make -e, 系统环境变量将覆盖 makefile 所定义的变量)
如果要传递变量到下层 makefile, 可以用 "export", 反之为 "unexport", 意思是不传递参数到下层 makefile.
export var = val
等同于
var = val
export var
也同于
var := val
export var
(export var := val)
":=" 与 "=" 差别的地方是前面不能使用后面的变量, 即时后面被重复赋值, 如下: $y = bar, 而不是 "foo bar"
y := $(x) bar
x := foo
再看另外一个 export 的例子:
export var += val
亦等同于
var += val
export var
如果要传递所有的变量, 只要声明 "export" 后面啥么都不用加.
特别要注意的是 MAKEFLAGS, 这是一个环境变量, 将会将上层的 makefile 所使用的参数传递到下层, 所以如果不想传递的话, 可以这样使用:
subsystem:
cd subdir && $(MAKE) MAKEFLAGS=
另外还有 make -w or make --print-subdirectory, 会在 make 的过程中显示目录的进入及离开:
make: Entering directory `/home/hchen/gnu/make', 会在完成下层的 make 后离开目录
make: Leaving directory `/home/hchen/gnu/make'
另外值得一提的是, 当使用参数 "-C", 则 "-w" 会被自动打开, 当使用 "-s" or "--no-print-subdirectory", 那么 "-w" 的作用将失效.
10. 定义命令
"define' 开头, "endef' 结尾.
define run-func
func $(firstworld $^)
mv f.temp.c $@
endef
11. 变量
如果令一个变量的值是一个空格, 可以下列写法,
nullstring :=
space := $(nullstring) # end of line
或是
empty :=
space := $(empty) $(empty)
还有一个比较有用的操作符是 "?=", 如果 foo 没有被定义过, 则 foo = bar, 否则忽略.
foo ?= bar
等同于
ifeq ($(origin foo), undefined)
foo = bar
endif
回顾一下前面提到的变量值替换: 结尾 .o 换成 .c
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
等价于
foo := a.o b.o c.o
bar := $(foo:.o=.c)
与 Perl 一样具有变量中的变量机制, 看看两个等同例子, 其输出都是 "Hello"
等同于:
subst 是把 $x 中的 "1' 替换成 "2".
make 预设以接在 make 之后的参数作为预设的参数, 也就是等同于 ":=" 的使用, 如果 makefile 中想在覆盖这些参数, 可以使用 override 指示符:
override a = b
override a := b
override a += b
override define foo
bar
endef
谈谈目标变量, 在规则规则内忽略全局变量, 不管 CFLAGS 全局变量为何, 在 prog 目标内, CFLAGS 永远为 -g
12. 条件表示式
ifeq, ifneq, ifdef, ifndef, 以下为示例:
13. 函数
makefile 中函数的使用以 "$" 来标示, 看看以下示例, 空格以",", 则其结果 bar = 'a,b,c".
1) 字符串函数
subst <arg1> <arg2> <arg>: 将 arg 中的 <arg1> 替换成 <arg2>
patsubst <pattern> <replace> <arg>: 将 arg 中符合 <pattern> 替换成 <replace>
strip <arg>: 将 <arg> 中开头跟结尾的空格去除
findstring <find> <target>: 在 <target> 寻找 <find>, 找到返回 <find>, 反之返回 "" (空字符串)
filter <pattern> <arg>: 保留 <arg> 中, 符合 <pattern> 的单词
filterout <pattern> <arg>: 与 filter 相反, 保留不符合 <pattern> 的单词
sort <list>: 将 <list> 的单词升序排列
word <number> <text>: 取第 <number> 个单词, 从 1 开始.
wordlist <from>, <to>, <list>: 从第 <from> 到 <to>, 将 <list> 单词取出
words <list>: 返回单词个数
firstword <list>: 返回第一个单词
2) 文件操作函数
dir <names>: 取 <names> 中各单词的目录名, 最后一个 "/" 之前的字串, 如果没有 "/", 则返回 "./"
notdir <names>: 取 <names> 中单词的档案名
suffix <names>: 取 <names> 中单词的副档名, 若无副档名返回空字串, 如 $(suffix a.c) 返回 ".c"
basename <names>: 取 <names> 中单词的前缀部分, 若无前缀返回空字串
addsuffix <suffix> <names>: 将 <names> 中的单词加上后缀 <suffix>
addprefix <prefix> <names>: 将 <prefix> 加在 <names> 中的单词之前
join <list1> <list2>: 将 <list1> 中的单词与 <list2> 中的单词分别连接, 如 $(join aaa bbb, 111 222) 返回 "aaa111 bbb222"
3) foreach
foreach <var> <list> <text>:
将 <list> 的单词取出以 <var> 在 <text> 表示再返回, 如下例: $files = "a.o b.o c.o d.o"
names := a b c d
files := $(foreach n, $(names), $(n).o)
4) call
call <expression> <arg1> <arg2>: 创建参数化的函数
reverse = $(1) $(2)
foo = $(call reverse, a, b)
则 $foo = "a b"
5) origin
origin <variable>: 告知 <variable> 是从哪来的, 其返回值有:
"undefined": 从没被定义
"default": 默认的的定义
"environment": 环境变量, 且 make 执行时, "-e" 没有被打开
"file": 定义在 makefile 中
"command line": 被命令行定义
"override": 被 override 指示符重新定义
'automatic": 自动化变量
origin 应用的示例如, 我们想判断 foo 这变量如果由环境而来, 则重新定义, 若是其他来源, 则不重新定义.
ifdef foo
ifeq "$(origin foo)" "environment"
foo = b, g, etc.
endif
endif
6) 控制 make 的函数
error & warning: error 会中断 make, warning 则不会, 用法都是一样.
error <text>: 输出错误讯息并中断 make
warning <text>: 输出警告不中断 make
- Knowing makefile in linux
- knowing
- Linux中的Makefile.in文件
- Knowing MTD
- Knowing+NTLM
- Makefile Makefile.am Makefile.in
- makefile.in
- makefile.am VS makefile.in
- makefile.am 与 makefile.in
- Makefile.am和Makefile.in
- makefile.am 与 makefile.in
- makefile.am和makefile.in
- makefile.am和makefile.in
- Makefile makefile.am makefile.in configure
- Makefile.am和makefile.in生成Makefile
- Knowing Your Team
- Linux Makefile
- linux makefile
- 『phphot』【SD2.0大会】胡百师从项目管理看SOA 称SOA并非新观念
- Answer to Chapter 3 of O'Reilly Learning Sql on SQL Server 2005
- ArcMap的书签操作
- 学习管道
- WebGIS的书签 MapXtreme VS2008(C#) Sql Server2005
- Knowing makefile in linux
- insert all
- 『phphot』【SD2.0大会】技术:为Tomcat配置SSL功能的实验步骤
- 我的电脑学习历程.第二章.电脑技术的第一次飞跃
- 『phphot』【SD2.0大会】讲师范路:我技术不行,用RoR搭建一个网站用两天
- 快速测试一条Select SQL语句是否合法
- Struts2标签介绍
- 『phphot』【SD2.0大会】蒋涛:CSDN为什么举办SD2C大会
- 10分钟学会Ajax