• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_span,
176    dir_pw_status,
177  ]
178
179  if (pw_sync_MUTEX_BACKEND != "") {
180    public_deps += [ "$dir_pw_sync:mutex" ]
181  }
182
183  deps = [
184    ":log_config",
185    dir_pw_log,
186  ]
187
188  # pw_rpc needs a way to yield the current thread. Depending on its
189  # configuration, it may need either pw_thread:sleep or pw_thread:yield.
190  if (pw_thread_SLEEP_BACKEND != "") {
191    deps += [ "$dir_pw_thread:sleep" ]
192  }
193  if (pw_thread_YIELD_BACKEND != "") {
194    deps += [ "$dir_pw_thread:yield" ]
195  }
196
197  public = [
198    "public/pw_rpc/channel.h",
199    "public/pw_rpc/method_id.h",
200    "public/pw_rpc/method_info.h",
201    "public/pw_rpc/packet_meta.h",
202    "public/pw_rpc/service_id.h",
203    "public/pw_rpc/writer.h",
204  ]
205  sources = [
206    "call.cc",
207    "channel.cc",
208    "channel_list.cc",
209    "endpoint.cc",
210    "packet.cc",
211    "packet_meta.cc",
212    "public/pw_rpc/internal/call.h",
213    "public/pw_rpc/internal/call_context.h",
214    "public/pw_rpc/internal/channel.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    "echo.options",
401    "benchmark.options",
402  ]
403  python_package = "py"
404  prefix = "pw_rpc"
405}
406
407pw_doc_group("docs") {
408  sources = [
409    "benchmark.rst",
410    "docs.rst",
411  ]
412  inputs = [
413    "benchmark.proto",
414    "echo.proto",
415    "internal/packet.proto",
416  ]
417  group_deps = [
418    "nanopb:docs",
419    "pwpb:docs",
420    "py:docs",
421    "ts:docs",
422  ]
423  report_deps = [ ":server_size" ]
424}
425
426pw_size_diff("server_size") {
427  title = "Pigweed RPC server size report"
428
429  binaries = [
430    {
431      target = "size_report:server_only"
432      base = "size_report:base"
433      label = "Server by itself"
434    },
435  ]
436
437  if (dir_pw_third_party_nanopb != "") {
438    binaries += [
439      {
440        target = "size_report:server_with_echo_service"
441        base = "size_report:base_with_nanopb"
442        label = "Server with a registered nanopb EchoService"
443      },
444    ]
445  }
446}
447
448pw_test_group("tests") {
449  tests = [
450    ":call_test",
451    ":callback_test",
452    ":channel_test",
453    ":client_server_test",
454    ":test_helpers_test",
455    ":fake_channel_output_test",
456    ":method_test",
457    ":ids_test",
458    ":packet_test",
459    ":packet_meta_test",
460    ":server_test",
461    ":service_test",
462  ]
463  group_deps = [
464    "fuzz:tests",
465    "nanopb:tests",
466    "pwpb:tests",
467    "raw:tests",
468  ]
469}
470
471pw_proto_library("test_protos") {
472  sources = [
473    "pw_rpc_test_protos/no_package.proto",
474    "pw_rpc_test_protos/test.proto",
475  ]
476  inputs = [ "pw_rpc_test_protos/test.options" ]
477  visibility = [ "./*" ]
478}
479
480pw_test("call_test") {
481  deps = [
482    ":server",
483    ":test_utils",
484  ]
485  sources = [ "call_test.cc" ]
486
487  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
488  configs = [ "$dir_pw_build:conversion_warnings" ]
489}
490
491pw_test("callback_test") {
492  enable_if = pw_thread_THREAD_BACKEND == "$dir_pw_thread_stl:thread"
493  deps = [
494    ":client",
495    ":server",
496    ":test_protos.raw_rpc",
497    "$dir_pw_sync:binary_semaphore",
498    "$dir_pw_thread:non_portable_test_thread_options",
499    "$dir_pw_thread:sleep",
500    "$dir_pw_thread:yield",
501    "$dir_pw_thread_stl:non_portable_test_thread_options",
502    "raw:client_testing",
503  ]
504  sources = [ "callback_test.cc" ]
505
506  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
507  configs = [ "$dir_pw_build:conversion_warnings" ]
508}
509
510pw_test("channel_test") {
511  deps = [
512    ":server",
513    ":test_utils",
514  ]
515  sources = [ "channel_test.cc" ]
516
517  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
518  configs = [ "$dir_pw_build:conversion_warnings" ]
519}
520
521pw_python_action("generate_ids_test") {
522  outputs = [ "$target_gen_dir/generated_ids_test.cc" ]
523
524  script = "py/tests/ids_test.py"
525  args = [ "--generate-cc-test" ] + rebase_path(outputs, root_build_dir)
526  python_deps = [
527    "$dir_pw_build/py",
528    "py",
529  ]
530}
531
532pw_test("ids_test") {
533  deps = [ ":server" ]
534  source_gen_deps = [ ":generate_ids_test" ]
535
536  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
537  configs = [ "$dir_pw_build:conversion_warnings" ]
538}
539
540pw_test("packet_test") {
541  deps = [
542    ":server",
543    "$dir_pw_fuzzer:fuzztest",
544    dir_pw_bytes,
545    dir_pw_protobuf,
546  ]
547  sources = [ "packet_test.cc" ]
548
549  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
550  configs = [ "$dir_pw_build:conversion_warnings" ]
551}
552
553pw_test("packet_meta_test") {
554  deps = [
555    ":server",
556    "$dir_pw_fuzzer:fuzztest",
557    dir_pw_bytes,
558  ]
559  sources = [ "packet_meta_test.cc" ]
560
561  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
562  configs = [ "$dir_pw_build:conversion_warnings" ]
563}
564
565pw_test("service_test") {
566  deps = [
567    ":protos.pwpb",
568    ":server",
569    dir_pw_assert,
570  ]
571  sources = [ "service_test.cc" ]
572
573  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
574  configs = [ "$dir_pw_build:conversion_warnings" ]
575}
576
577pw_test("client_server_test") {
578  deps = [
579    ":client_server",
580    ":test_utils",
581    "raw:server_api",
582  ]
583  sources = [ "client_server_test.cc" ]
584
585  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
586  configs = [ "$dir_pw_build:conversion_warnings" ]
587}
588
589pw_test("method_test") {
590  deps = [
591    ":server",
592    ":test_utils",
593  ]
594  sources = [ "method_test.cc" ]
595
596  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
597  configs = [ "$dir_pw_build:conversion_warnings" ]
598}
599
600pw_test("server_test") {
601  deps = [
602    ":protos.pwpb",
603    ":server",
604    ":test_utils",
605    dir_pw_assert,
606  ]
607  sources = [ "server_test.cc" ]
608
609  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
610  configs = [ "$dir_pw_build:conversion_warnings" ]
611}
612
613pw_test("fake_channel_output_test") {
614  deps = [ ":test_utils" ]
615  sources = [ "fake_channel_output_test.cc" ]
616
617  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
618  configs = [ "$dir_pw_build:conversion_warnings" ]
619}
620
621pw_test("test_helpers_test") {
622  deps = [
623    ":test_helpers",
624    "$dir_pw_result",
625    "$dir_pw_status",
626    "$dir_pw_sync:interrupt_spin_lock",
627    "$dir_pw_sync:lock_annotations",
628    "$dir_pw_sync:timed_thread_notification",
629    "pwpb:client_testing",
630    "pwpb:echo_service",
631    "pwpb:server_api",
632  ]
633  sources = [ "test_helpers_test.cc" ]
634  enable_if = pw_sync_TIMED_THREAD_NOTIFICATION_BACKEND != "" &&
635              pw_sync_COUNTING_SEMAPHORE_BACKEND != "" &&
636              pw_chrono_SYSTEM_CLOCK_BACKEND != ""
637
638  # TODO: b/259746255 - Remove this when everything compiles with -Wconversion.
639  configs = [ "$dir_pw_build:conversion_warnings" ]
640}
641