学会使用makefile:3

前面写的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 = 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 。

 

 

 

转载于:https://my.oschina.net/u/2310741/blog/729157

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值