如何有条件地设置 Makefile 变量的东西,如果它是空的?

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

....
TEST := $(something)
...
TEST ?= $(something else)

第一个 $(something)可能返回一个空字符串,但条件赋值?= 仅在未设置前一个变量的情况下工作,而不是在为空的情况下工作。

如果变量为空,有什么优雅的解决方案吗?


剪辑 我找到了解决办法:

....
TEST := $(something)
...
TEST += $(something else)
TEST := $(word 1, $(TEST))

但我觉得会有一个更优雅的。

139571 次浏览

Any elegant solution to set the variable if empty?

GNU make is hardly known for elegant solutions. Unless you find trapdoors and minefields to be elegant. I know only of the two ways to accomplish what you want:

  1. The standard ifeq/endif solution:

    ifeq ($(TEST),)
    TEST := $(something else)
    endif
    
  2. Use the $(if) function:

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

    One can try to package that construct into a function too, but that is inadvisable. The function would have the hidden pitfall of occasionally breaking the $(something else) if it contains the , (for which there are only wayward workarounds). (The built-in functions like $(if) are immune to the , bug.)

Elegance test is up to you.

From GNU make, chapter 7.2, Syntax of Conditionals:

"Often you want to test if a variable has a non-empty value. When the value results from complex expansions of variables and functions, expansions you would consider empty may actually contain whitespace characters and thus are not seen as empty. However, you can use the strip function to avoid interpreting whitespace as a non-empty value. For example:

ifeq ($(strip $(foo)),)
text-if-empty
endif

will evaluate text-if-empty even if the expansion of $(foo) contains whitespace characters."

Here's another alternative that I personally find quite elegant, because it's a one-liner and doesn't need the redundant else-branch:

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

Just in case anyone stumbled upon putting the condition in the rule itself. below how I did it, thought it might help others.

In Makefile, suppose we have the following rule with check target and we need to check whether var was passed.

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

To test this out, run the following commands

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


$ make check var=test
all good

So, Now we can pass the variable value or a default value in case it was not passed to a bash script that will be responsible to do the logic. something like the following:

@[ "${var}" ] && ./b.sh ${var} || ./b.sh 'ss'

Here's below what b.sh might look like, though you can add more logic to it.

#!/bin/sh
echo $1

In case you need to distinguish if a variable is undefined or just has an empty value, use $(origin VARNAME) function:

ifeq ($(origin VARNAME),undefined)
VARNAME := "now it's finally defined"
endif

Note that VARNAME is not surrounded by $() - you literally give the name of the variable.

Folks, I think there's a simpler solution

KDIR ?= "foo"

From: What is ?= in Makefile

Setting value to variable in Makefile if value defined

ifdef RELEASE_BRANCH
GIT_TAG=$(shell cat projects/${RELEASE_BRANCH}/GIT_TAG)
else
GIT_TAG=$(shell cat release/DEFAULT_GIT_TAG)
endif