Gnu make gmake如何解析和执行模板定义
所以,我有一个制作模板。我这样说:Gnu make gmake如何解析和执行模板定义,gnu-make,Gnu 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)
$(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))
在我添加$(如果
)之前,$(1)
会完整地传递给LIBRARYBUILD\u模板,但一旦我添加$(如果
,$(1)
就会变成一个空字符串
我已经尝试了各种组合的$
$(eval
$$eval
等,但有一点我只是不了解gmake解析这个模板定义的方式
我试图做的是在这个模板中使$(2)
成为可选的,如果提供了,则使用它;如果没有提供,则使用它构建32位和64位库
模板定义最初是如何解析的,然后是如何计算的。首先,函数
$(if条件,然后part,else部分)
与其他条件(如ifeq
)不同。$(if)
函数条件只需检查是否为空字符串():
如果它扩展到任何非空字符串,则该条件被视为true。如果它扩展到空字符串,则该条件被视为false
当涉及到$(eval$(call…
)时,事情可能会变得棘手,必须按照什么顺序对事情进行评估。我通常这样想:
如果运算的计算结果取决于参数(如$1
),则运算需要延迟
所以在你的情况下,我认为这就是你想要的:
.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
让我们使用
PRIVATE\u LIBRARY\u模板的定义
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))
显然,make必须先展开$call
,然后才能展开$eval
:
1
设置为privatelib1
2
设置为64
PRIVATE\u LIBRARY\u模板现在已展开
- 首先,
$(如果…
需要扩展:
- Make查看
$(如果$(2)='',$(调用LIBRARYBUILD_模板,$(1),32))
,然后展开$(2)=''
。您会注意到64=''
不是空字符串,因此被认为是真的。要完成$的展开(如果…)
,make因此选择真正的分支并继续展开$(调用LIBRARYBUILD\u模板,$(1),32)
1
变为privatelib1
2
变为32
$(调用LIBRARYBUILD\u TEMPLATE,privatelib1,32)
会变成一些文本。不知道是什么,但由于它最终会被传递给$eval
,所以它必须是有效的make语法。让我们假设它是类似LIB\u privatelib1\u 32:=1
这样简单的东西
- 第二个
$(如果…
)类似地展开
- 第三个
$(if…
类似地展开
- 为了便于讨论,让我们假设
$(调用PRIVATE\u LIBRARY\u TEMPLATE,…)
的最终扩展是以下文本:
LIB_privatelib1_32:=1
LIB_privatelib1_64:=1
LIB_privatelib1_64:=1
这三行被传递到$eval
- 作为副作用,定义了三个新的简单变量
$(eval…
的扩展名为空
呸
这里一个明显的错误是,==
的make语法无效。
真实性仅仅是字符串中是否包含字符。
您可能需要以下内容:
$(if $2,$(eval $(call LIBRARYBUILD_TEMPLATE,$1,32)))
$(if $2,$(eval $(call LIBRARYBUILD_TEMPLATE,$1,64)))
$(if $2,,$(eval $(call LIBRARYBUILD_TEMPLATE,$1,$2)))
(查看最后一个否定。)