在 Makefile 函数中设置变量值时遇到问题
Encountered an issue setting the value of a variable inside a Makefile function
目录结构(以 运行 本例为例)如下所示:
example
|-- Makefile
|-- foo
| |-- foo.h (empty file)
|-- bar
| |-- bar.h (empty file)
Makefile 看起来像这样:
TARGETS=foo bar
define GEN_HEADER_RULE
$(1)_INCS = $(wildcard $(1)/*.h)
$(info $$($(1)_INCS) is [$($(1)_INCS)])
$(info $$(wildcard $$(1)/*) is: [$(wildcard $(1)/*)])
endef
$(foreach t,$(TARGETS),$(eval $(call GEN_HEADER_RULE,$t)))
all:
@echo "DONE"
实际输出为:
$(foo_INCS) is []
$(wildcard $(1)/*) is: [foo/foo.h]
$(bar_INCS) is []
$(wildcard $(1)/*) is: [bar/bar.h]
DONE
预期输出为:
$(foo_INCS) is [foo/foo.h]
$(bar_INCS) is [bar/bar.h]
我不明白为什么变量 $(1)_INCS 的值没有被设置为通配符函数的输出?通配符函数显然可以正常工作 - 如 $info 命令直接从中转储输出所示。
我构建了这个简单的 Makefile 来演示我在更大的构建系统中遇到的相同问题。
您忘记保护变量和函数免受双重展开。将除 $(1)
之外的所有 $
加倍,你应该几乎看到你想要的(第二个 $(info...)
除外,它会产生比你预期更多的输出)。
host> cat Makefile
TARGETS=foo bar
define GEN_HEADER_RULE
$(1)_INCS = $$(wildcard $(1)/*.h)
$$(info $$$$($(1)_INCS) is [$$($(1)_INCS)])
$$(info $$$$(wildcard $(1)/*) is: [$$(wildcard $(1)/*)])
endef
$(foreach t,$(TARGETS),$(eval $(call GEN_HEADER_RULE,$t)))
all:
@echo "DONE"
host> make
$(foo_INCS) is [foo/foo.h]
$(wildcard foo/*) is: [foo/foo.h]
$(bar_INCS) is [bar/bar.h]
$(wildcard bar/*) is: [bar/bar.h]
DONE
当使用 foreach-eval-call
时,请记住 eval-call
会进行第一次扩展,当 make 将结果解析为 make 语法时会进行第二次扩展。您经常需要转义第一个扩展 ($$
),有时甚至需要转义第二个扩展 ($$$$
)。有关详细说明,请参阅 the GNU make manual。
目录结构(以 运行 本例为例)如下所示:
example
|-- Makefile
|-- foo
| |-- foo.h (empty file)
|-- bar
| |-- bar.h (empty file)
Makefile 看起来像这样:
TARGETS=foo bar
define GEN_HEADER_RULE
$(1)_INCS = $(wildcard $(1)/*.h)
$(info $$($(1)_INCS) is [$($(1)_INCS)])
$(info $$(wildcard $$(1)/*) is: [$(wildcard $(1)/*)])
endef
$(foreach t,$(TARGETS),$(eval $(call GEN_HEADER_RULE,$t)))
all:
@echo "DONE"
实际输出为:
$(foo_INCS) is []
$(wildcard $(1)/*) is: [foo/foo.h]
$(bar_INCS) is []
$(wildcard $(1)/*) is: [bar/bar.h]
DONE
预期输出为:
$(foo_INCS) is [foo/foo.h]
$(bar_INCS) is [bar/bar.h]
我不明白为什么变量 $(1)_INCS 的值没有被设置为通配符函数的输出?通配符函数显然可以正常工作 - 如 $info 命令直接从中转储输出所示。
我构建了这个简单的 Makefile 来演示我在更大的构建系统中遇到的相同问题。
您忘记保护变量和函数免受双重展开。将除 $(1)
之外的所有 $
加倍,你应该几乎看到你想要的(第二个 $(info...)
除外,它会产生比你预期更多的输出)。
host> cat Makefile
TARGETS=foo bar
define GEN_HEADER_RULE
$(1)_INCS = $$(wildcard $(1)/*.h)
$$(info $$$$($(1)_INCS) is [$$($(1)_INCS)])
$$(info $$$$(wildcard $(1)/*) is: [$$(wildcard $(1)/*)])
endef
$(foreach t,$(TARGETS),$(eval $(call GEN_HEADER_RULE,$t)))
all:
@echo "DONE"
host> make
$(foo_INCS) is [foo/foo.h]
$(wildcard foo/*) is: [foo/foo.h]
$(bar_INCS) is [bar/bar.h]
$(wildcard bar/*) is: [bar/bar.h]
DONE
当使用 foreach-eval-call
时,请记住 eval-call
会进行第一次扩展,当 make 将结果解析为 make 语法时会进行第二次扩展。您经常需要转义第一个扩展 ($$
),有时甚至需要转义第二个扩展 ($$$$
)。有关详细说明,请参阅 the GNU make manual。