Makefile override 指示符

一个变量可以定义在Makefile中,也可以在执行make时通过命令行定义。一个在Makefile中定义的变量,如果在执行make命令时又定义了一次,那么它将替代在Makefile中出现的同名变量。也就是说,在一个Makefile中使用define、:=、= 定义的变量,我们可以在执行make命令时重新指定这个变量的值。

.PHONY: all

web = www.zhaixue.cc

all:
    @echo "web = $(web)"

在上面的Makefile中,我们定义了一个变量:web,在执行make时如果重新给web赋值,然后在Makefile中就可以打印出重新赋的值:

# make
web = www.zhaixue.cc
# make web=wanglitao.taobao.com
web = wanglitao.taobao.com

如果不希望在命令行指定的变量值替代在Makefile中的原来定义,那么我们可以在Makefile中使用指示符 override 对这个变量进行声明:

.PHONY: all

override web = www.zhaixue.cc

all:
    @echo "web = $(web)"

一个变量使用override修饰后,用户在命令行中重新赋值,不会对Makefile中的变量定义产生影响,无论用户在命令行中如何修改,make始终打印的是Makefile中定义的值:

# make web=wanglitao.taobao.com
web = www.zhaixue.cc

追加赋值

Makefile中的变量分为多种:追加变量、立即变量、展开变量、使用define定义的变量,它们都可以使用override修饰:

override VARIABLE = VALUE
override VARIABLE := VALUE
override VARIABLE += MORE TEXT
override define foo

当一个追加变量在定义时使用了override,后续对它的值进行追加时,也需要使用带有override指示符的追加方式。否则对此变量值的追加不会有效。

.PHONY: all

override fruits = apple
fruits += banana
all:
    @echo "fruits = $(fruits)"

如上面定义的fruits变量,在定义时因为使用了override修饰,在对其追加赋值时,因为没有使用override修饰,所以追加是无效的“

# make
fruits = apple

override存在的意义

override的主要目的是为了使用户可以改变或者追加哪些使用make命令行指定的变量的定义。从另一个角度上看,就是实现了在Makefile中增加或者修改命令行参数的一种机制。

我们在编译程序时,可能会有这样一些需求:通过命令行来指定一些额外的编译参数。而对于一些通用或者必需的参数则在Makefile中指定,一些特殊的参数则在命令行中指定。

比如在编译程序时,无论在命令行指定什么参数,编译器在编译时必需打开 -Wall选项,那么在Makefile中的CFLAGS应该这样定义:

.PHONY: all

override CFLAGS += -Wall

all:
    @echo "CFLAGS = $(CFLAGS)"

当执行make命令时,默认的CFLAGS是-Wall;当执行make CFLAGS=-g时,CFLAGS就变成了 -Wall -g:

# make
CFLAGS = -Wall

# make CFLAGS=-g
CFLAGS = -g -Wall

如果在Makefile中定义CFLAGS变量时,不使用override修饰:

.PHONY: all

CFLAGS += -Wall

all:
    @echo "CFLAGS = $(CFLAGS)"

再次执行上面的make命令,运行结果就发生了变化:

# make
CFLAGS = -Wall

# make CFLAGS=-g
CFLAGS = -g

这就跟我们预先设定的不一致了:当在命令行中给CFLAGS追加赋值时,原来的-Wall选项就被覆盖掉了。而使用override修饰就不会发生这种情况。

《Makefile工程实践》视频教程,一线开发工程师独家录制,网上首家讲解Makefile的实战课程。从零开始,教你一步一步编写一个工程项目的Makefile,支持使用第三方静态库、动态库,支持指定模块或目录编译生成静态库、动态库,赠送企业级的Makefile模板,学完即可拿来使用,投入项目开发实战,具备独立开展项目开发和管理的能力。详情请点击淘宝链接:Linux三剑客