Android.mk:为什么 $(info) 和 $(警告) 不反映从函数中分配的变量的值



Android.mk文件中使用的简单测试代码:

my_var := 'Foo'
$(warning $(my_var))

产生预期输出:

jni/Android.mk:6: 'Foo'

但是,在定义函数并调用此函数时,局部变量似乎被忽略(就好像首先处理warning行一样)。例如:

define my_func
    my_var := 'Test $1'
    $(warning "MYFUNC: <$1> [$(my_var)]")
endef
$(call my_func,'foo')
$(call my_func,'bar')

输出:

jni/Android.mk:10: "MYFUNC: <'foo'> []"
jni/Android.mk:11: "MYFUNC: <'bar'> []"

如果在函数范围之外定义此my_var

my_var := 'norf'
define my_func
    my_var := 'Test $1'
    $(warning "MYFUNC: <$1> [$(my_var)]")
endef
$(call my_func,'foo')
$(call my_func,'bar')

输出:

jni/Android.mk:10: "MYFUNC: <'foo'> ['norf']"
jni/Android.mk:11: "MYFUNC: <'bar'> ['norf']"

当在foreach循环中使用时,它的行为就像它是my_func函数中的第一行一样(实际上,将其作为第一行会给出相同的输出):

define my_func
    my_var := 'Test $1'
    $(warning "MYFUNC: <$1> [$(my_var)]")
endef
items := foo bar qux norf
$(foreach item,$(items),$(eval $(call my_func,$(item))))

输出:

jni/Android.mk:10: "MYFUNC: <foo> []"
jni/Android.mk:10: "MYFUNC: <bar> ['Test foo']"
jni/Android.mk:10: "MYFUNC: <qux> ['Test bar']"
jni/Android.mk:10: "MYFUNC: <norf> ['Test qux']"

如果只在函数调用检查值,则输出预期值。只有从函数内部,我才发现warninginfo行为出乎意料。


有人可以解释一下吗?

使用 $(info OUT) 而不是 $(warning OUT) 表现出类似的行为。我在 NDK 文档中没有找到这两个函数。

定义规则的计算顺序很难正确,在这种情况下,问题是过早评估警告,并且变量赋值可能根本不会被评估。

通过像这样修改您的示例,我让它工作:

define my_func
    my_var := 'Test $1'
    $$(warning "MYFUNC: <$1> [$$(my_var)]")
endef
$(eval $(call my_func,'foo'))
$(eval $(call my_func,'bar'))

通过使用 $$ 来使用变量和警告,它们的评估将推迟到我添加的包装 $(eval) 调用,然后在分配变量后发生。

有关该主题的更多提示和解释,请参阅 https://unix.stackexchange.com/questions/154557。