GNU Make中如何让构建目标依赖可选存在的.options文件
问题原因
你之前的写法将.options作为强制前置依赖,make执行时默认所有依赖项必须存在,或有明确规则可以生成。对于没有配套.options文件的proto文件,make找不到对应依赖、也找不到生成该.options文件的规则,就会抛出构建中断错误。你之前尝试的二次展开写法本质还是把.options作为强制依赖,哪怕patsubst能正确匹配到文件名,只要对应文件不存在,make还是会报错,无法适配可选依赖的场景。
解决方案
以下两种方案都可以实现「存在.options文件就监听变更触发重建,不存在则正常构建」的需求,按需选择即可:
方法1:添加空规则适配可选依赖(改动最小)
只需要新增一条匹配.options文件的空规则,告诉make如果找不到对应.options文件,不需要额外生成,直接认为该依赖已满足即可,同时修改两个存根生成规则的依赖项。
核心修改片段如下:
# 新增:空规则,处理不存在的.options文件 %.options: ; # 修改C++生成规则,加入.options依赖 $(CPP_PATH)%.pb.cpp: %.proto %.options $(PYTHON) $(NANOPB_GEN) -H .h -S .cpp -D $(CPP_PATH) --strip-path $< # 修改C#生成规则,加入.options依赖 $(CS_PATH)%.cs: %.proto %.options $(PROTOC) -I./ -I=$(NANOPB_GEN) -I=$(NANOPB_PROTO) --csharp_out=$(CS_PATH) $<
该方案逻辑:
- 如果对应
.options文件存在,它的修改时间晚于目标存根文件时就会触发重建 - 如果
.options文件不存在,空规则会直接返回构建成功,make不会因为找不到依赖报错,正常走构建流程。
方法2:动态追加已存在的.options依赖(逻辑更严谨)
如果你不想让不存在的文件出现在依赖列表中,可以在Makefile初始化阶段扫描所有实际存在的.options文件,动态给对应生成目标追加依赖,原有生成规则不需要改动。完整修改后的Makefile如下:
PROTOC := protoc.exe PYTHON := python NANOPB_GEN := ../lib/generator/ NANOPB_PROTO := $(NANOPB_GEN)proto NANOPB_SCRIPT := $(NANOPB_GEN)nanopb_generator.py CPP_PATH := ../../Firmware/protobuf/ CS_PATH := ../../Console/Networking/DataExchange/ SRCS := $(wildcard *.proto) CPP_TARGETS := $(patsubst %.proto, $(CPP_PATH)%.pb.cpp, $(SRCS)) CS_TARGETS := $(patsubst %.proto, $(CS_PATH)%.cs, $(SRCS)) # 扫描当前目录下所有真实存在的.options文件 EXISTING_OPTIONS := $(wildcard *.options) # 给对应C++、C#存根目标追加.options依赖 $(foreach opt,$(EXISTING_OPTIONS),\ $(eval $(CPP_PATH)$(patsubst %.options,%.pb.cpp,$(opt)): $(opt))\ $(eval $(CS_PATH)$(patsubst %.options,%.cs,$(opt)): $(opt))\ ) $(CPP_PATH)%.pb.cpp: %.proto $(PYTHON) $(NANOPB_GEN) -H .h -S .cpp -D $(CPP_PATH) --strip-path $< $(CS_PATH)%.cs: %.proto $(PROTOC) -I./ -I=$(NANOPB_GEN) -I=$(NANOPB_PROTO) --csharp_out=$(CS_PATH) $< all: cpp cs @echo "making all" cpp: $(CPP_TARGETS) @echo "generating C++ stubs" cs: $(CS_TARGETS) @echo "generating C# stubs"
该方案会在Makefile加载阶段就把实际存在的.options文件绑定到对应生成目标上,不存在的.options不会被加入依赖列表,完全不会触发找不到依赖的错误。
内容的提问来源于stack exchange,提问作者gtSasha
相关产品推荐
相关产品推荐

