使用ENV变量或默认值定义Makefile变量


77

我正在尝试做一个简单的事情:

TMPDIR ?= /tmp

test:
    @echo $(TMPDIR)

如果我运行,这可以工作:

$ make test
/tmp

如果我运行它也可以:

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

我也可以做些什么来使其适用于:

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

4
嗯...您所做的工作正常(如果您使用?=并且设置了环境变量,那么将使用环境变量的值代替)。到底是什么问题(为什么您认为它不起作用)?
MadScientist 2014年

1
也是仅供参考,在makefile中的变量值中添加引号通常不是一个好主意。
MadScientist 2014年

是的,我经过仔细检查并与之合作TMPDIR ?= "/tmp"echo $(TMPDIR)唯一的事情就是不要忘记变量名周围的括号。
纳蒂姆2014年

1
您有-e向后使用的功能。-e表示允许env var覆盖makefile中定义的变量,它们不影响来自命令行参数的变量分配。
Etan Reisner 2014年

1
对不起Natim,但?= 确实可以。如果它没有做您想要的事情,那么上面的解释会令人困惑,我们无法理解您想要什么,或者您的实际环境中有一些事情没有反映在上面的问题中。
MadScientist 2014年

Answers:


129

为了跟进我上面的评论,下面是一个示例:

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

现在,如果我以各种方式运行Makefile,它的行为将与我们预期的一样(foo仅当我未T在命令行或环境中进行设置时,我才能得到):

$ make
: 'foo'

$ make T=bar
: 'bar'

$ T=bar make
: 'bar'

这是all:;:什么
Xiphias

3
all:所有目标创建规则。分号结束先决条件列表并开始第一个配方行。最后:是食谱;冒号是一种特殊的POSIX Shell运算符,基本上意味着“什么也不做”。因此,这为all目标制定了一条完整的规则,该目标具有不执行任何操作的配方。
MadScientist

我实际上更喜欢原始格式,因为它不需要将空格转换为制表符即可(很难在SO中将硬TAB放入示例中)。但是我想其他人还是批准了该编辑,所以……
MadScientist

35

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

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

然后:

make TMPDIR=whatever
whatever

通常,makefile文件依赖于环境变量是一种不好的做法,这就是为什么首选在make命令行中传递变量的原因。


另一种方法是使用makeor函数:

X := $(or ${X},${X},abc)

all :
    @echo ${X}

make
abc

X=def make 
def

实际上,您应该只使用?=分配。


1
知道的很好,但是如果设置了该如何将环境变量用作默认值?
纳蒂姆2014年

在那种特定情况下,TMPDIR是一个可能存在的变量,如果存在,我想使用它。
纳蒂姆2014年

我试过了,TMPDIR := $(or $$TMPDIR,$$TMPDIR,"/tmp")但似乎没有用。
纳蒂姆2014年

@Natim为什么要放额外的美元符号?
Maxim Egorushkin 2014年

1
似乎这些$(or调用超出了需要。这不行吗?$(or $X,abc)
内德·巴切尔德

4

这是一个简单的解决方案:

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

all:
  @echo $(TMPDIR)

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


0

您可以做的一件事是:

TMPDIR := "/tmp"

ifdef $$TMPDIR
TMPDIR := $$TMPDIR
endif

test:
    echo $(TMPDIR)

它不能以方式工作TMPDIR=~/tmp make,仅以方式运行make TMPDIR=~/tmp ,但问题是要使其同时适用于两者。
kenorb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.