所以,我有一个make模板。我这样调用它:
$(eval $(call PRIVATE_LIBRARY_TEMPLATE,privatelib1,64))
它的定义如下:
define PRIVATE_LIBRARY_TEMPLATE
# Evaluate the condition multiple times because of way make processes templates
$(if $(2)=='',$(eval $(call LIBRARYBUILD_TEMPLATE,$(1),32)))
$(if $(2)=='',$(eval $(call LIBRARYBUILD_TEMPLATE,$(1),64)))
$(if $(2)!='',$(eval $(call LIBRARYBUILD_TEMPLATE,$(1),$(2))))
# More stuff that doesn't matter here
endef
或者喜欢:
define PRIVATE_LIBRARY_TEMPLATE
# Evaluate the condition multiple times because of way make processes templates
$(if $(2)=='',$(call LIBRARYBUILD_TEMPLATE,$(1),32))
$(if $(2)=='',$(call LIBRARYBUILD_TEMPLATE,$(1),64))
$(if $(2)!='',$(call LIBRARYBUILD_TEMPLATE,$(1),$(2)))
# More stuff that doesn't matter here
endef
以前将其定义为:
define PRIVATE_LIBRARY_TEMPLATE
$$(eval $$(call LIBRARYBUILD_TEMPLATE,$(1),32))
$$(eval $$(call LIBRARYBUILD_TEMPLATE,$(1),64))
在我添加$(if
之前,$(1)
完整地传递给LIBRARYBUILD_TEMPLATE,但是一旦我添加$(if
,$(1)
就变成空字符串。
我尝试了$$
$(eval
$$eval
等的各种组合,但有些基本原理我只是不了解gmake解析此模板定义的方式。
我要做的是在此模板中使$(2)
成为可选项,并在提供时使用它,或者如果没有提供,则构建32位和64位库。
如何最初解析模板定义,然后进行评估。
答案 0 :(得分:0)
首先,函数$(if condition,then-part,else-part)
与ifeq
等其他条件不同。只检查$(if)
函数条件是否为空字符串(c.f. manual):
如果它扩展为任何非空字符串,则认为该条件为真。如果它扩展为空字符串,则该条件被视为false。
当谈到$(eval $(call ...)
时,事情可能变得棘手,必须评估事物的顺序。我通常这样想:
如果操作的评估结果取决于参数(如
$1
),则操作需要延迟secondary expansion。
所以在你的情况下,我认为这就是你想要的:
.SECONDEXPANSION:
define LIBRARYBUILD_TEMPLATE
$$(info >> LIBRARYBUILD_TEMPLATE: $1 $2)
endef
define PRIVATE_LIBRARY_TEMPLATE
$$(info > PRIVATE_LIBRARY_TEMPLATE $1 $2)
ifeq ($2,)
$$(eval $$(call LIBRARYBUILD_TEMPLATE,$1,32))
$$(eval $$(call LIBRARYBUILD_TEMPLATE,$1,64))
else
$$(eval $$(call LIBRARYBUILD_TEMPLATE,$1,$2))
endif
endef
$(eval $(call PRIVATE_LIBRARY_TEMPLATE,privatelib1,64))
$(eval $(call PRIVATE_LIBRARY_TEMPLATE,privatelib2,))
给出了输出:
> PRIVATE_LIBRARY_TEMPLATE privatelib1 64
>> LIBRARYBUILD_TEMPLATE: privatelib1 64
> PRIVATE_LIBRARY_TEMPLATE privatelib2
>> LIBRARYBUILD_TEMPLATE: privatelib2 32
>> LIBRARYBUILD_TEMPLATE: privatelib2 64
答案 1 :(得分:0)
让我们使用PRIVATE_LIBRARY_TEMPLATE
define PRIVATE_LIBRARY_TEMPLATE
# Evaluate the condition multiple times because of way make processes templates
$(if $(2)=='',$(eval $(call LIBRARYBUILD_TEMPLATE,$(1),32)))
$(if $(2)=='',$(eval $(call LIBRARYBUILD_TEMPLATE,$(1),64)))
$(if $(2)!='',$(eval $(call LIBRARYBUILD_TEMPLATE,$(1),$(2))))
endef
详细了解 make 在遇到
时所做的事情是有益的$(eval $(call PRIVATE_LIBRARY_TEMPLATE,privatelib1,64))
显然,在展开$eval
之前, make 必须首先展开$call
:
1
设置为privatelib1
2
设置为64
PRIVATE_LIBRARY_TEMPLATE
现已扩展。
首先,$(if …)
需要扩展:
制作查看$(if $(2)=='',$(call LIBRARYBUILD_TEMPLATE,$(1),32))
中的条件,然后展开$(2)==''
。您会注意到64==''
不是空字符串,因此被视为 true 。要完成$(if …)
的扩展, make 会选择真正的分支,然后继续展开$(call LIBRARYBUILD_TEMPLATE,$(1),32)
1
变为privatelib1
2
变为32
$(call LIBRARYBUILD_TEMPLATE,privatelib1,32)
成为一些文字。不知道是什么,但由于它最终将传递给$eval
,因此它必须是有效的 make 语法。我们假设它像LIB_privatelib1_32 := 1
一样简单。同样扩展了第二个$(if …)
。
同样扩展了第三个$(if …)
。
为了论证,让我们说$(call PRIVATE_LIBRARY_TEMPLATE,…)
的最终扩展是这样的文字:
LIB_privatelib1_32 := 1
LIB_privatelib1_64 := 1
LIB_privatelib1_64 := 1
这三行传递给$eval
。
$(eval …)
的扩展虽然为空。呼。
这里一个明显的错误是==
无效 make 语法。
Truthyness仅仅是一个字符串是否包含字符。
你可能想要这样的东西:
$(if $2,$(eval $(call LIBRARYBUILD_TEMPLATE,$1,32)))
$(if $2,$(eval $(call LIBRARYBUILD_TEMPLATE,$1,64)))
$(if $2,,$(eval $(call LIBRARYBUILD_TEMPLATE,$1,$2)))
(查看最后一项否定。)