学会使用makefile:3
2016-08-07 00:00
232 查看
前面写的makefile的相关只是都没有使用到变量,依照变量,makefile可以使用的非常多变。
上面这个例子执行 make 将会打出 Huh?当 make 读到 foo = $(bar) 时,确定 foo 的值是 $(bar) ,但并不立即展开 $(bar) ,然后读到 bar = Huh? ,确定 bar 的值是 Huh?
通过上面这个特点,我们可以讲变量的值推迟到后面去定义:
像上面这样,编译选项就可以展开生成为:gcc -O -g -Iinclude -c main.c
通常把 CFLAGS 定义成一些编译选项,例如 -O 、 -g 等,而把 CPPFLAGS 定义成一些预处理选项,例如 -D 、 -I 等。
如果希望makefile在遇到赋值的时候立刻展开,可以使用:=来代替= ,下面这个例子
如果x 和 y的位置交换,那么赋值的时候x会被展开成为一个空值
还有一种有用的赋值运算符是?=:例如 foo ?= $(bar) 的意思是:如果 foo 没有定义过,那么 ?= 相当于 = ,定义 foo 的值是 $(bar) ,但不立即展开;如果先前已经定义了 foo ,则什么也不做,不会给 foo 重新赋值。
另一种是+=,其可以给变量追加值,+=依旧保持着=或者:=的特性,主要看这个变量原先是怎么定义的。如果变量还没有定义过就直接用 += 赋值,那么 += 相当于 = 。
类似$@这样的特殊变量还有:
按照上面,下面的两条语句实际上就是等价的了:
这样即使以后又往条件里添加了新的目标文件,编译命令也不需要修改,减少了出错的可能。
$? 变量也很有用,有时候希望只对更新过的条件进行操作,例如有一个库文件 libsome.a 依赖于几个目标文件:
这样,只有更新过的目标文件才需要重新打包到 libsome.a 中,没更新过的目标文件原本已经在 libsome.a 中了,不必重新打包。
第一节中可以看到默认规则中有很多变量,类似CC,CFLAGS,CC默认值为cc,而CFLAGS的默认值为空,类似的变量还有很多:
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 = gcc CFLAGS = -O -g CPPFLAGS = -Iinclude
像上面这样,编译选项就可以展开生成为:gcc -O -g -Iinclude -c main.c
通常把 CFLAGS 定义成一些编译选项,例如 -O 、 -g 等,而把 CPPFLAGS 定义成一些预处理选项,例如 -D 、 -I 等。
如果希望makefile在遇到赋值的时候立刻展开,可以使用:=来代替= ,下面这个例子
root@wc:~/Codes/Learn# cat makefile x := foo y := $(x) bar! all: @echo "$(y)" root@wc:~/Codes/Learn# make all foo bar! root@wc:~/Codes/Learn#
如果x 和 y的位置交换,那么赋值的时候x会被展开成为一个空值
还有一种有用的赋值运算符是?=:例如 foo ?= $(bar) 的意思是:如果 foo 没有定义过,那么 ?= 相当于 = ,定义 foo 的值是 $(bar) ,但不立即展开;如果先前已经定义了 foo ,则什么也不做,不会给 foo 重新赋值。
另一种是+=,其可以给变量追加值,+=依旧保持着=或者:=的特性,主要看这个变量原先是怎么定义的。如果变量还没有定义过就直接用 += 赋值,那么 += 相当于 = 。
类似$@这样的特殊变量还有:
$@ ,表示规则中的目标。 $< ,表示规则中的第一个条件。 $? ,表示规则中所有比目标新的条件,组成一个列表,以空格分隔。 $^ ,表示规则中的所有条件,组成一个列表,以空格分隔。
按照上面,下面的两条语句实际上就是等价的了:
main: main.o stack.o maze.o gcc main.o stack.o maze.o -o main main: main.o stack.o maze.o gcc $^ -o $@
这样即使以后又往条件里添加了新的目标文件,编译命令也不需要修改,减少了出错的可能。
$? 变量也很有用,有时候希望只对更新过的条件进行操作,例如有一个库文件 libsome.a 依赖于几个目标文件:
libsome.a: foo.o bar.o lose.o win.o ar 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 。
相关文章推荐
- 学会使用makefile:3
- 学会使用makefile:5
- 学会使用makefile:1
- 学会使用makefile:5
- 学会使用makefile:4
- 学会使用makefile:2
- 学会使用makefile:4
- 学会使用makefile:2
- 学会使用makefile:1
- 学会在ASP中使用存储过程
- 使用AutoMake轻松生成Makefile
- [转载]使用Automake,Autoconf生成Makefile
- 5天学会使用NoahWeb表现层制作动态网站(第二天)
- 编写 "纯HTML" jsp应用--学会使用 JSTL
- 学会在ASP中使用存储过程
- 5天学会使用NoahWeb表现层制作动态网站(第三天)
- 学会使用SafeArray
- 使用makefile的简单例子
- 5天学会使用NoahWeb表现层制作动态网站(第一天)
- 学会使用Linux性能分析工具