如何为多个依赖不同的输出文件创建Makefile?
可选的更优方案
方案1:为特殊目标单独编写规则
如果需要额外依赖的目标数量不多,直接单独写规则是最直观的方式,不用依赖二次扩展,可读性拉满:
BINS = 1 2 3 4 5 ASFLAGS = --gstabs all: $(BINS) # 通用规则:覆盖大部分不需要额外依赖的目标 $(filter-out 2 3,$(BINS)): %: %.o utils.o ld -o $@ $^ # 单独处理目标2 2: 2.o 2_lib.o utils.o ld -o $@ $^ # 单独处理目标3 3: 3.o 3_lib.o another_lib.o utils.o ld -o $@ $^ .PHONY: all clean clean: rm -f $(BINS) *.o
这个方案逻辑直白,新人接手也能快速看懂,维护成本极低,适合特殊目标少的场景。
方案2:用变量映射表管理特殊依赖
如果特殊目标数量较多,可以用映射表的方式统一管理,扩展性更好,同样不用二次扩展:
BINS = 1 2 3 4 5 ASFLAGS = --gstabs # 定义每个特殊目标的额外依赖 EXTRA_DEPS_2 = 2_lib.o EXTRA_DEPS_3 = 3_lib.o another_lib.o all: $(BINS) # 通用规则,自动匹配对应目标的额外依赖 $(BINS): %: %.o utils.o $(EXTRA_DEPS_%) ld -o $@ $^ .PHONY: all clean clean: rm -f $(BINS) *.o
这里利用Makefile的变量名拼接特性,$(EXTRA_DEPS_%)会根据当前目标自动匹配对应的变量值。后续新增特殊目标时,只需要加一行EXTRA_DEPS_xxx = xxx.o就行,不用改规则部分。
方案3:利用模式规则匹配命名规律
如果额外库的命名和目标有固定规律(比如目标x对应x_lib.o),可以用模式规则进一步简化:
BINS = 1 2 3 4 5 ASFLAGS = --gstabs # 目标3的额外特殊依赖 3: EXTRA_SPECIAL = another_lib.o all: $(BINS) # 通用规则,包含规律化的额外库和特殊依赖 $(BINS): %: %.o %_lib.o utils.o $(EXTRA_SPECIAL) ld -o $@ $^ # 为不需要%_lib.o的目标添加空规则,避免报错 1 4 5: %_lib.o: @true .PHONY: all clean clean: rm -f $(BINS) *.o
这个方案适合依赖有统一命名规律的场景,能最大限度减少重复配置,但需要给不需要规律化依赖的目标加空规则来跳过构建检查。
方案对比
| 方案类型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 二次扩展方案 | 特殊目标多且依赖无明显规律 | 规则统一 | 需理解二次扩展机制,可读性弱 |
| 单独规则方案 | 特殊目标数量少 | 直观易懂,维护成本低 | 特殊目标多时代码冗余 |
| 变量映射表方案 | 特殊目标数量较多 | 扩展性好,规则统一 | 需维护映射表 |
| 模式规则方案 | 依赖有固定命名规律 | 配置极简 | 需处理无规律依赖的例外情况 |
内容的提问来源于stack exchange,提问作者fff
相关产品推荐
相关产品推荐

