在GNU Make中实现C文件条件替换以切换同一接口实现
GNU Make 二选一编译存储实现文件的解决方案
一、解决函数重复定义问题(核心:确保仅编译一个存储实现文件)
不要尝试用filter-out过滤已包含的源文件,直接通过条件变量指定要编译的文件更可靠:
- 编写带条件分支的Makefile:
# 默认使用数组实现 USE_STORAGE ?= array # 根据变量选择对应的源文件 ifeq ($(USE_STORAGE), array) STORAGE_SRC := array_storage.c else ifeq ($(USE_STORAGE), tree) STORAGE_SRC := tree_storage.c else $(error Invalid USE_STORAGE value, must be 'array' or 'tree') endif # 其他业务源文件(示例) OTHER_SRCS := main.c utils.c # 拼接完整源文件列表 SRCS := $(OTHER_SRCS) $(STORAGE_SRC) # 编译链接目标 target: $(SRCS:.c=.o) gcc -o $@ $^
- 编译时指定存储实现:
# 使用数组实现编译 make USE_STORAGE=array # 使用树实现编译 make USE_STORAGE=tree
这种方式从根源上保证只编译一个存储实现文件,彻底解决函数重复定义问题。
二、filter-out通配符失效的原因
GNU Make的filter-out函数仅支持前缀/后缀模式匹配(%只能放在模式的开头或结尾),不支持%storage%这种中间包含的模糊匹配。
如果一定要用过滤逻辑(不推荐,不如条件选择直观),可以先通过filter函数筛选出所有存储相关文件,再针对性过滤:
# 从所有源文件中筛选出存储实现文件 ALL_STORAGE_SRCS := $(filter %storage%.c, $(SRCS)) # 保留array实现,过滤tree实现 SRCS := $(filter-out tree_storage.c, $(ALL_STORAGE_SRCS)) $(filter-out %storage%.c, $(SRCS))
三、Makefile语法高亮的正确标记
在支持Markdown的平台(如Stack Overflow),使用makefile作为代码块的语言标记即可触发语法高亮:
# 这里编写你的Makefile代码
部分平台也支持make作为标记,效果一致。
内容的提问来源于stack exchange,提问作者Ter Maxima
相关产品推荐
相关产品推荐

