xref: /aosp_15_r20/system/chre/build/nanopb.mk (revision 84e339476a462649f82315436d70fd732297a399)
1#
2# Nanoapp/CHRE NanoPB and Pigweed RPC Makefile
3#
4# Include this file in your nanoapp Makefile to generate .c source and .h header
5# files. ($NANOPB_EXTENSION.c and $NANOPB_EXTENSION.h if $NANOPB_EXTENSION
6# is defined) for .proto files specified in the NANOPB_SRCS and PW_RPC_SRCS
7# variables.
8#
9# The generated source files are automatically added to the COMMON_SRCS variable
10# for the nanoapp build.
11#
12# The path to the generated header files is similarly added to the COMMON_CFLAGS.
13#
14# The NANOPB_OPTIONS variable can be used to supply an .options file to use when
15# generating code for all .proto files. Alternatively, if an .options file has
16# the same name as a .proto file, it'll be automatically picked up when generating
17# code **only** for that .proto file.
18#
19# NANOPB_FLAGS can be used to supply additional command line arguments to the
20# nanopb compiler. Note that this is global and applies to all protobuf
21# generated source.
22#
23# NANOPB_INCLUDES may optionally be used to automatically add one or more
24# include path prefixes for C/C++ source and .proto files. For example, if the
25# file myprefix/proto/foo.proto is added to NANOPB_SRCS, but you'd like to use
26# #include "proto/foo.pb.h" in your source (rather than myprefix/proto/foo.pb.h)
27# and/or import "proto/foo.proto" in your .proto files, then set NANOPB_INCLUDES
28# to myprefix.
29
30# Environment Checks ###########################################################
31
32HAS_PROTO_SRC = false
33
34ifneq ($(NANOPB_SRCS),)
35ifeq ($(NANOPB_PREFIX),)
36$(error "NANOPB_SRCS is non-empty. You must supply a NANOPB_PREFIX environment \
37         variable containing a path to the nanopb project. Example: \
38         export NANOPB_PREFIX=$$HOME/path/to/nanopb/nanopb-c")
39endif
40HAS_PROTO_SRC = true
41endif
42
43ifneq ($(PW_RPC_SRCS),)
44ifeq ($(NANOPB_PREFIX),)
45$(error "PW_RPC_SRCS is non-empty. You must supply a NANOPB_PREFIX environment \
46         variable containing a path to the nanopb project. Example: \
47         export NANOPB_PREFIX=$$HOME/path/to/nanopb/nanopb-c")
48endif
49HAS_PROTO_SRC = true
50endif
51
52################################################################################
53# Common #######################################################################
54################################################################################
55
56ifeq ($(PROTOC),)
57PROTOC=protoc
58endif
59
60NANOPB_GEN_PATH = $(OUT)/nanopb_gen
61
62ifeq ($(NANOPB_EXTENSION),)
63NANOPB_EXTENSION = pb
64else
65NANOPB_GENERATOR_FLAGS = --extension=.$(NANOPB_EXTENSION)
66endif
67
68NANOPB_GEN_SRCS += $(patsubst %.proto, \
69                              $(NANOPB_GEN_PATH)/%.$(NANOPB_EXTENSION).c, \
70                              $(NANOPB_SRCS))
71
72# Add Google proto well-known types. See https://protobuf.dev/reference/protobuf/google.protobuf/.
73PROTOBUF_DIR = $(ANDROID_BUILD_TOP)/external/protobuf
74COMMON_CFLAGS += -I$(NANOPB_GEN_PATH)/$(PROTOBUF_DIR)/src
75
76################################################################################
77# Common to nanopb & rpc #######################################################
78################################################################################
79
80ifeq ($(HAS_PROTO_SRC),true)
81COMMON_CFLAGS += -I$(NANOPB_PREFIX)
82
83ifneq ($(NANOPB_INCLUDE_LIBRARY),false)
84COMMON_SRCS += $(NANOPB_PREFIX)/pb_common.c
85COMMON_SRCS += $(NANOPB_PREFIX)/pb_decode.c
86COMMON_SRCS += $(NANOPB_PREFIX)/pb_encode.c
87endif
88
89# NanoPB Compiler Flags
90ifneq ($(NANOPB_INCLUDE_LIBRARY),false)
91COMMON_CFLAGS += -DPB_NO_PACKED_STRUCTS=1
92endif
93
94NANOPB_PROTOC = $(NANOPB_PREFIX)/generator/protoc-gen-nanopb
95
96endif # ifeq ($(HAS_PROTO_SRC),true)
97
98################################################################################
99# nanopb #######################################################################
100################################################################################
101
102ifneq ($(NANOPB_GEN_SRCS),)
103COMMON_CFLAGS += -I$(NANOPB_GEN_PATH)
104COMMON_CFLAGS += $(addprefix -I$(NANOPB_GEN_PATH)/, $(NANOPB_INCLUDES))
105endif
106
107# NanoPB Generator Setup #######################################################
108
109NANOPB_GENERATOR_SRCS = $(NANOPB_PREFIX)/generator/proto/nanopb_pb2.py
110NANOPB_GENERATOR_SRCS += $(NANOPB_PREFIX)/generator/proto/plugin_pb2.py
111
112$(NANOPB_GENERATOR_SRCS):
113	cd $(NANOPB_PREFIX)/generator/proto && $(MAKE)
114
115ifneq ($(NANOPB_OPTIONS),)
116NANOPB_OPTIONS_FLAG = --options-file=$(NANOPB_OPTIONS)
117else
118NANOPB_OPTIONS_FLAG =
119endif
120
121NANOPB_FLAGS += $(addprefix --proto_path=, $(abspath $(NANOPB_INCLUDES)))
122
123# Generate NanoPB Sources ######################################################
124
125COMMON_SRCS += $(NANOPB_GEN_SRCS)
126
127NANOPB_PROTOC = $(NANOPB_PREFIX)/generator/protoc-gen-nanopb
128
129$(NANOPB_GEN_PATH)/%.$(NANOPB_EXTENSION).c \
130        $(NANOPB_GEN_PATH)/%.$(NANOPB_EXTENSION).h: %.proto \
131                                                    %.options \
132                                                    $(NANOPB_GENERATOR_SRCS)
133	@echo " [NANOPB] $<"
134	$(V)mkdir -p $(dir $@)
135	$(V)PYTHONPATH=$(PYTHONPATH) $(PROTOC) \
136	  --plugin=protoc-gen-nanopb=$(NANOPB_PROTOC) \
137	  --proto_path=$(abspath $(dir $<)) \
138	  $(NANOPB_FLAGS) \
139	  --nanopb_out="$(NANOPB_GENERATOR_FLAGS) \
140	  --options-file=$(basename $<).options:$(dir $@)" \
141	  $(abspath $<)
142
143$(NANOPB_GEN_PATH)/%.$(NANOPB_EXTENSION).c \
144        $(NANOPB_GEN_PATH)/%.$(NANOPB_EXTENSION).h: %.proto \
145                                                    $(NANOPB_OPTIONS) \
146                                                    $(NANOPB_GENERATOR_SRCS)
147	@echo " [NANOPB] $<"
148	$(V)mkdir -p $(dir $@)
149	$(V)PYTHONPATH=$(PYTHONPATH) $(PROTOC) \
150	  --plugin=protoc-gen-nanopb=$(NANOPB_PROTOC) \
151	  --proto_path=$(abspath $(dir $<)) \
152	  $(NANOPB_FLAGS) \
153	  --nanopb_out="$(NANOPB_GENERATOR_FLAGS) $(NANOPB_OPTIONS_FLAG):$(dir $@)" \
154	  $(abspath $<)
155
156################################################################################
157# Specific to pigweed RPC ######################################################
158################################################################################
159ifneq ($(PW_RPC_SRCS),)
160
161# Location of various Pigweed modules
162PIGWEED_DIR = $(ANDROID_BUILD_TOP)/external/pigweed
163PROTOBUF_DIR = $(ANDROID_BUILD_TOP)/external/protobuf
164CHRE_PREFIX = $(ANDROID_BUILD_TOP)/system/chre
165CHRE_UTIL_DIR = $(CHRE_PREFIX)/util
166CHRE_API_DIR = $(CHRE_PREFIX)/chre_api
167PIGWEED_CHRE_DIR=$(CHRE_PREFIX)/external/pigweed
168PIGWEED_CHRE_UTIL_DIR = $(CHRE_UTIL_DIR)/pigweed
169
170PW_RPC_GEN_PATH = $(OUT)/pw_rpc_gen
171
172# Create proto used for header generation ######################################
173
174PW_RPC_PROTO_GENERATOR = $(PIGWEED_DIR)/pw_protobuf_compiler/py/pw_protobuf_compiler/generate_protos.py
175PW_RPC_GENERATOR_PROTO = $(PIGWEED_DIR)/pw_rpc/internal/packet.proto
176PW_RPC_GENERATOR_COMPILED_PROTO = $(PW_RPC_GEN_PATH)/py/pw_rpc/internal/packet_pb2.py
177PW_PROTOBUF_PROTOS = $(PIGWEED_DIR)/pw_protobuf/pw_protobuf_protos/common.proto \
178	  $(PIGWEED_DIR)/pw_protobuf/pw_protobuf_protos/field_options.proto \
179	  $(PIGWEED_DIR)/pw_protobuf/pw_protobuf_protos/status.proto
180
181# Modifies PYTHONPATH so that python can see all of pigweed's modules used by
182# their protoc plugins
183PW_RPC_GENERATOR_CMD = PYTHONPATH=$$PYTHONPATH:$(PW_RPC_GEN_PATH)/py:$\
184  $(PIGWEED_DIR)/pw_status/py:$(PIGWEED_DIR)/pw_protobuf/py:$\
185  $(PIGWEED_DIR)/pw_protobuf_compiler/py $(PYTHON)
186
187$(PW_RPC_GENERATOR_COMPILED_PROTO): $(PW_RPC_GENERATOR_PROTO)
188	@echo " [PW_RPC] $<"
189	$(V)mkdir -p $(PW_RPC_GEN_PATH)/py/pw_rpc/internal
190	$(V)mkdir -p $(PW_RPC_GEN_PATH)/py/pw_protobuf_codegen_protos
191	$(V)mkdir -p $(PW_RPC_GEN_PATH)/py/pw_protobuf_protos
192	$(V)cp -R $(PIGWEED_DIR)/pw_rpc/py/pw_rpc $(PW_RPC_GEN_PATH)/py/
193
194	$(PROTOC) -I$(PIGWEED_DIR)/pw_protobuf/pw_protobuf_protos \
195	  --experimental_allow_proto3_optional \
196	  --python_out=$(PW_RPC_GEN_PATH)/py/pw_protobuf_protos \
197	  $(PW_PROTOBUF_PROTOS)
198
199	$(PROTOC) -I$(PIGWEED_DIR)/pw_protobuf/pw_protobuf_codegen_protos \
200	  --experimental_allow_proto3_optional \
201	  --python_out=$(PW_RPC_GEN_PATH)/py/pw_protobuf_codegen_protos \
202	  $(PIGWEED_DIR)/pw_protobuf/pw_protobuf_codegen_protos/codegen_options.proto
203
204	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
205	  --out-dir=$(PW_RPC_GEN_PATH)/py/pw_rpc/internal \
206	  --compile-dir=$(dir $<) --sources $(PW_RPC_GENERATOR_PROTO) \
207	  --language python \
208	  --no-experimental-editions
209
210	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
211	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) \
212	  --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \
213	  --compile-dir=$(dir $<) --sources $(PW_RPC_GENERATOR_PROTO) \
214	  --language pwpb \
215	  --no-experimental-editions
216
217# Generated PW RPC Files #######################################################
218
219PW_RPC_GEN_SRCS = $(patsubst %.proto, \
220                             $(PW_RPC_GEN_PATH)/%.pb.c, \
221                             $(PW_RPC_SRCS))
222
223# Include to-be-generated files
224COMMON_CFLAGS += -I$(PW_RPC_GEN_PATH)
225COMMON_CFLAGS += -I$(PW_RPC_GEN_PATH)/$(PIGWEED_DIR)
226
227# Add include paths to reference protos directly
228COMMON_CFLAGS += $(addprefix -I$(PW_RPC_GEN_PATH)/, $(abspath $(dir $(PW_RPC_SRCS))))
229
230# Add include paths to import protos
231ifneq ($(PW_RPC_INCLUDE_DIRS),)
232COMMON_CFLAGS += $(addprefix -I$(PW_RPC_GEN_PATH)/, $(abspath $(PW_RPC_INCLUDE_DIRS)))
233endif
234
235# Add Google proto well-known types. See https://protobuf.dev/reference/protobuf/google.protobuf/.
236COMMON_CFLAGS += -I$(PW_RPC_GEN_PATH)/$(PROTOBUF_DIR)/src
237
238COMMON_SRCS += $(PW_RPC_GEN_SRCS)
239
240# PW RPC library ###############################################################
241
242# Pigweed RPC include paths
243COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_assert/public
244COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_bytes/public
245COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_containers/public
246COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_function/public
247COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_log/public
248COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_polyfill/public
249COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_polyfill/public_overrides
250COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_polyfill/standard_library_public
251COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_preprocessor/public
252COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_protobuf/public
253COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_result/public
254COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/nanopb/public
255COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/public
256COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/pwpb/public
257COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/raw/public
258COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_span/public
259COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_span/public_overrides
260COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_status/public
261COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_stream/public
262COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_string/public
263COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_sync/public
264COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_toolchain/public
265COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_varint/public
266COMMON_CFLAGS += -I$(PIGWEED_DIR)/third_party/fuchsia/repo/sdk/lib/fit/include
267COMMON_CFLAGS += -I$(PIGWEED_DIR)/third_party/fuchsia/repo/sdk/lib/stdcompat/include
268
269# Pigweed RPC sources
270COMMON_SRCS += $(PIGWEED_DIR)/pw_assert_log/assert_log.cc
271COMMON_SRCS += $(PIGWEED_DIR)/pw_containers/intrusive_item.cc
272COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/decoder.cc
273COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/encoder.cc
274COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/stream_decoder.cc
275COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/call.cc
276COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/channel.cc
277COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/channel_list.cc
278COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/client.cc
279COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/client_call.cc
280COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/endpoint.cc
281COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/packet.cc
282COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/server.cc
283COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/server_call.cc
284COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/service.cc
285COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/nanopb/common.cc
286COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/nanopb/method.cc
287COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/nanopb/server_reader_writer.cc
288COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/pwpb/server_reader_writer.cc
289COMMON_SRCS += $(PIGWEED_DIR)/pw_status/status.cc
290COMMON_SRCS += $(PIGWEED_DIR)/pw_stream/memory_stream.cc
291COMMON_SRCS += $(PIGWEED_DIR)/pw_varint/stream.cc
292COMMON_SRCS += $(PIGWEED_DIR)/pw_varint/varint_c.c
293COMMON_SRCS += $(PIGWEED_DIR)/pw_varint/varint.cc
294# Pigweed configuration
295COMMON_CFLAGS += -DPW_RPC_USE_GLOBAL_MUTEX=0
296COMMON_CFLAGS += -DPW_RPC_YIELD_MODE=PW_RPC_YIELD_MODE_BUSY_LOOP
297
298# Enable closing a client stream.
299COMMON_CFLAGS += -DPW_RPC_COMPLETION_REQUEST_CALLBACK
300
301# Use dynamic channel allocation
302COMMON_CFLAGS += -DPW_RPC_DYNAMIC_ALLOCATION
303COMMON_CFLAGS += -DPW_RPC_DYNAMIC_CONTAINER\(type\)="chre::DynamicVector<type>"
304COMMON_CFLAGS += -DPW_RPC_DYNAMIC_CONTAINER_INCLUDE='"chre/util/dynamic_vector.h"'
305
306# Add CHRE Pigweed util sources since nanoapps should always use these
307COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/chre_channel_output.cc
308COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/rpc_client.cc
309COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/rpc_helper.cc
310COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/rpc_server.cc
311COMMON_SRCS += $(CHRE_UTIL_DIR)/nanoapp/callbacks.cc
312COMMON_SRCS += $(CHRE_UTIL_DIR)/dynamic_vector_base.cc
313
314# CHRE Pigweed overrides
315COMMON_CFLAGS += -I$(PIGWEED_CHRE_DIR)/pw_log_nanoapp/public_overrides
316COMMON_CFLAGS += -I$(PIGWEED_CHRE_DIR)/pw_assert_nanoapp/public_overrides
317
318# Generate PW RPC headers ######################################################
319
320$(PW_RPC_GEN_PATH)/%.pb.c \
321        $(PW_RPC_GEN_PATH)/%.pb.h \
322        $(PW_RPC_GEN_PATH)/%.rpc.pb.h \
323        $(PW_RPC_GEN_PATH)/%.raw_rpc.pb.h: %.proto \
324                                           %.options \
325                                           $(NANOPB_GENERATOR_SRCS) \
326                                           $(PW_RPC_GENERATOR_COMPILED_PROTO)
327	@echo " [PW_RPC] $<"
328	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
329	  --plugin-path=$(NANOPB_PROTOC) \
330	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb \
331	  --no-experimental-editions \
332	  --sources $<
333
334	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
335	  --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \
336	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb \
337	  --no-experimental-editions \
338	  --sources $<
339
340	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
341	  --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_nanopb.py \
342	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb_rpc \
343	  --no-experimental-editions \
344	  --sources $<
345
346	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
347	  --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_raw.py \
348	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language raw_rpc \
349	  --no-experimental-editions \
350	  --sources $<
351
352	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
353	  --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_pwpb.py \
354	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb_rpc \
355	  --no-experimental-editions \
356	  --sources $<
357
358$(PW_RPC_GEN_PATH)/%.pb.c \
359        $(PW_RPC_GEN_PATH)/%.pb.h \
360        $(PW_RPC_GEN_PATH)/%.rpc.pb.h \
361        $(PW_RPC_GEN_PATH)/%.raw_rpc.pb.h: %.proto \
362                                           $(NANOPB_OPTIONS) \
363                                           $(NANOPB_GENERATOR_SRCS) \
364                                           $(PW_RPC_GENERATOR_COMPILED_PROTO)
365	@echo " [PW_RPC] $<"
366	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
367	  --plugin-path=$(NANOPB_PROTOC) \
368	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb \
369	  --no-experimental-editions \
370	  --sources $<
371
372	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
373	  --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \
374	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb \
375	  --no-experimental-editions \
376	  --sources $<
377
378	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
379	  --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_nanopb.py \
380	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb_rpc \
381	  --no-experimental-editions \
382	  --sources $<
383
384	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
385	  --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_raw.py \
386	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language raw_rpc \
387	  --no-experimental-editions \
388	  --sources $<
389
390	$(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \
391	  --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_pwpb.py \
392	  --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb_rpc \
393	  --no-experimental-editions \
394	  --sources $<
395
396endif # ifneq ($(PW_RPC_SRCS),)
397