您的位置:首页 > 其它

学会使用makefile:3

2016-01-12 16:26 232 查看
 前面写的makefile的相关只是都没有使用到变量,依照变量,makefile可以使用的非常多变。
foo = $(bar)bar = Huh?all:@echo $(foo)
上面这个例子执行 make 将会打出 Huh?当 make 读到 foo = $(bar) 时,确定 foo 的值是 $(bar) ,但并不立即展开 $(bar) ,然后读到 bar = Huh? ,确定 bar 的值是 Huh?通过上面这个特点,我们可以讲变量的值推迟到后面去定义:
main.o: main.c$(CC) $(CFLAGS) $(CPPFLAGS) -c $<CC = gccCFLAGS = -O -gCPPFLAGS = -Iinclude
像上面这样,编译选项就可以展开生成为:gcc -O -g -Iinclude -c main.c通常把 CFLAGS 定义成一些编译选项,例如 -O 、 -g 等,而把 CPPFLAGS 定义成一些预处理选项,例如 -D 、 -I 等。如果希望makefile在遇到赋值的时候立刻展开,可以使用:=来代替= ,下面这个例子
root@wc:~/Codes/Learn# cat makefilex := fooy := $(x) bar!all:@echo "$(y)"root@wc:~/Codes/Learn# make allfoo bar!root@wc:~/Codes/Learn# 
如果x 和 y的位置交换,那么赋值的时候x会被展开成为一个空值还有一种有用的赋值运算符是?=:例如 foo ?= $(bar) 的意思是:如果 foo 没有定义过,那么 ?= 相当于 = ,定义 foo 的值是 $(bar) ,但不立即展开;如果先前已经定义了 foo ,则什么也不做,不会给 foo 重新赋值。另一种是+=,其可以给变量追加值,+=依旧保持着=或者:=的特性,主要看这个变量原先是怎么定义的。如果变量还没有定义过就直接用 += 赋值,那么 += 相当于 = 。类似$@这样的特殊变量还有:
$@ ,表示规则中的目标。$< ,表示规则中的第一个条件。$? ,表示规则中所有比目标新的条件,组成一个列表,以空格分隔。$^ ,表示规则中的所有条件,组成一个列表,以空格分隔。
按照上面,下面的两条语句实际上就是等价的了:
main: main.o stack.o maze.ogcc main.o stack.o maze.o -o mainmain: main.o stack.o maze.ogcc $^ -o $@
这样即使以后又往条件里添加了新的目标文件,编译命令也不需要修改,减少了出错的可能。$? 变量也很有用,有时候希望只对更新过的条件进行操作,例如有一个库文件 libsome.a 依赖于几个目标文件:
libsome.a: foo.o bar.o lose.o win.oar r libsome.a $?ranlib libsome.a
这样,只有更新过的目标文件才需要重新打包到 libsome.a 中,没更新过的目标文件原本已经在 libsome.a 中了,不必重新打包。第一节中可以看到默认规则中有很多变量,类似CC,CFLAGS,CC默认值为cc,而CFLAGS的默认值为空,类似的变量还有很多:
AR  静态库打包命令的名字,缺省值是 ar 。ARFLAGS     静态库打包命令的选项,缺省值是 rv 。AS     汇编器的名字,缺省值是 as 。ASFLAGS     汇编器的选项,没有定义。CC     C编译器的名字,缺省值是 cc 。CFLAGS     C编译器的选项,没有定义。CXX     C++编译器的名字,缺省值是 g++ 。CXXFLAGS     C++编译器的选项,没有定义。CPP     C预处理器的名字,缺省值是 $(CC) -E 。CPPFLAGS     C预处理器的选项,没有定义。LD     链接器的名字,缺省值是 ld 。LDFLAGS     链接器的选项,没有定义。TARGET_ARCH  和目标平台相关的命令行选项,没有定义。OUTPUT_OPTION  输出的命令行选项,缺省值是 -o $@ 。LINK.o  把 .o 文件链接在一起的命令行,缺省值是 $(CC) $(LDFLAGS) $(TARGET_ARCH) 。LINK.c   把 .c 文件链接在一起的命令行,缺省值是 $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)$(TARGET_ARCH) 。 
LINK.cc   把 .cc 文件(C++源文件)链接在一起的命令行,缺省值是 $(CXX) $(CXXFLAGS)$(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) 。COMPILE.c   编译 .c 文件的命令行,缺省值是 $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 。COMPILE.cc  编译 .cc 文件的命令行,缺省值是 $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 。RM  删除命令的名字,缺省值是 rm -f 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: