Reputation: 125
I have a simple Makefile that generates protobuf stubs from .proto files.
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))
$(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"
It works fine, but I also want the makefile to rebuild the stubs if a corresponding .options file changes in addition to the .proto file. For instance, Tag.proto may have an optional Tag.options file that nanopb generator expects. I want to modify the Makefile to rebuild the stubs if .options file changes, but also works if there is no .options file.
I tried this rule:
$(CPP_PATH)%.pb.cpp: %.proto $$(patsubst %.proto, %.options, $$<)
However, this does not handle .proto files that don't have the corresponding *.options
file.
Err:
make: *** No rule to make target
../../Firmware/protobuf/Tag.pb.cpp', needed by
cpp'. Stop.
How can I define a rule that can use .options ?
Thank you!
Upvotes: 0
Views: 152
Reputation: 4271
I think the easiest way would be to use wildcard
function, that will only take a file into account if it exists. The only tricky thing is that you cannot use %
within secondary expanded part, but you can use $$*
instead, which will expand to the tested stem, i.e.:
$ cat Makefile
.SECONDEXPANSION:
%.pb.cpp: %.proto $$(wildcard $$*.options)
echo $^ > $@
This will handle both options when the .options file exists or not, e.g.:
$ touch foo.proto bar.proto bar.options
$ make foo.pb.cpp
echo foo.proto > foo.pb.cpp
$ make bar.pb.cpp
echo bar.proto bar.options > bar.pb.cpp
This will also rebuild if .options file gets changed:
$ make bar.pb.cpp
make: 'bar.pb.cpp' is up to date.
$ touch bar.options
$ make bar.pb.cpp
echo bar.proto bar.options > bar.pb.cpp
Upvotes: 1