单执行流程中能否复用Makefile?现有复用方案存变量延迟求值问题
问题描述
现有两个文件:./Makefile:
CLUSTER=dev include Makefile.cluster.mk CLUSTER=local include Makefile.cluster.mk
./Makefile.cluster.mk:
${CLUSTER}.cmd: cmd ${CLUSTER}
执行make local.cmd会输出cmd local,但执行make dev.cmd同样输出cmd local——这是因为Makefile的规则步骤采用延迟求值,只有在执行规则时才会解析${CLUSTER},而此时CLUSTER已经被最后一次赋值为local,符合GNU Make的规则:
immediate : immediate ; deferred
deferred
需求:找到无需维护多份重复文件的方法,正确生成对应集群的命令。
解决方案
核心思路是让规则中的${CLUSTER}在include阶段就完成求值,而非延迟到执行阶段。以下是两种可行方案:
方案一:用eval函数改造include文件
修改Makefile.cluster.mk,借助eval立即展开当前CLUSTER值生成规则:
define CLUSTER_RULE $(1).cmd: cmd $(1) endef $(eval $(call CLUSTER_RULE,$(CLUSTER)))
每次include时,eval会立即用当前的CLUSTER值生成对应规则,步骤里的命令会被直接绑定到当前集群名称,执行make dev.cmd会输出cmd dev,make local.cmd输出cmd local。
方案二:主Makefile直接批量生成规则
无需额外include文件,直接在主Makefile中枚举集群,通过foreach+eval批量生成规则:
CLUSTERS := dev local define CLUSTER_RULE $(1).cmd: cmd $(1) endef $(foreach cluster,$(CLUSTERS),$(eval $(call CLUSTER_RULE,$(cluster))))
这种方式更简洁,直接管理所有集群列表,避免多次重复include操作。
内容的提问来源于stack exchange,提问作者user48956
相关产品推荐
相关产品推荐

