为什么转义变量$$工作而不是$

时间:2017-03-21 17:50:55

标签: makefile

这是我在线程中提到的上一个问题的后续问题:

search subdirectories and update path variables in makefile

以下内容:

有一个规则makefile,它添加了各种标准定义, Include.mak。它有一个定义:

RESOLVED_PATH=$(subst $(abspath .)/,,$(abspath $(1)))

它正在另一个makefile中使用:

include Include.mak

ROOT:=.
define UPDATE_GUI
d:= $$(strip $(1))
GUI_FOLDER:= $(ROOT)/$(d)
GUI_ALL:=$(call RESOLVED_PATH,$(GUI_FOLDER)/$(d)_generated.txt)
$$(warning GUI_ALL is set to $$(GUI_ALL))
endef

TARGET_FILE:= ProjectParms.rb

ACTIVE_GUIS = $(wildcard GUI*/$(TARGET_FILE))
GUIS_OF_INTEREST = $(dir $(ACTIVE_GUIS))
GUIS= $(patsubst %/,%,$(GUIS_OF_INTEREST))
$(foreach GUI, $(GUIS), $(eval  $(call UPDATE_GUI, $(GUI))))

这不会根据需要提供输出,但如果我在行中展开相同的内容:

GUI_ALL:=$$(subst $$(abspath .)/,,$$(abspath $$(GUI_FOLDER)/$$(d)_generated.txt)

$$(warning GUI_ALL is set to $$(GUI_ALL))

它运作正常,有人可以告诉我为什么吗? $(调用RESOLVED_PATH,Param)正在整个make项目的不同地方使用(虽然在其他地方没有使用$(warning''),我只是用它来进行快速的健全性检查。

1 个答案:

答案 0 :(得分:0)

除了实际的call参数之外,您必须在函数中转义所有。有时你不想要这个,但几乎所有的时间都是这样。所以它应该是:

define UPDATE_GUI
d := $$(strip $(1))
GUI_FOLDER := $$(ROOT)/$$(d)
GUI_ALL := $$(call RESOLVED_PATH,$$(GUI_FOLDER)/$$(d)_generated.txt)
$$(warning GUI_ALL is set to $$(GUI_ALL))
endef

对于调试,您可以使用eval函数替换info函数;这将打印出eval可以使用的makefile语法。如果你这样做,你会看到eval获取文本时解析它已经错了,因为call扩展了它。如,

$(foreach GUI,$(GUIS),$(info $(call UPDATE_GUI,$(GUI))))

ETA

我将指出,您可以通过完全删除call功能来大大简化此操作。为了做到这一点,您必须确保UPDATE_GUI定义与foreach紧密绑定。既然您只是将一个参数传递给call,那么您可以不这样做并将GUI变量(foreach中的循环变量)直接放入UPDATE_GUI限定;那你就不需要打电话了。像这样:

define UPDATE_GUI
d := $(strip $(GUI))
GUI_FOLDER := $(ROOT)/$(d)
GUI_ALL := $(call RESOLVED_PATH,$(GUI_FOLDER)/$(d)_generated.txt)
$(warning GUI_ALL is set to $(GUI_ALL))
endef

$(foreach GUI,$(GUIS),$(eval $(UPDATE_GUI)))