Define a Makefile variable using a ENV variable or a default value

I am trying to do a simple thing:

TMPDIR ?= /tmp


test:
@echo $(TMPDIR)

This works if I run:

$ make test
/tmp

It also works if I run:

$ make test -e TMPDIR=~/tmp
/home/user/tmp

What can I do to also have it works for:

$ TMPDIR=~/tmp make test
/home/user/tmp
93679 次浏览

你可以做的一件事是:

TMPDIR := "/tmp"


ifdef $$TMPDIR
TMPDIR := $$TMPDIR
endif


test:
echo $(TMPDIR)

make命令行上指定的变量覆盖 makefile 中分配的值:

TMPDIR := "/tmp"
test:
@echo $(TMPDIR)

然后:

make TMPDIR=whatever
whatever

通常认为 makefile 依赖于环境变量是一种不好的做法,因为这可能导致不可重现的构建。这就是为什么显式地建议在 make命令行中传递变量重写。

为了跟进我上面的评论,这里有一个例子:

T ?= foo
all:
: '$(T)'

现在,如果我以不同的方式运行 Makefile,它就会按照我们预期的方式运行(只有在命令行或环境中不设置 T的情况下,我才能得到 foo) :

$ make
: 'foo'


$ make T=bar
: 'bar'


$ T=bar make
: 'bar'

这里有一个简单的解决办法:

SHELL  := env TMPDIR=$(TMPDIR) $(SHELL)
TMPDIR ?= "/tmp"


all:
@echo $(TMPDIR)

它适用于两种情况: TMPDIR=new/path makemake TMPDIR=new/path