如果变量不为空,则进行文件测试



在生成文件中,我正在尝试

  • 运行shell命令并在make变量中捕获输出
  • 如果变量不为空,请执行操作

我创建了这个简化的makefile来演示我的问题。make amake b都不执行if的主体,我不明白为什么不执行。

.PHONY: a b
a:
$(eval MY_VAR = $(shell echo whatever))
@echo MY_VAR is $(MY_VAR)
$(info $(MY_VAR))
ifneq ($(strip $(MY_VAR)),)
@echo "should be executed"
endif
@echo done
b:
$(eval MY_VAR = $(shell echo ''))
@echo MY_VAR is $(MY_VAR)
$(info $(MY_VAR))
ifneq ($(strip $(MY_VAR)),)
@echo "should not be executed"
endif
@echo done

我正在使用

$ make --version
GNU Make 3.81

编辑:正如所指出的,vars不需要使vars

如果您想动态测试MY_VAR的内容,您可能需要:

a:
$(eval MY_VAR = $(shell echo ''))
$(if $(strip $(MY_VAR)),echo ok,echo no)

如果MY_VAR不为空,则if评估将变为echo ok,否则将变为echo no

请注意,由于评估时间的原因,make条件语句(ifeqifneq…(不能以您尝试的方式在配方中使用。请改用shell条件语句,如下所示。

由于您的MY_VAR变量仅在配方中使用,与目标相关,并且您希望仅在需要时计算它,为什么不使用shell变量而不是make变量呢?

$ cat Makefile
.PHONY: a b
a:
MY_VAR=$$(echo 'whatever') && 
echo '$@: MY_VAR is $$MY_VAR' && 
if [ -n "$$MY_VAR" ]; then 
echo '$@: should be executed'; 
fi && 
echo '$@: done'
b:
MY_VAR=$$(echo '') && 
echo '$@: MY_VAR is $$MY_VAR' && 
if [ -n "$$MY_VAR" ]; then 
echo '$@: should not be executed'; 
fi && 
echo '$@: done'
$ make a
a: MY_VAR is whatever
a: should be executed
a: done
$ make b
b: MY_VAR is
b: done

如果你绝对需要MY_VAR作为目标特定的make变量,但只想(每个目标(执行一次产生其值的shell命令,MadScientist有一个绝妙的技巧,你可能应该看看

$ make --version
GNU Make 4.1
...
$ cat Makefile
a: MY_VAR = $(eval a: MY_VAR := $$(shell echo 'whatever'))$(MY_VAR)
b: MY_VAR = $(eval b: MY_VAR := $$(shell echo ''))$(MY_VAR)
a:
@echo '$@: MY_VAR is $(MY_VAR)' && 
if [ -n "$(MY_VAR)" ]; then 
echo '$@: should be executed'; 
fi && 
echo '$@: done'
b:
@echo '$@: MY_VAR is $(MY_VAR)' && 
if [ -n "$(MY_VAR)" ]; then 
echo '$@: should not be executed'; 
fi && 
echo '$@: done'
$ make a
a: MY_VAR is whatever
a: should be executed
a: done
$ make b
b: MY_VAR is
b: done
$ make b a
b: MY_VAR is
b: done
a: MY_VAR is whatever
a: should be executed
a: done

它看起来可能非常奇怪,但它保证了当且仅当调用目标ab时才计算MY_VAR,并且每个目标最多只能调用一次。看看《疯狂科学家》的帖子,了解详细的解释。加油,太棒了。

在解析Makefile时会评估ifeq和条件语句族。如果在扩展规则时需要Make变量的条件,则需要使用$(if )函数:

.PHONY: a b
a b:
@$(if $(strip $(MY_VAR)),echo "MY_VAR isn't empty",)
@echo done
a: MY_VAR =
b: MY_VAR = something

一个稍左的字段,但在我的情况下很有用,所以我想它值得分享:使用--no-run-if-empty选项将值管道传输到xargs

echo $(POSSIBLY_EMPTY) | xargs --no-run-if-empty echo

请注意,这将在OSX上不起作用。请参阅如果stdin输入为空,如何忽略xargs命令?有关xargs --no-run-if-empty的更多详细信息

相关内容

  • 没有找到相关文章

最新更新