Makefile中百分号匹配规则对构建目录下sim_*目标不生效如何解决
问题原因
你遇到的报错核心来自GNU Make对**万能匹配规则(match-anything rule,即目标仅为%的模式规则)**的默认限制:
- 你定义的
%: %.sv属于万能匹配规则,Make为了避免无意义的匹配开销,默认不会将这类规则用于生成另一个模式规则的依赖项 - 你修改后的
$(BUILD_DIR)/sim_%模式规则的依赖包含无后缀的%(比如生成sim_alu时依赖alu),Make查找alu的生成规则时会自动跳过你写的万能sv匹配规则,最终报找不到规则的错误 - 你之前写固定目标
sim_alu时能正常运行,是因为固定目标的依赖查找不会跳过万能匹配规则
解决方案
方案1:避免使用万能匹配规则(更推荐,可维护性更高)
将sv文件的生成目标放到统一目录,不再用万能匹配,Make会正常识别该模式规则用于依赖查找:
# 把sv生成的目标放到bin目录下,替换原来的%: %.sv规则 bin/%: %.sv $(VCC) $(VFLAGS) $^ # 同步修改sim的模式规则,依赖bin目录下的对应目标 $(BUILD_DIR)/sim_%: sim_%.cc bin/% | $(BUILD_DIR) $(CC) $(STD) $(CFLAGS) -o $@ $< -Wall -Wno-sign-compare
之后执行make build/sim_alu就会自动匹配到规则,先生成bin/alu再编译仿真文件。
方案2:保留万能匹配规则,显式声明规则可用
如果你一定要保留无后缀的sv生成目标,可以添加.SECONDEXPANSION显式指定sim规则的依赖查找逻辑,强制Make调用万能匹配规则生成依赖:
.SECONDEXPANSION: $(BUILD_DIR)/sim_%: sim_%.cc $$* | $(BUILD_DIR) $(CC) $(STD) $(CFLAGS) -o $@ $< -Wall -Wno-sign-compare
注意这里的依赖项要写$$*,二次展开后才会被替换为匹配的通配符内容。
额外检查项
- 确认你在Makefile开头明确定义了
BUILD_DIR := build,如果变量未定义或者定义为空,模式规则会匹配失败 - 确认所有
sim_xxx.cc文件都存在,且对应名字的xxx.sv文件存在于当前目录
内容的提问来源于stack exchange,提问作者Plasty Grove
相关产品推荐
相关产品推荐

