2012年(10)
分类: Python/Ruby
2012-10-23 17:49:09
再看两个源文件编译成的程序:
//file:main.c
#include
int add(int a,int b);
int main()
{
printf("%d\n",add(2,3));
}
//file:add.c
int add(int a,int b)
{
return (a+b);
}
//makefile
add : main.o add.o
gcc -o add main.o add.o
main.o : main.c
gcc -c -o main.o main.c
add.o : add.c
gcc -c -o add.o add.c
.PHONY : clean
clean:
rm *.o add
大致是以上面的hello是一样的,不过add有两个依赖。
注意的是make支持3种通配符,分别是:
“*”,“?”,“[…]”例如上面的“*.o”表示所有的object code,要表示真正的“*”时要加上转义字符“\”,即“\*”
在makefile中使用变量:
makefile的变量也就是一个字符串,类似于C中的宏,使用makefile使得修改更加简单,不易出错。例如:
object = main.o add.o 这里可以加上新的.o文件
add : $(object)
gcc -o add $(object)
main.o : main.c
gcc -c -o main.o main.c
add.o : add.c
gcc -c -o add.o add.c
.PHONY : clean
clean:
rm $(object) add
增加一个 new object code时仅需在object加上就可以了,既简单又避免遗漏。
在上面的例子中,就很容易知道makefile变量的使用方法:
1、变量声明时需要赋予初值。
2、makefile变量使用时需要给在变量名前加上“$ ”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。如果你要使用真实的“$ ”字符,那么你需要用“$$”来表示。
3、变量就像C中的宏一样在它使用的位置展开。
makefile中的变量的变量:
1、简单的使用“=”号,在“=”左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值。
例如:puts = $(object)
object = Hello?
all:
echo $(puts)
执行make all 打印变量的值为hello。
这个方法的缺点:makefile会有很多展开的过程。
简单应用:
object = main.o add.o
add : $(object)
gcc -o add $(object)
main.o : main.c
gcc -c -o main.o main.c
add.o : add.c
gcc -c -o add.o add.c
foo = $(object)
.PHONY : clean
clean:
rm $(foo) add
2、使用“:=”操作符
例如上面的:
object = main.o add.o
add : $(object)
gcc -o add $(object)
main.o : main.c
gcc -c -o main.o main.c
add.o : add.c
gcc -c -o add.o add.c
foo := $(object)
.PHONY : clean
clean:
rm $(foo) add
前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。
“?=”比较符:
例如:
foo ?= bar //如果foo没有定义过,那么foo的值就是bar
变量值的替换:
替换变量中的共有的部分,其格式是“$(var:a=b) ”或是“${var:a=b} ”,其
意思是,把变量“var ”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。(可以为后缀)
例如:
object = main.o add.o
foo = $(object : .o=.c)
把main.o add.o 改为main.c add.c
以静态方式转换:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
这依赖于被替换字串中的有相同的模式,模式中必须包含一个“% ”字符,这个例子同样让$(bar)变量的值为“a.c b.c c.c”。
把变量的值变成变量:
x = y
y = z
a := $($(x))
在这个例子中,$(x)的值是“y”,所以$($(x))就是$(y),于是 $(a)的值就是“z”。(注
意,是“x=y ”,而不是“x=$(y)”)
追加变量:
使用“+=”操作符
例如:
object = main.o
object+=add.o
add : $(object)
gcc -o add $(object)
main.o : main.c
gcc -c -o main.o main.c
add.o : add.c
gcc -c -o add.o add.c
foo := $(object)
.PHONY : clean
clean:
rm $(foo) add
多行变量: define 指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef 关键字 结束。其工作方式和“= ”操作符一样。变量的值可以包含函数、命令、文字,或是其它变 量。因为命令需要以[Tab]
键开头,所以如果你用 define 定义的命令变量中没有以[Tab] 键开头,那么make 就不会把其认为是命令。 下面的这个示例展示了define 的用法: define two-lines echo foo echo $(bar) endef 以endef结束(在行首) make的自动推导: GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。 只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的makefile再也不用写得这么复杂。 原: object s = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o #反斜杠(\)是换行符的意思,这 #样比较便于Makefile的阅读 edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit $(objects) 利用自动推导可变为:(就是将上面的蓝色部分去掉) objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : defs.h kbd.o : defs.h command.h command.o : defs.h command.h display.o : defs.h buffer.h insert.o : defs.h buffer.h search.o : defs.h buffer.h files.o : defs.h buffer.h command.h utils.o : defs.h .PHONY : clean clean : rm edit $(objects) 未完....