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

GNU Make:如何为单次生成多模块的代码生成器配置依赖规则

解决方案

GNU Make本身没有直接的内置函数可以传入目标和依赖,直接返回该目标的recipe是否需要执行的结果。但你现有的实现思路是正确的,可以进一步优化,完全避免生成临时文件、后续sed解析的额外步骤,直接在Make层面完成参数构造和生成器调用。

优化后实现

你可以直接在ALL_GEN_READY的recipe中完成模块提取、输入文件去重、生成器调用的全流程:

# 提前定义的基础变量(示例)
GEN_OUTPUT_PATH := ./gen
CMD_TOUCH := touch

# 你已提前定义好的各模块输入文件
module_A_INPUT_FILES := infile infile_A1 infile_A2
module_B_INPUT_FILES := infile infile_A1 infile_B
module_C_INPUT_FILES := infile_C
module_D_INPUT_FILES := infile_D infile_D1

# 单模块依赖检查规则,和原有逻辑一致
define PROC_MODULE
$(GEN_OUTPUT_PATH)/$1_GEN: $($1_INPUT_FILES)
	$(CMD_TOUCH) $$@
endef

define GEN_MODULES
$(foreach m,$1,$(eval $(call PROC_MODULE,$m)))
# 注册模块对应的输入文件映射,方便后续查询
$(foreach m,$1,$(eval MODULE_INPUT_MAP_$m := $($1_INPUT_FILES)))

$(GEN_OUTPUT_PATH)/ALL_GEN_READY: $(foreach m,$1,$(GEN_OUTPUT_PATH)/$m_GEN)
	@# 提取所有需要重新生成的模块名
	@modules=$$(echo "$$?" | sed 's|$(GEN_OUTPUT_PATH)/\([^ ]*\)_GEN|\1|g'); \
	if [ -n "$$modules" ]; then \
		# 收集所有模块的输入文件并去重
		input_files=$$(for m in $$modules; do echo "$(MODULE_INPUT_MAP_$$m)"; done | tr ' ' '\n' | sort -u | tr '\n' ' '); \
		# 构造-m参数列表
		module_args=$$(for m in $$modules; do echo "-m $$m"; done); \
		# 直接调用生成器
		generator $$module_args $$input_files; \
	fi
	$(CMD_TOUCH) $$@
endef

# 注册需要管理的模块
$(call GEN_MODULES,module_A module_B module_C)
$(call GEN_MODULES,module_D)

优化点说明

  1. 省去了中间文件MODULES_TO_GENERATE的生成和后续解析步骤,所有逻辑在同一个recipe中完成
  2. 直接利用shell的sort -u完成输入文件去重,不需要额外处理
  3. 逻辑和原有实现兼容,不需要改动你已经定义好的MODULE_INPUT_FILES配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:36:05