xref: /aosp_15_r20/external/pigweed/pw_rpc/BUILD.gn (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2021 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14
15import("//build_overrides/pigweed.gni")
16
17import("$dir_pw_bloat/bloat.gni")
18import("$dir_pw_build/python.gni")
19import("$dir_pw_build/python_action.gni")
20import("$dir_pw_build/python_action_test.gni")
21import("$dir_pw_build/target_types.gni")
22import("$dir_pw_chrono/backend.gni")
23import("$dir_pw_compilation_testing/negative_compilation_test.gni")
24import("$dir_pw_docgen/docs.gni")
25import("$dir_pw_protobuf_compiler/proto.gni")
26import("$dir_pw_sync/backend.gni")
27import("$dir_pw_third_party/nanopb/nanopb.gni")
28import("$dir_pw_thread/backend.gni")
29import("$dir_pw_unit_test/test.gni")
30import("config.gni")
31import("internal/integration_test_ports.gni")
32
33config("public_include_path") {
34  include_dirs = [ "public" ]
35  visibility = [ ":*" ]
36}
37
38config("disable_global_mutex_config") {
39  defines = [
40    "PW_RPC_USE_GLOBAL_MUTEX=0",
41    "PW_RPC_YIELD_MODE=PW_RPC_YIELD_MODE_BUSY_LOOP",
42  ]
43  visibility = [ ":*" ]
44}
45
46# Set pw_rpc_CONFIG to this to disable the global mutex. If additional options
47# are needed, a config target that sets those can depend on this.
48group("disable_global_mutex") {
49  public_configs = [ ":disable_global_mutex_config" ]
50}
51
52config("global_mutex_config") {
53  defines = [ "PW_RPC_USE_GLOBAL_MUTEX=1" ]
54  visibility = [ ":*" ]
55}
56
57# Set pw_rpc_CONFIG to this to always enable the global mutex. The mutex is
58# enabled by default, so this is a no-op.
59group("use_global_mutex") {
60  public_configs = [ ":global_mutex_config" ]
61}
62
63config("dynamic_allocation_config") {
64  defines = [ "PW_RPC_DYNAMIC_ALLOCATION=1" ]
65  visibility = [ ":*" ]
66}
67
68# Use this for pw_rpc_CONFIG to enable dynamic allocation.
69pw_source_set("use_dynamic_allocation") {
70  public_configs = [ ":dynamic_allocation_config" ]
71}
72
73pw_source_set("config") {
74  sources = [ "public/pw_rpc/internal/config.h" ]
75  public_configs = [ ":public_include_path" ]
76  public_deps = [ pw_rpc_CONFIG ]
77  visibility = [ "./*" ]
78  friend = [ "./*" ]
79}
80
81pw_source_set("log_config") {
82  sources = [ "public/pw_rpc/internal/log_config.h" ]
83  public_configs = [ ":public_include_path" ]
84  public_deps = [ ":config" ]
85  visibility = [ "./*" ]
86  friend = [ "./*" ]
87}
88
89pw_source_set("server") {
90  public_configs = [ ":public_include_path" ]
91  public_deps = [ ":common" ]
92  deps = [
93    ":log_config",
94    dir_pw_log,
95  ]
96  public = [
97    "public/pw_rpc/server.h",
98    "public/pw_rpc/service.h",
99  ]
100  sources = [
101    "public/pw_rpc/internal/hash.h",
102    "public/pw_rpc/internal/method.h",
103    "public/pw_rpc/internal/method_lookup.h",
104    "public/pw_rpc/internal/method_union.h",
105    "public/pw_rpc/internal/server_call.h",
106    "server.cc",
107    "server_call.cc",
108    "service.cc",
109  ]
110  friend = [ "./*" ]
111  allow_circular_includes_from = [ ":common" ]
112}
113
114pw_source_set("client") {
115  public_configs = [ ":public_include_path" ]
116  public_deps = [
117    ":common",
118    dir_pw_result,
119    dir_pw_span,
120  ]
121  deps = [
122    ":log_config",
123    dir_pw_log,
124    dir_pw_preprocessor,
125  ]
126  public = [
127    "public/pw_rpc/client.h",
128    "public/pw_rpc/internal/client_call.h",
129    "public/pw_rpc/internal/service_client.h",
130  ]
131  sources = [
132    "client.cc",
133    "client_call.cc",
134  ]
135  allow_circular_includes_from = [ ":common" ]
136}
137
138pw_source_set("client_server") {
139  public_configs = [ ":public_include_path" ]
140  public_deps = [
141    ":client",
142    ":server",
143  ]
144  public = [ "public/pw_rpc/client_server.h" ]
145  sources = [ "client_server.cc" ]
146}
147
148pw_source_set("synchronous_client_api") {
149  public_configs = [ ":public_include_path" ]
150  public_deps = [
151    ":client",
152    ":common",
153    "$dir_pw_chrono:system_clock",
154    "$dir_pw_sync:timed_thread_notification",
155  ]
156  public = [
157    "public/pw_rpc/synchronous_call.h",
158    "public/pw_rpc/synchronous_call_result.h",
159  ]
160  sources = [ "public/pw_rpc/internal/synchronous_call_impl.h" ]
161}
162
163# Classes shared by the server and client.
164pw_source_set("common") {
165  public_configs = [ ":public_include_path" ]
166  public_deps = [
167    ":config",
168    ":protos.pwpb",
169    "$dir_pw_containers:intrusive_list",
170    "$dir_pw_sync:lock_annotations",
171    "$dir_pw_toolchain:no_destructor",
172    dir_pw_assert,
173    dir_pw_bytes,
174    dir_pw_function,
175    dir_pw_polyfill,
176    dir_pw_span,
177    dir_pw_status,
178  ]
179
180  if (pw_sync_MUTEX_BACKEND != "") {
181    public_deps += [ "$dir_pw_sync:mutex" ]
182  }
183
184  deps = [
185    ":log_config",
186    dir_pw_log,
187  ]
188
189  # pw_rpc needs a way to yield the current thread. Depending on its
190  # configuration, it may need either pw_thread:sleep or pw_thread:yield.
191  if (pw_thread_SLEEP_BACKEND != "") {
192    deps += [ "$dir_pw_thread:sleep" ]
193  }
194  if (pw_thread_YIELD_BACKEND != "") {
195    deps += [ "$dir_pw_thread:yield" ]
196  }
197
198  public = [
199    "public/pw_rpc/channel.h",
200    "public/pw_rpc/method_id.h",
201    "public/pw_rpc/method_info.h",
202    "public/pw_rpc/packet_meta.h",
203    "public/pw_rpc/service_id.h",
204    "public/pw_rpc/writer.h",
205  ]
206  sources = [
207    "call.cc",
208    "channel.cc",
209    "channel_list.cc",
210    "endpoint.cc",
211    "packet.cc",
212    "packet_meta.cc",
213    "public/pw_rpc/internal/call.h",
214    "public/pw_rpc/internal/call_context.h",
215    "public/pw_rpc/internal/channel_list.h",
216    "public/pw_rpc/internal/encoding_buffer.h",
217    "public/pw_rpc/internal/endpoint.h",
218    "public/pw_rpc/internal/grpc.h",
219    "public/pw_rpc/internal/lock.h",
220    "public/pw_rpc/internal/method_info.h",
221    "public/pw_rpc/internal/packet.h",
222    "public/pw_rpc/method_type.h",
223  ]
224  friend = [ "./*" ]
225}
226
227pw_source_set("benchmark") {
228  public_configs = [ ":public_include_path" ]
229  public_deps = [ ":protos.raw_rpc" ]
230  public = [ "public/pw_rpc/benchmark.h" ]
231  sources = [ "benchmark.cc" ]
232}
233
234pw_source_set("fake_channel_output") {
235  public = [
236    "public/pw_rpc/internal/fake_channel_output.h",
237    "public/pw_rpc/payloads_view.h",
238  ]
239  sources = [ "fake_channel_output.cc" ]
240  public_configs = [ ":public_include_path" ]
241  public_deps = [
242    ":common",
243    "$dir_pw_containers:filtered_view",
244    "$dir_pw_containers:vector",
245    "$dir_pw_containers:wrapped_iterator",
246    "$dir_pw_sync:mutex",
247    dir_pw_assert,
248    dir_pw_bytes,
249    dir_pw_function,
250  ]
251  deps = [ ":log_config" ]
252  visibility = [ "./*" ]
253}
254
255pw_source_set("client_server_testing") {
256  public = [ "public/pw_rpc/internal/client_server_testing.h" ]
257  public_configs = [ ":public_include_path" ]
258  public_deps = [
259    ":client_server",
260    ":fake_channel_output",
261    "$dir_pw_bytes",
262    "$dir_pw_result",
263  ]
264  visibility = [ "./*" ]
265}
266
267pw_source_set("client_server_testing_threaded") {
268  public = [ "public/pw_rpc/internal/client_server_testing_threaded.h" ]
269  public_configs = [ ":public_include_path" ]
270  public_deps = [
271    ":client_server_testing",
272    "$dir_pw_bytes",
273    "$dir_pw_result",
274    "$dir_pw_sync:binary_semaphore",
275    "$dir_pw_sync:lock_annotations",
276    "$dir_pw_sync:mutex",
277    "$dir_pw_thread:thread",
278  ]
279  visibility = [ "./*" ]
280}
281
282pw_source_set("test_helpers") {
283  public = [ "public/pw_rpc/test_helpers.h" ]
284  public_deps = [
285    ":fake_channel_output",
286    "$dir_pw_chrono:system_clock",
287    "$dir_pw_status",
288    "$dir_pw_sync:counting_semaphore",
289    "$dir_pw_thread:yield",
290    dir_pw_assert,
291  ]
292}
293
294# thread_testing target is kept for backward compatibility.
295# New code should use test_helpers instead.
296pw_source_set("thread_testing") {
297  public = [ "public/pw_rpc/thread_testing.h" ]
298  public_deps = [ ":test_helpers" ]
299}
300
301pw_source_set("test_utils") {
302  public = [
303    "public/pw_rpc/internal/fake_channel_output.h",
304    "public/pw_rpc/internal/method_impl_tester.h",
305    "public/pw_rpc/internal/method_info_tester.h",
306    "public/pw_rpc/internal/test_method_context.h",
307    "public/pw_rpc/internal/test_utils.h",
308    "pw_rpc_private/fake_server_reader_writer.h",
309    "pw_rpc_private/test_method.h",
310  ]
311  public_configs = [ ":public_include_path" ]
312  public_deps = [
313    ":client",
314    ":server",
315    "$dir_pw_containers:vector",
316    "raw:fake_channel_output",
317    "raw:server_api",
318    dir_pw_assert,
319    dir_pw_bytes,
320  ]
321  visibility = [ "./*" ]
322}
323
324pw_source_set("integration_testing") {
325  testonly = pw_unit_test_TESTONLY
326  public = [
327    "public/pw_rpc/integration_test_socket_client.h",
328    "public/pw_rpc/integration_testing.h",
329  ]
330  sources = [ "integration_testing.cc" ]
331  public_deps = [
332    ":client",
333    "$dir_pw_hdlc:decoder",
334    "$dir_pw_hdlc:default_addresses",
335    "$dir_pw_hdlc:rpc_channel_output",
336    "$dir_pw_stream:socket_stream",
337    "$dir_pw_unit_test:logging",
338    dir_pw_assert,
339    dir_pw_function,
340    dir_pw_unit_test,
341  ]
342  deps = [ dir_pw_log ]
343}
344
345pw_executable("test_rpc_server") {
346  sources = [ "test_rpc_server.cc" ]
347  deps = [
348    ":benchmark",
349    ":log_config",
350    "system_server",
351    "system_server:socket",
352    dir_pw_log,
353  ]
354}
355
356pw_executable("client_integration_test") {
357  testonly = pw_unit_test_TESTONLY
358  sources = [ "client_integration_test.cc" ]
359  deps = [
360    ":client",
361    ":integration_testing",
362    ":protos.raw_rpc",
363    "$dir_pw_sync:binary_semaphore",
364    dir_pw_log,
365    dir_pw_unit_test,
366  ]
367
368  deps += [ "pwpb:client_integration_test" ]
369
370  if (dir_pw_third_party_nanopb != "") {
371    deps += [ "nanopb:client_integration_test" ]
372  }
373}
374
375pw_python_action_test("cpp_client_server_integration_test") {
376  testonly = pw_unit_test_TESTONLY
377  script = "py/pw_rpc/testing.py"
378  args = [
379    "--server",
380    "<TARGET_FILE(:test_rpc_server)>",
381    "--client",
382    "<TARGET_FILE(:client_integration_test)>",
383    "--",
384    "$pw_rpc_CPP_CLIENT_INTEGRATION_TEST_PORT",
385  ]
386  deps = [
387    ":client_integration_test",
388    ":test_rpc_server",
389  ]
390  tags = [ "integration" ]
391}
392
393pw_proto_library("protos") {
394  sources = [
395    "benchmark.proto",
396    "echo.proto",
397    "internal/packet.proto",
398  ]
399  inputs = [
400    "benchmark.options",
401    "benchmark.pwpb_options",
402    "echo.options",
403    "echo.pwpb_options",
404  ]
405  python_package = "py"
406  prefix = "pw_rpc"
407}
408
409pw_doc_group("docs") {
410  sources = [
411    "cpp.rst",
412    "design.rst",
413    "docs.rst",
414    "guides.rst",
415    "libraries.rst",
416    "protocol.rst",
417  ]
418  inputs = [
419    "Kconfig",
420    "benchmark.proto",
421    "echo.proto",
422    "internal/packet.proto",
423  ]
424  group_deps = [
425    "nanopb:docs",
426    "pwpb:docs",
427    "py:docs",
428    "ts:docs",
429  ]
430  report_deps = [ ":server_size" ]
431}
432
433pw_size_diff("server_size") {
434  title = "Pigweed RPC server size report"
435
436  binaries = [
437    {
438      target = "size_report:server_only"
439      base = "size_report:base"
440      label = "Server by itself"
441    },
442  ]
443
444  if (dir_pw_third_party_nanopb != "") {
445    binaries += [
446      {
447        target = "size_report:server_with_echo_service"
448        base = "size_report:base_with_nanopb"
449        label = "Server with a registered nanopb EchoService"
450      },
451    ]
452  }
453}
454
455pw_test_group("tests") {
456  tests = [
457    ":call_test",
458    ":callback_test",
459    ":channel_test",
460    ":client_server_test",
461    ":test_helpers_test",
462    ":fake_channel_output_test",
463    ":method_test",
464    ":ids_test",
465    ":packet_test",
466    ":packet_meta_test",
467    ":server_test",
468    ":service_test",
469  ]
470  group_deps = [
471    "fuzz:tests",
472    "nanopb:tests",
473    "pwpb:tests",
474    "raw:tests",
475  ]
476}
477
478pw_proto_library("test_protos") {
479  sources = [
480    "pw_rpc_test_protos/no_package.proto",
481    "pw_rpc_test_protos/test.proto",
482  ]
483  inputs = [ "pw_rpc_test_protos/test.options" ]
484  visibility = [ "./*" ]
485}
486
487pw_test("call_test") {
488  deps = [
489    ":server",
490    ":test_utils",
491  ]
492  sources = [ "call_test.cc" ]
493
494  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
495  configs = [ "$dir_pw_build:conversion_warnings" ]
496}
497
498pw_test("callback_test") {
499  enable_if = pw_thread_THREAD_BACKEND == "$dir_pw_thread_stl:thread"
500  deps = [
501    ":client",
502    ":server",
503    ":test_protos.raw_rpc",
504    "$dir_pw_sync:binary_semaphore",
505    "$dir_pw_thread:non_portable_test_thread_options",
506    "$dir_pw_thread:sleep",
507    "$dir_pw_thread:yield",
508    "$dir_pw_thread_stl:non_portable_test_thread_options",
509    "raw:client_testing",
510  ]
511  sources = [ "callback_test.cc" ]
512
513  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
514  configs = [ "$dir_pw_build:conversion_warnings" ]
515}
516
517pw_test("channel_test") {
518  deps = [
519    ":server",
520    ":test_utils",
521  ]
522  sources = [ "channel_test.cc" ]
523
524  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
525  configs = [ "$dir_pw_build:conversion_warnings" ]
526}
527
528pw_python_action("generate_ids_test") {
529  outputs = [ "$target_gen_dir/generated_ids_test.cc" ]
530
531  script = "py/tests/ids_test.py"
532  args = [ "--generate-cc-test" ] + rebase_path(outputs, root_build_dir)
533  python_deps = [
534    "$dir_pw_build/py",
535    "py",
536  ]
537}
538
539pw_test("ids_test") {
540  deps = [ ":server" ]
541  source_gen_deps = [ ":generate_ids_test" ]
542
543  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
544  configs = [ "$dir_pw_build:conversion_warnings" ]
545}
546
547pw_test("packet_test") {
548  deps = [
549    ":server",
550    "$dir_pw_fuzzer:fuzztest",
551    dir_pw_bytes,
552    dir_pw_protobuf,
553  ]
554  sources = [ "packet_test.cc" ]
555
556  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
557  configs = [ "$dir_pw_build:conversion_warnings" ]
558}
559
560pw_test("packet_meta_test") {
561  deps = [
562    ":server",
563    "$dir_pw_fuzzer:fuzztest",
564    dir_pw_bytes,
565  ]
566  sources = [ "packet_meta_test.cc" ]
567
568  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
569  configs = [ "$dir_pw_build:conversion_warnings" ]
570}
571
572pw_test("service_test") {
573  deps = [
574    ":protos.pwpb",
575    ":server",
576    dir_pw_assert,
577  ]
578  sources = [ "service_test.cc" ]
579
580  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
581  configs = [ "$dir_pw_build:conversion_warnings" ]
582}
583
584pw_test("client_server_test") {
585  deps = [
586    ":client_server",
587    ":test_utils",
588    "raw:server_api",
589  ]
590  sources = [ "client_server_test.cc" ]
591
592  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
593  configs = [ "$dir_pw_build:conversion_warnings" ]
594}
595
596pw_test("method_test") {
597  deps = [
598    ":server",
599    ":test_utils",
600  ]
601  sources = [ "method_test.cc" ]
602
603  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
604  configs = [ "$dir_pw_build:conversion_warnings" ]
605}
606
607pw_test("server_test") {
608  deps = [
609    ":protos.pwpb",
610    ":server",
611    ":test_utils",
612    dir_pw_assert,
613  ]
614  sources = [ "server_test.cc" ]
615
616  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
617  configs = [ "$dir_pw_build:conversion_warnings" ]
618}
619
620pw_test("fake_channel_output_test") {
621  deps = [ ":test_utils" ]
622  sources = [ "fake_channel_output_test.cc" ]
623
624  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
625  configs = [ "$dir_pw_build:conversion_warnings" ]
626}
627
628pw_test("test_helpers_test") {
629  deps = [
630    ":test_helpers",
631    "$dir_pw_result",
632    "$dir_pw_status",
633    "$dir_pw_sync:interrupt_spin_lock",
634    "$dir_pw_sync:lock_annotations",
635    "$dir_pw_sync:timed_thread_notification",
636    "pwpb:client_testing",
637    "pwpb:echo_service",
638    "pwpb:server_api",
639  ]
640  sources = [ "test_helpers_test.cc" ]
641  enable_if = pw_sync_TIMED_THREAD_NOTIFICATION_BACKEND != "" &&
642              pw_sync_COUNTING_SEMAPHORE_BACKEND != "" &&
643              pw_chrono_SYSTEM_CLOCK_BACKEND != ""
644
645  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
646  configs = [ "$dir_pw_build:conversion_warnings" ]
647}
648