You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GNU Make 3.82下能否动态生成规则及实现Shell补全匹配?

问题与解答

场景说明

现有Makefile内容如下:

items=Excelsior Shibboleth AbraCadabra

ceremony@%:
  foo bar biz baz $*

ritual@%:
  ding ring bing bong $*

ceremonies: $(foreach item,$(items),ceremony@$(item))
rituals: $(foreach item,$(items),ritual@$(item))

all: ceremonies | rituals

由于ceremonies和rituals下的子目标执行耗时,且希望Makefile保持简洁、支持命令自动补全提升易用性,期望实现:

  • 为预定义的items动态生成形如$(item)@ritual的目标(伪代码如下,但GNU Make 3.82下无法运行):
# 伪代码——GNU Make 3.82下不生效
$(foreach item,$(items),$(item)@ritual: ritual@$(item))

要求实现后触发tab补全时能显示这些分项命令,同时避免Makefile过于冗长。

核心问题

上述动态生成目标的需求是否可行?

衍生问题

若使用通配符规则,能否在zsh/bash的tab补全中生成匹配规则的结果?


解答

1. 动态生成目标的可行方案(兼容GNU Make 3.82)

GNU Make 3.82支持通过eval函数实现动态规则生成,这是实现需求的关键。修改后的代码如下:

items=Excelsior Shibboleth AbraCadabra

ceremony@%:
	foo bar biz baz $*

ritual@%:
	ding ring bing bong $*

# 动态生成反向依赖目标
$(foreach item,$(items),\
	$(eval $(item)@ceremony: ceremony@$(item))\
	$(eval $(item)@ritual: ritual@$(item))\
)

ceremonies: $(foreach item,$(items),ceremony@$(item))
rituals: $(foreach item,$(items),ritual@$(item))

all: ceremonies | rituals
  • eval函数会将参数内容作为Makefile代码执行,因此可以在循环中动态创建Excelsior@ritual、Shibboleth@ceremony这类目标,每个目标都依赖对应的ritual@%或ceremony@%规则。
  • 这些动态生成的目标会被Make的自动补全机制识别(只要shell的make补全脚本支持解析动态生成的目标),tab补全时会显示所有$(item)@ceremony和$(item)@ritual形式的命令。

2. 通配符规则与shell补全的兼容性

默认情况下,zsh/bash的make补全脚本不会自动解析通配符规则生成补全候选。因为补全脚本通常只会扫描Makefile中显式定义的目标,而通配符规则是隐式的,无法提前枚举所有可能的匹配项。

如果要让通配符规则支持补全,需要自定义shell补全脚本:

  • 针对bash:可以扩展_make补全函数,提取Makefile中的通配符规则模板,结合预定义的items列表生成补全候选。
  • 针对zsh:可以修改_make补全逻辑,类似bash的思路,从Makefile中读取items变量,再结合通配符规则生成对应的目标候选。
    但这种方式需要额外编写shell补全脚本,复杂度较高,不如直接用eval动态生成显式目标来得直接。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:10:49