如何在Make中处理特殊案例?解决Makefile多目标生成报错
解决Makefile模式规则报错并实现定制化文件生成
你的报错原因很明确:你把带通配符%的模式规则和不带通配符的特殊目标规则绑定到了同一个$(FILES):前缀下,Make无法解析这种混合写法——它期望模式规则必须包含%来匹配源文件和目标文件的对应关系,而特殊目标规则没有%,就触发了target pattern contains no '%'的错误。
下面是两种简洁且符合Make语法的实现方案,满足你的需求:
方案一:拆分普通目标与特殊目标
这种写法逻辑清晰,把通用文件和定制文件的规则完全分开:
# 1. 定义所有源文件:排除dec.pla,剩下的是普通*.pla文件 PLA_FILES := $(filter-out $(SRC_DIR)/dec.pla, $(wildcard $(SRC_DIR)/*.pla)) # 2. 生成普通目标列表:每个*.pla对应TMP_DIR下的*.a NORMAL_TARGETS := $(patsubst $(SRC_DIR)/%.pla, $(TMP_DIR)/%.a, $(PLA_FILES)) # 3. 定义dec.pla对应的特殊目标 DEC_TARGETS := $(TMP_DIR)/dec0.a $(TMP_DIR)/dec1.a # 4. 合并所有最终目标 FILES := $(NORMAL_TARGETS) $(DEC_TARGETS) # 5. 通用模式规则:处理普通*.pla到*.a的转换 $(NORMAL_TARGETS): $(TMP_DIR)/%.a : $(SRC_DIR)/%.pla $(BASE_CMD) < $< > $@ # 6. 特殊规则:处理dec.pla生成dec0.a $(TMP_DIR)/dec0.a: $(SRC_DIR)/dec.pla $(BASE_CMD) -D c=0 < $< > $@ # 7. 特殊规则:处理dec.pla生成dec1.a $(TMP_DIR)/dec1.a: $(SRC_DIR)/dec.pla $(BASE_CMD) -D c=1 < $< > $@
方案二:替换默认目标
如果不想拆分列表,可以先生成默认的目标集合,再把dec.a替换成需要的两个文件:
# 1. 先生成所有默认目标(包含dec.a) FILES := $(patsubst $(SRC_DIR)/%.pla, $(TMP_DIR)/%.a, $(wildcard $(SRC_DIR)/*.pla)) # 2. 替换dec.a为dec0.a和dec1.a FILES := $(filter-out $(TMP_DIR)/dec.a, $(FILES)) $(TMP_DIR)/dec0.a $(TMP_DIR)/dec1.a # 3. 通用模式规则:处理除dec目标外的所有文件 $(filter-out $(TMP_DIR)/dec0.a $(TMP_DIR)/dec1.a, $(FILES)): $(TMP_DIR)/%.a : $(SRC_DIR)/%.pla $(BASE_CMD) < $< > $@ # 4. 特殊规则:处理dec.pla的两个定制目标 $(TMP_DIR)/dec0.a: $(SRC_DIR)/dec.pla $(BASE_CMD) -D c=0 < $< > $@ $(TMP_DIR)/dec1.a: $(SRC_DIR)/dec.pla $(BASE_CMD) -D c=1 < $< > $@
核心要点总结
- 模式规则(带
%)只能用于有一一对应关系的源文件和目标文件,不能和无通配符的特殊规则混合绑定到同一个目标前缀 - 必须确保
$(FILES)最终包含所有需要生成的文件(普通*.a + dec0.a + dec1.a) - 特殊目标的规则要单独定义,明确依赖对应的源文件
dec.pla
内容的提问来源于stack exchange,提问作者Jean
相关产品推荐
相关产品推荐

