【问题标题】:Makefile function with multiple statements具有多个语句的 Makefile 函数
【发布时间】:2019-08-19 19:26:38
【问题描述】:

[HEADS UP]:stackoverflow 上已经存在一些类似的问题,但它们似乎不能完全解决我的问题。因此,我发布了这个问题。

我正在尝试编写一个 makefile 函数,该函数应该为作为参数传递给函数的变量设置一个值。
所以,我称这个函数为 -

RESULT :=
$(eval $(call myfunction,RESULT,value,res1,res2))

这里 'res1' 和 'res2' 是 RESULT 的两个可能结果值,参数 'value' 将用于某些测试条件。

以下是我对myfunction定义的尝试。但是好像不行。

define myfunction
TEST1 := $(shell test `mybinary` -ge 5 && printf "TEST")
TEST2 := $(findstring $(2),$(SOME_SHELL_ENV))
$(info "$(TEST1)")
$(info "$(TEST2)")

ifneq "$$(or $(TEST1),$(TEST2)" ""
    LOCAL_RESULT := true
else
    LOCAL_RESULT := false
endif

ifeq($(LOCAL_RESULT),true)
    $(1) = $(3)
else
    $(1) = $(4)
endif
endef

在我看来,局部变量 TEST1 和 TEST2 似乎都没有设置。

谁能告诉我为什么我的功能不能正常工作以及我必须做出哪些改变来解决这些问题?

【问题讨论】:

  • GNU make 可以使用 Guile 或插件进行扩展。考虑使用它们。并使用remake 调试您的Makefile

标签: makefile gnu-make


【解决方案1】:

引用eval manual page:

eval 函数非常特殊:[...] eval 函数的参数被扩展,然后扩展的结果被解析为 makefile 语法。

重要的是要意识到eval 参数被扩展了两次;首先是 eval 函数,然后在将其解析为 makefile 语法时再次展开该扩展的结果。这意味着您在使用eval 时可能需要为“$”字符提供额外的转义级别。

这发生在$(call) 参数被替换后,所以$1 等在$(eval) 被调用时已经被扩展,不需要$-转义。

要使变量在$(eval) 的最后(解析)阶段扩展,请将非数字变量的$s 加倍。

define myfunction
TEST1 := $$(shell test `echo 6` -ge 5 && printf "TEST")
TEST2 := $$(findstring $(2),$$(PATH))
$$(info "$$(TEST1)")
$$(info "$$(TEST2)")

ifneq "$$(or $$(TEST1),$$(TEST2))" ""
    LOCAL_RESULT := true
else
    LOCAL_RESULT := false
endif

ifeq ($$(LOCAL_RESULT), true)
    $(1) = $(3)
else
    $(1) = $(4)
endif
endef

$(eval $(call myfunction,RESULT,value,res1,res2))
test:
    echo "$(LOCAL_RESULT)"

另外,$(or) 中缺少右大括号。

不清楚res1res2是变量名还是值;根据这一点,最后两个分配需要或不需要看起来像$(1) := $($(4))

尽量始终使用急切的赋值::=,以减少惰性变量扩展带来的意外。

【讨论】:

  • 感谢您的回复。这似乎有效。我仍然很困惑为什么到处都需要 $$ 以及为什么 $(2),$(3) 不需要它。
  • 另外, res1 和 res2 是值(我已经提到过这个问题)。你能解释一下 $($(4)) 吗?和 $$(4) 有区别吗?
  • 更新了回答第一条评论的答案。对于第二条评论,$($(4)) 非常直观:它是“call 的参数 4 命名的变量的值”。 eval 转义规则仍然适用。
  • 另一个后续问题:MadScientist 对问题stackoverflow.com/questions/22544784/… 的回答指出“Make 将在单独的 shell 中调用配方的每个逻辑行”,然后我如何做这个解决方案能够保持值整个函数中的 TEST1、TEST2、LOCAL_RESULT?
  • 它们是 make 变量,而不是 shell 变量。
猜你喜欢
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 2021-10-29
相关资源
最近更新 更多