如果变量为空,则设置Makefile

Ric*_*ico 48 makefile

我想设置一个变量,如果它是空的.我试过这样的方式:

....
TEST := $(something)
...
TEST ?= $(something else)
Run Code Online (Sandbox Code Playgroud)

第一个$(something)可能返回一个空字符串,但是条件赋值?=仅在未设置前一个变量时才起作用,而不是在为空时.

任何优雅的解决方案,如果设置变量为空?


编辑 我找到了这个解决方案:

....
TEST := $(something)
...
TEST += $(something else)
TEST := $(word 1, $(TEST))
Run Code Online (Sandbox Code Playgroud)

但我认为会有一个更优雅.

Dum*_*001 86

任何优雅的解决方案,如果设置变量为空?

GNU make以优雅的解决方案而闻名.除非你发现陷门和雷区优雅.我只知道实现你想要的两种方法:

  1. 标准ifeq/ endif解决方案:

    ifeq ($(TEST),)
    TEST := $(something else)
    endif
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用$(if)功能:

    TEST := $(if $(TEST),$(TEST),$(something else))
    
    Run Code Online (Sandbox Code Playgroud)

    可以尝试将该构造打包成函数,但这是不可取的.这个函数会有一个隐藏的陷阱,偶尔会破坏$(something else)它是否包含,(为此只有任性的解决方法).(内置函数$(if)不受,bug的影响.)

优雅测试取决于你.

  • “GNU make 几乎不以优雅的解决方案而闻名。除非你发现活板门和雷区是优雅的。” 感谢您在这个痛苦的时期创造了一些轻浮。 (7认同)
  • 但请记住,如果您在 CLI 上传递 `TEST=`,无论如何它都会覆盖 `TEST:=`。 (2认同)
  • 我建议不要使用`ifeq($(VAR),)`而不是`ifdef VAR`。 (2认同)

Dan*_*jel 12

GNU make,第7.2章,条件语法:

"通常你想测试变量是否具有非空值.当值由变量和函数的复杂扩展产生时,你认为空的扩展实际上可能包含空格字符,因此不会被视为空.但是,你可以使用strip函数来避免将空格解释为非空值.例如:

ifeq ($(strip $(foo)),)
text-if-empty
endif
Run Code Online (Sandbox Code Playgroud)

即使$(foo)的扩展包含空格字符,也会评估text-if-empty."


Muh*_*man 10

以防万一有人无意中将条件放入规则本身。下面是我的做法,认为对其他人可能有帮助。

在 中Makefile,假设我们有以下带有checktarget 的规则,我们需要检查 var 是否被传递。

check:
    @[ "${var}" ] && echo "all good" || ( echo "var is not set"; exit 1 )
Run Code Online (Sandbox Code Playgroud)

要对此进行测试,请运行以下命令

$ make check 
  var is not set
  make: *** [check] Error 1  

$ make check var=test
  all good 
Run Code Online (Sandbox Code Playgroud)

所以,现在我们可以传递变量值或默认值,以防它没有传递给负责执行逻辑的 bash 脚本。像下面这样:

@[ "${var}" ] && ./b.sh ${var} || ./b.sh 'ss'
Run Code Online (Sandbox Code Playgroud)

下面是b.sh可能的样子,不过您可以向其中添加更多逻辑。

#!/bin/sh
echo $1
Run Code Online (Sandbox Code Playgroud)


Tom*_*nio 9

这是我个人觉得很优雅的另一种选择,因为它是单线的,不需要多余的else-branch:

TEST := $(or $(TEST),$(something else))

  • + 1 + `TGT_DIR := $(or $(TGT_DIR),"the-default-string-value")` 使 `$(something else)` 成为要后备的硬编码字符串 (6认同)

Pet*_*ahn 7

伙计们,我认为有一个更简单的解决方案

KDIR ?= "foo"
Run Code Online (Sandbox Code Playgroud)

来自:Makefile 中的 ?= 是什么

  • OP 在他们的问题中排除了这一点:如果“KDIR”包含空字符串,只有当变量完全未定义时,条件赋值才不会触发。 (4认同)

Vic*_*nko 6

如果您需要区分变量是未定义还是只有空值,请使用$(origin VARNAME)函数:

ifeq ($(origin VARNAME),undefined)
VARNAME := "now it's finally defined"
endif
Run Code Online (Sandbox Code Playgroud)

请注意, VARNAME 并没有被$()- 您从字面上给出变量的名称。