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 209 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 210 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) \ 211 --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \ 212 --compile-dir=$(dir $<) --sources $(PW_RPC_GENERATOR_PROTO) \ 213 --language pwpb 214 215# Generated PW RPC Files ####################################################### 216 217PW_RPC_GEN_SRCS = $(patsubst %.proto, \ 218 $(PW_RPC_GEN_PATH)/%.pb.c, \ 219 $(PW_RPC_SRCS)) 220 221# Include to-be-generated files 222COMMON_CFLAGS += -I$(PW_RPC_GEN_PATH) 223COMMON_CFLAGS += -I$(PW_RPC_GEN_PATH)/$(PIGWEED_DIR) 224 225# Add include paths to reference protos directly 226COMMON_CFLAGS += $(addprefix -I$(PW_RPC_GEN_PATH)/, $(abspath $(dir $(PW_RPC_SRCS)))) 227 228# Add include paths to import protos 229ifneq ($(PW_RPC_INCLUDE_DIRS),) 230COMMON_CFLAGS += $(addprefix -I$(PW_RPC_GEN_PATH)/, $(abspath $(PW_RPC_INCLUDE_DIRS))) 231endif 232 233# Add Google proto well-known types. See https://protobuf.dev/reference/protobuf/google.protobuf/. 234COMMON_CFLAGS += -I$(PW_RPC_GEN_PATH)/$(PROTOBUF_DIR)/src 235 236COMMON_SRCS += $(PW_RPC_GEN_SRCS) 237 238# PW RPC library ############################################################### 239 240# Pigweed RPC include paths 241COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_assert/public 242COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_bytes/public 243COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_containers/public 244COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_function/public 245COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_log/public 246COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_polyfill/public 247COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_polyfill/public_overrides 248COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_polyfill/standard_library_public 249COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_preprocessor/public 250COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_protobuf/public 251COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_result/public 252COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/nanopb/public 253COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/public 254COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/pwpb/public 255COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_rpc/raw/public 256COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_span/public 257COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_span/public_overrides 258COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_status/public 259COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_stream/public 260COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_string/public 261COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_sync/public 262COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_toolchain/public 263COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_varint/public 264COMMON_CFLAGS += -I$(PIGWEED_DIR)/third_party/fuchsia/repo/sdk/lib/fit/include 265COMMON_CFLAGS += -I$(PIGWEED_DIR)/third_party/fuchsia/repo/sdk/lib/stdcompat/include 266 267# Pigweed RPC sources 268COMMON_SRCS += $(PIGWEED_DIR)/pw_assert_log/assert_log.cc 269COMMON_SRCS += $(PIGWEED_DIR)/pw_containers/intrusive_list.cc 270COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/decoder.cc 271COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/encoder.cc 272COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/stream_decoder.cc 273COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/call.cc 274COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/channel.cc 275COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/channel_list.cc 276COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/client.cc 277COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/client_call.cc 278COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/endpoint.cc 279COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/packet.cc 280COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/server.cc 281COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/server_call.cc 282COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/service.cc 283COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/nanopb/common.cc 284COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/nanopb/method.cc 285COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/nanopb/server_reader_writer.cc 286COMMON_SRCS += $(PIGWEED_DIR)/pw_rpc/pwpb/server_reader_writer.cc 287COMMON_SRCS += $(PIGWEED_DIR)/pw_status/status.cc 288COMMON_SRCS += $(PIGWEED_DIR)/pw_stream/memory_stream.cc 289COMMON_SRCS += $(PIGWEED_DIR)/pw_varint/stream.cc 290COMMON_SRCS += $(PIGWEED_DIR)/pw_varint/varint_c.c 291COMMON_SRCS += $(PIGWEED_DIR)/pw_varint/varint.cc 292# Pigweed configuration 293COMMON_CFLAGS += -DPW_RPC_USE_GLOBAL_MUTEX=0 294COMMON_CFLAGS += -DPW_RPC_YIELD_MODE=PW_RPC_YIELD_MODE_BUSY_LOOP 295 296# Enable closing a client stream. 297COMMON_CFLAGS += -DPW_RPC_COMPLETION_REQUEST_CALLBACK 298 299# Use dynamic channel allocation 300COMMON_CFLAGS += -DPW_RPC_DYNAMIC_ALLOCATION 301COMMON_CFLAGS += -DPW_RPC_DYNAMIC_CONTAINER\(type\)="chre::DynamicVector<type>" 302COMMON_CFLAGS += -DPW_RPC_DYNAMIC_CONTAINER_INCLUDE='"chre/util/dynamic_vector.h"' 303 304# Add CHRE Pigweed util sources since nanoapps should always use these 305COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/chre_channel_output.cc 306COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/rpc_client.cc 307COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/rpc_helper.cc 308COMMON_SRCS += $(PIGWEED_CHRE_UTIL_DIR)/rpc_server.cc 309COMMON_SRCS += $(CHRE_UTIL_DIR)/nanoapp/callbacks.cc 310COMMON_SRCS += $(CHRE_UTIL_DIR)/dynamic_vector_base.cc 311 312# CHRE Pigweed overrides 313COMMON_CFLAGS += -I$(PIGWEED_CHRE_DIR)/pw_log_nanoapp/public_overrides 314COMMON_CFLAGS += -I$(PIGWEED_CHRE_DIR)/pw_assert_nanoapp/public_overrides 315 316# Generate PW RPC headers ###################################################### 317 318$(PW_RPC_GEN_PATH)/%.pb.c \ 319 $(PW_RPC_GEN_PATH)/%.pb.h \ 320 $(PW_RPC_GEN_PATH)/%.rpc.pb.h \ 321 $(PW_RPC_GEN_PATH)/%.raw_rpc.pb.h: %.proto \ 322 %.options \ 323 $(NANOPB_GENERATOR_SRCS) \ 324 $(PW_RPC_GENERATOR_COMPILED_PROTO) 325 @echo " [PW_RPC] $<" 326 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 327 --plugin-path=$(NANOPB_PROTOC) \ 328 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb \ 329 --sources $< 330 331 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 332 --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \ 333 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb \ 334 --sources $< 335 336 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 337 --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_nanopb.py \ 338 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb_rpc \ 339 --sources $< 340 341 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 342 --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_raw.py \ 343 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language raw_rpc \ 344 --sources $< 345 346 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 347 --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_pwpb.py \ 348 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb_rpc \ 349 --sources $< 350 351$(PW_RPC_GEN_PATH)/%.pb.c \ 352 $(PW_RPC_GEN_PATH)/%.pb.h \ 353 $(PW_RPC_GEN_PATH)/%.rpc.pb.h \ 354 $(PW_RPC_GEN_PATH)/%.raw_rpc.pb.h: %.proto \ 355 $(NANOPB_OPTIONS) \ 356 $(NANOPB_GENERATOR_SRCS) \ 357 $(PW_RPC_GENERATOR_COMPILED_PROTO) 358 @echo " [PW_RPC] $<" 359 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 360 --plugin-path=$(NANOPB_PROTOC) \ 361 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb \ 362 --sources $< 363 364 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 365 --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \ 366 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb \ 367 --sources $< 368 369 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 370 --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_nanopb.py \ 371 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb_rpc \ 372 --sources $< 373 374 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 375 --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_raw.py \ 376 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language raw_rpc \ 377 --sources $< 378 379 $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ 380 --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_pwpb.py \ 381 --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb_rpc \ 382 --sources $< 383 384endif # ifneq ($(PW_RPC_SRCS),) 385