嵌入式LINUX编程中,Makefile是必须涉及的.作为笔记,仅对工作学习常用的MAKEFILE知识点进行汇总.
1.MAKEFILE的基本规则:
target:prerequisites
command
...
各项的意义如下:
target:目标文件;
prerequisites:生成目标文件的依赖文件;
command:编译规则,是make需要执行的命令(任意shell命令).
如下面的示意代码:
hello: hello.c
gcc -o hello hllo.c
clean:
rm -f hello
[注:]编译规则项必须以Tab键进行缩进.
2.MAKEFILE中使用变量
平时编译程序时,往往涉及到多个源文件.MAKEFILE引入了变量,简化了工作量、清晰了代码.
Makefile中变量的赋值有两种方式:延时变量和立即变量.区别在于它们的定义方式和扩展时的方式不同.
延时变量:
在这个变量使用时才展开;
定义延时变量示例:
immediate = deferred
立即变量:
在定义时已经确定下来
定义立即变量示例:
immediate := immediate
.
Makefile变量的引用:
括号括起来外加"$"符号.
如:
objects = xxx0.o xxx1.o xxx2.o
edit:$(objects)
3.Makefile常用函数
Makefile中函数调用格式如下:
$(function,arguments)
各项意义如下:
function:函数名.
arguments:该函数参数.
[注:]参数和函数名之间要用空格隔开,如果有多个参数,参数之间用逗号隔开.
3-1. 字符串替换和分析函数
3-1-1 $(subst from,to,text)
在文本"text"中使用"to"替换每一处"from".
如:
$(subst ee,EE,feet on the street)
输出结果:
fEEt on the strEEt
3-1-2 $(patsubst pattern,replacement,text)
寻找"pattern"中符合格式"pattern"的字,用"replacement"替换它们."pattern"和"replacement"中可以使用通配符.
如:
$(patsubst %.c,%.o,x.c.c bar.c)
输出结果:
x.c.o bar.o
3-1-3 $(strip string)
去掉前导和结尾空格,并将中间的多个空格压缩为单个空格.
如:
$(strip a b c)
输出结果:
a b c
3-1-4 $(findstring find,in)
在字符串"in"中搜索"find",如果找到,返回"find",否则返回空.
如:
$(findstring a,a b c)
$(findstring a,b c)
输出结果:
a和空.
3-1-5 $(filter pattern...,text)
返回在"text"中由空格隔开且匹配格式"pattern..."的字,去除不符合格式"pattern..."的字.
如:
$(filter %.c %.s,foo.c bar.c baz.s ugh.h)
输出结果:
foo.c bar.c baz.s
3-1-6 $(filter-out pattern...,text)
返回"text"中由空格隔开且不匹配格式"pattern..."的字,去除符合格式"pattern..."的字.它是函数filter的反函数.
如:
$(filter-out %.c %.s,foo.c bar.c baz.s ugh.h)
输出结果:
ugh.h
3-1-7 $(sort list)
将"list"中的字按字母顺序排序,并去掉重复的字.输出由单个空格隔开的字的列表.
如:
$(sort foo bar lose)
输出结果:
bar foo lose
3-2 文件名函数
3-2-1 $(dir names...)
抽取"names..."中每一个文件名的路径部分.文件名的路径部分包括从文件名的首字母符到最后一个斜杠(含斜杠)之前的一切字符.
如:
$(dir src/foo.c hacks)
输出结果:
src/ ./
3-2-2 $(notdir names...)
抽取"names..."中每一个文件名除路径部分一切字符(真正的文件名).
如:
$(notdir src/foo.c hacks)
输出结果:
foo.c hacks
3-2-3 $(suffix names...)
抽取"names..."中每一个文件名的后缀.
如:
$(suffix src/foo.c src-1.0/bar.c hacks)
输出结果:
.c .c
3-2-4 $(basename names...)
抽取"name..."中每一个文件名中除后缀外的一切字符.
如:
$(basename src/foo.c src-1.0/bar hacks)
输出结果:
src/foo src-1.0/bar hacks
3-2-5 $(addsuffix suffix,names...)
参数"names..."是一系列的文件名,文件名之间用空格隔开;suffix是一个后缀名.将suffix(后缀)的值附加在每一个独立文件名的后面,
完成后将文件名串联起来,它们之间用单个空格隔开.
如:
$(addsuffix .c,foo bar)
输出结果:
foo.c bar.c
3-2-6 $(addprefix prefix,names...)
参数"names..."是一系列文件名,文件名之间用空格隔开;prefix是一个前缀名.将prefix(前缀)的值附加在每一个独立文件名的前面,
完成后将文件名串联起来,它们之间用单个空格隔开.
如:
$(addprefix src/,foo bar)
输出结果:
src/foo src/bar
3-2-7 $(wildcard pattern)
参数"pattern"是一个文件名格式,包含有通配符.函数wildcard的结果是一列和格式匹配且真实存在的文件的名称,文件名
之间用一个空格隔开.
如:
当前目录下有文件1.c、2.c、1.h、2.h,则:
c_src := $(wildcard *.c)
输出结果:
1.c 2.c
3-3 其他函数
3-3-1 $(foreach var,list,text)
<variable>;是变量的名字,不应该是引用。所以你最好不要在<variable>;中使用“$”字符。Origin函数会以其返回值来告诉你这个变量的“出生情况”,下面,是origin函数的返回值:
“undefined”
如果<variable>;从来没有定义过,origin函数返回这个值“undefined”.
“default”
如果<variable>;是一个默认的定义,比如“CC”这个变量,这种变量我们将在后面讲述.
“environment”
如果<variable>;是一个环境变量,并且当Makefile被执行时,“-e”参数没有被打开.
“file”
如果<variable>;这个变量被定义在Makefile中.
“command line”
如果<variable>;这个变量是被命令行定义的.
“override”
如果<variable>;是被override指示符重新定义的.
3-3-2 $(shell command arguments)
shell函数和实际在终端的操作一样.
如:
当前目录下有文件1.c、2.c、1.h、2.h,则:
c_src := $(shell ls *.c)
输出结果:
1.c 2.c
3-3-3 $(call <expression>,<parm1>,<parm2>,<parm3>...)
当 make执行这个函数时,<expression>参数中的变量,如$(1),$(2),$(3)等,会被参数
<parm1>,<parm2>,<parm3>依次取代。而<expression>的返回值就是 call函数的返回值.
例如:
reverse = $(1) $(2)
foo = $(call reverse,a,b)
那么,foo的值就是“a b”。当然,参数的次序是可以自定义的,不一定是顺序的,如:
reverse = $(2) $(1)
foo = $(call reverse,a,b)
此时的foo的值就是“b a”。