xref: /aosp_15_r20/external/pigweed/pw_system/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_pigweed/third_party/ambiq/ambiq.gni")
18import("$dir_pigweed/third_party/freertos/freertos.gni")
19import("$dir_pigweed/third_party/nanopb/nanopb.gni")
20import("$dir_pigweed/third_party/pico_sdk/pi_pico.gni")
21import("$dir_pigweed/third_party/smartfusion_mss/mss.gni")
22import("$dir_pigweed/third_party/stm32cube/stm32cube.gni")
23import("$dir_pw_async2/backend.gni")
24import("$dir_pw_build/error.gni")
25import("$dir_pw_build/facade.gni")
26import("$dir_pw_build/module_config.gni")
27import("$dir_pw_build/target_types.gni")
28import("$dir_pw_cpu_exception/backend.gni")
29import("$dir_pw_docgen/docs.gni")
30import("$dir_pw_protobuf_compiler/proto.gni")
31import("$dir_pw_unit_test/test.gni")
32import("backend.gni")
33
34declare_args() {
35  # The build target that overrides the default configuration options for this
36  # module. This should point to a source set that provides defines through a
37  # public config (which may -include a file or add defines directly).
38  pw_system_CONFIG = pw_build_DEFAULT_MODULE_CONFIG
39}
40
41config("public_include_path") {
42  include_dirs = [ "public" ]
43}
44
45# This config moves RPC logging to a separate RPC channel and HDLC
46# address. This does two things:
47#   * The separate RPC channel allows logging traffic to be treated as
48#     if it is being sent to a different client via a separate RPC
49#     channel. This illustrates the ability for an RPC server to
50#     communicate to multiple clients over multiple physical links.
51#   * The separate HDLC address completely isolates typical RPC traffic
52#     from logging traffic by communicating to a different HDLC endpoint
53#     address. This effectively creates two virtual data pipes over the
54#     same physical link.
55#
56# This is mostly to illustrate pw_rpc's capability to route and multiplex
57# traffic.
58config("multi_endpoint_rpc_overrides") {
59  defines = [
60    "PW_SYSTEM_LOGGING_CHANNEL_ID=10000",
61    "PW_SYSTEM_LOGGING_RPC_HDLC_ADDRESS=10000",
62  ]
63}
64
65config("pw_cpu_exception_config") {
66  # disable the crash handler entirely if the cpu exception backend has
67  # not been set.
68  if (pw_cpu_exception_ENTRY_BACKEND == "") {
69    defines = [ "PW_SYSTEM_ENABLE_CRASH_HANDLER=0" ]
70  }
71}
72
73# The Pigweed config pattern requires a pw_source_set to provide the
74# configuration defines. This provides the flags in
75# multi_endpoint_rpc_overrides.
76pw_source_set("multi_endpoint_rpc_config") {
77  public_configs = [ ":multi_endpoint_rpc_overrides" ]
78}
79
80pw_source_set("config") {
81  sources = [ "public/pw_system/config.h" ]
82  public_configs = [
83    ":public_include_path",
84    ":pw_cpu_exception_config",
85  ]
86  public_deps = [ pw_system_CONFIG ]
87  visibility = [ "./*" ]
88}
89
90pw_source_set("log") {
91  public = [ "public/pw_system/log.h" ]
92  public_configs = [ ":public_include_path" ]
93  sources = [ "log.cc" ]
94  public_deps = [
95    "$dir_pw_log_rpc:log_service",
96    "$dir_pw_log_rpc:rpc_log_drain_thread",
97    "$dir_pw_multisink",
98  ]
99  deps = [
100    ":config",
101    "$dir_pw_log_rpc:rpc_log_drain",
102    "$dir_pw_sync:lock_annotations",
103    "$dir_pw_sync:mutex",
104  ]
105}
106
107# There is no public part to this backend which does not cause circular
108# dependencies, there is only the pw_build_LINK_DEPS "log_backend.impl".
109pw_source_set("log_backend") {
110}
111
112pw_source_set("log_backend.impl") {
113  sources = [ "log_backend.cc" ]
114  deps = [
115    ":config",
116    ":log",
117    "$dir_pw_bytes",
118    "$dir_pw_chrono:system_clock",
119    "$dir_pw_log:proto_utils",
120    "$dir_pw_log:pw_log.facade",
121    "$dir_pw_log_string:handler.facade",
122    "$dir_pw_metric:global",
123    "$dir_pw_multisink",
124    "$dir_pw_result",
125    "$dir_pw_string",
126    "$dir_pw_sync:interrupt_spin_lock",
127    "$dir_pw_sync:lock_annotations",
128    "$dir_pw_tokenizer",
129  ]
130}
131
132pw_facade("rpc_server") {
133  backend = pw_system_RPC_SERVER_BACKEND
134  public = [ "public/pw_system/rpc_server.h" ]
135  public_configs = [ ":public_include_path" ]
136  public_deps = [
137    ":config",
138    "$dir_pw_rpc:server",
139    "$dir_pw_thread:thread_core",
140  ]
141}
142
143pw_facade("io") {
144  backend = pw_system_IO_BACKEND
145  public_configs = [ ":public_include_path" ]
146  public = [ "public/pw_system/io.h" ]
147  public_deps = [ "$dir_pw_stream" ]
148}
149
150pw_facade("device_handler") {
151  backend = pw_system_DEVICE_HANDLER
152  public_configs = [ ":public_include_path" ]
153  public = [ "public/pw_system/device_handler.h" ]
154  public_deps = [ "$dir_pw_snapshot:snapshot_proto.pwpb" ]
155}
156
157pw_source_set("unknown_device_handler") {
158  sources = [ "unknown_device_handler.cc" ]
159  deps = [ ":device_handler.facade" ]
160}
161
162pw_source_set("init") {
163  public_configs = [ ":public_include_path" ]
164  public = [ "public/pw_system/init.h" ]
165  sources = [ "init.cc" ]
166  deps = [
167    ":device_service",
168    ":file_manager",
169    ":file_service",
170    ":log",
171    ":rpc_server",
172    ":target_hooks.facade",
173    ":thread_snapshot_service",
174    ":trace_service",
175    ":transfer_service",
176    ":work_queue",
177    "$dir_pw_metric:global",
178    "$dir_pw_metric:metric_service_pwpb",
179    "$dir_pw_rpc/pwpb:echo_service",
180    "$dir_pw_thread:thread",
181    "$dir_pw_trace",
182  ]
183  if (pw_cpu_exception_ENTRY_BACKEND != "") {
184    deps += [
185      ":crash_handler",
186      ":crash_snapshot",
187    ]
188  }
189
190  # disable include checking, as there are conditional includes dependent on
191  # whether the pw_cpu_exception_ENTRY_BACKEND is set.
192  check_includes = false
193}
194
195pw_source_set("hdlc_rpc_server") {
196  sources = [ "hdlc_rpc_server.cc" ]
197  deps = [
198    ":config",
199    ":io",
200    ":rpc_server.facade",
201    "$dir_pw_assert",
202    "$dir_pw_hdlc:decoder",
203    "$dir_pw_hdlc:default_addresses",
204    "$dir_pw_hdlc:rpc_channel_output",
205    "$dir_pw_log",
206    "$dir_pw_sync:mutex",
207    "$dir_pw_trace",
208  ]
209}
210
211pw_source_set("work_queue") {
212  public_configs = [ ":public_include_path" ]
213  public = [ "public/pw_system/work_queue.h" ]
214  sources = [ "work_queue.cc" ]
215  public_deps = [ "$dir_pw_work_queue" ]
216  deps = [ ":config" ]
217}
218
219pw_source_set("sys_io_target_io") {
220  sources = [ "sys_io_target_io.cc" ]
221  deps = [
222    ":io.facade",
223    "$dir_pw_stream",
224    "$dir_pw_stream:sys_io_stream",
225  ]
226}
227
228pw_source_set("socket_target_io") {
229  sources = [ "socket_target_io.cc" ]
230  deps = [
231    ":config",
232    ":io.facade",
233    "$dir_pw_assert",
234    "$dir_pw_stream",
235    "$dir_pw_stream:socket_stream",
236  ]
237}
238
239pw_source_set("transfer_handlers") {
240  public = [ "public/pw_system/transfer_handlers.h" ]
241  public_configs = [ ":public_include_path" ]
242  public_deps = [
243    ":config",
244    "$dir_pw_persistent_ram",
245    "$dir_pw_trace_tokenized:config",
246    "$dir_pw_transfer",
247  ]
248  sources = [ "transfer_handlers.cc" ]
249  deps = []
250}
251
252pw_source_set("file_manager") {
253  public = [ "public/pw_system/file_manager.h" ]
254  public_configs = [ ":public_include_path" ]
255  public_deps = [
256    ":config",
257    ":transfer_handlers",
258    "$dir_pw_file:flat_file_system",
259    "$dir_pw_persistent_ram:flat_file_system_entry",
260  ]
261  sources = [ "file_manager.cc" ]
262  deps = [ ":trace_service" ]
263  if (pw_cpu_exception_ENTRY_BACKEND != "") {
264    deps += [ ":crash_snapshot" ]
265  }
266
267  # disable include checking, as there are conditional includes dependent on
268  # whether the pw_cpu_exception_ENTRY_BACKEND is set.
269  check_includes = false
270}
271
272pw_source_set("transfer_service") {
273  public = [ "public/pw_system/transfer_service.h" ]
274  public_configs = [ ":public_include_path" ]
275  public_deps = [ "$dir_pw_transfer" ]
276  sources = [ "transfer_service.cc" ]
277  deps = [ ":file_manager" ]
278}
279
280pw_source_set("file_service") {
281  public = [ "public/pw_system/file_service.h" ]
282  public_configs = [ ":public_include_path" ]
283  public_deps = []
284  sources = [ "file_service.cc" ]
285  deps = [ ":file_manager" ]
286}
287
288pw_source_set("trace_service") {
289  public = [ "public/pw_system/trace_service.h" ]
290  public_configs = [ ":public_include_path" ]
291  public_deps = [ ":transfer_handlers" ]
292  sources = [ "trace_service.cc" ]
293  deps = [
294    "$dir_pw_persistent_ram",
295    "$dir_pw_trace_tokenized:trace_service_pwpb",
296  ]
297}
298
299pw_source_set("crash_handler") {
300  public = [ "public/pw_system/crash_handler.h" ]
301  public_configs = [ ":public_include_path" ]
302  public_deps = []
303  sources = [ "crash_handler.cc" ]
304  deps = [
305    ":crash_snapshot",
306    ":device_handler",
307    ":log",
308    "$dir_pw_assert_trap:message",
309    "$dir_pw_cpu_exception:handler",
310  ]
311}
312
313pw_source_set("crash_snapshot") {
314  public = [ "public/pw_system/crash_snapshot.h" ]
315  public_configs = [ ":public_include_path" ]
316  public_deps = [
317    ":transfer_handlers",
318    "$dir_pw_cpu_exception:entry",
319    "$dir_pw_persistent_ram",
320    "$dir_pw_snapshot:snapshot_proto.pwpb",
321  ]
322  sources = [ "crash_snapshot.cc" ]
323  deps = [
324    ":device_handler",
325    ":log",
326    "$dir_pw_multisink:util",
327    "$dir_pw_snapshot:uuid",
328  ]
329}
330
331pw_proto_library("device_service_proto") {
332  sources = [ "pw_system_protos/device_service.proto" ]
333  inputs = [ "pw_system_protos/device_service.options" ]
334  deps = []
335}
336
337pw_source_set("device_service_pwpb") {
338  public = [ "public/pw_system/device_service_pwpb.h" ]
339  public_configs = [ ":public_include_path" ]
340  public_deps = []
341  sources = [ "device_service_pwpb.cc" ]
342  public_deps = [ ":device_service_proto.pwpb_rpc" ]
343  deps = [ ":device_handler" ]
344}
345
346pw_source_set("device_service") {
347  public = [ "public/pw_system/device_service.h" ]
348  public_configs = [ ":public_include_path" ]
349  public_deps = []
350  sources = [ "device_service.cc" ]
351  deps = [ ":device_service_pwpb" ]
352}
353
354pw_source_set("thread_snapshot_service") {
355  public = [ "public/pw_system/thread_snapshot_service.h" ]
356  public_configs = [ ":public_include_path" ]
357  public_deps = [ "$dir_pw_rpc:server" ]
358  sources = [ "thread_snapshot_service.cc" ]
359  deps = [ "$dir_pw_thread:thread_snapshot_service" ]
360}
361
362pw_facade("target_hooks") {
363  backend = pw_system_TARGET_HOOKS_BACKEND
364  public = [ "public/pw_system/target_hooks.h" ]
365  public_deps = [ "$dir_pw_thread:thread" ]
366  public_configs = [ ":public_include_path" ]
367}
368
369if (pw_system_TARGET_HOOKS_BACKEND == "") {
370  # Do nothing, prevents errors from trying to parse pw_system_TARGET_HOOKS_BACKEND as a
371  # build target when it's unset.
372} else if (get_label_info(pw_system_TARGET_HOOKS_BACKEND,
373                          "label_no_toolchain") ==
374           get_label_info(":stl_target_hooks", "label_no_toolchain")) {
375  pw_source_set("stl_target_hooks") {
376    deps = [
377      ":config",
378      "$dir_pw_thread:thread",
379      "$dir_pw_thread_stl:thread",
380    ]
381    sources = [ "stl_target_hooks.cc" ]
382  }
383} else if (get_label_info(pw_system_TARGET_HOOKS_BACKEND,
384                          "label_no_toolchain") ==
385           get_label_info(":freertos_target_hooks", "label_no_toolchain")) {
386  pw_source_set("freertos_target_hooks") {
387    deps = [
388      ":config",
389      ":init",
390      "$dir_pw_third_party/freertos",
391      "$dir_pw_thread:thread",
392      "$dir_pw_thread_freertos:thread",
393    ]
394    sources = [ "freertos_target_hooks.cc" ]
395  }
396}
397
398group("pw_system") {
399  public_deps = [
400    ":init",
401    ":io",
402    ":log",
403    ":rpc_server",
404    ":work_queue",
405  ]
406  deps = [ ":target_hooks" ]
407}
408
409pw_source_set("async") {
410  public = [ "public/pw_system/system.h" ]
411  public_configs = [ ":public_include_path" ]
412  sources = [
413    "pw_system_private/threads.h",
414    "system.cc",
415    "threads.cc",
416  ]
417  public_deps = [
418    "$dir_pw_allocator:allocator",
419    "$dir_pw_async2:dispatcher",
420    "$dir_pw_channel",
421    "$dir_pw_rpc:server",
422  ]
423  deps = [
424    ":async_packet_io",
425    ":file_manager",
426    ":file_service",
427    ":log",
428    ":thread_snapshot_service",
429    ":transfer_service",
430    ":work_queue",
431    "$dir_pw_allocator:best_fit_block_allocator",
432    "$dir_pw_allocator:synchronized_allocator",
433    "$dir_pw_async2:allocate_task",
434    "$dir_pw_async2:pend_func_task",
435    "$dir_pw_hdlc:router",
436    "$dir_pw_multibuf:simple_allocator",
437    "$dir_pw_rpc/pwpb:echo_service",
438    "$dir_pw_sync:interrupt_spin_lock",
439    "$dir_pw_thread:thread",
440  ]
441  if (pw_cpu_exception_ENTRY_BACKEND != "") {
442    deps += [
443      ":crash_handler",
444      ":crash_snapshot",
445    ]
446  }
447}
448
449pw_executable("system_example") {
450  # TODO: b/303282642 - Remove this testonly
451  testonly = pw_unit_test_TESTONLY
452
453  sources = [ "example_user_app_init.cc" ]
454  deps = [
455    ":pw_system",
456    "$dir_pw_log",
457    "$dir_pw_thread:sleep",
458    "$dir_pw_trace",
459    "$dir_pw_unit_test:rpc_service",
460
461    # Adds a test that the test server can run.
462    "$dir_pw_status:status_test.lib",
463    "$dir_pw_string:string_builder_test.lib",
464  ]
465}
466
467pw_executable("system_async_host_example") {
468  sources = [ "system_async_host_example.cc" ]
469  deps = [
470    ":async",
471    "$dir_pw_channel:epoll_channel",
472    "$dir_pw_multibuf:testing",
473  ]
474}
475
476pw_source_set("async_packet_io") {
477  public_configs = [ ":public_include_path" ]
478  public = [ "public/pw_system/internal/async_packet_io.h" ]
479  sources = [ "async_packet_io.cc" ]
480  public_deps = [
481    "$dir_pw_async2:dispatcher",
482    "$dir_pw_channel:forwarding_channel",
483    "$dir_pw_containers:inline_var_len_entry_queue",
484    "$dir_pw_hdlc:router",
485    "$dir_pw_multibuf:simple_allocator",
486    "$dir_pw_rpc:server",
487    "$dir_pw_sync:lock_annotations",
488    "$dir_pw_sync:mutex",
489    "$dir_pw_sync:thread_notification",
490    "$dir_pw_thread:thread",
491    dir_pw_allocator,
492    dir_pw_channel,
493    dir_pw_multibuf,
494  ]
495  deps = [
496    ":config",
497    dir_pw_assert,
498    dir_pw_log,
499  ]
500  visibility = [ "./*" ]
501}
502
503pw_test("async_packet_io_test") {
504  sources = [ "async_packet_io_test.cc" ]
505  deps = [
506    ":async_packet_io",
507    "$dir_pw_allocator:testing",
508    "$dir_pw_channel:loopback_channel",
509    "$dir_pw_multibuf:testing",
510  ]
511
512  # TODO: b/317922402 - Run on Windows when thread detaching is supported.
513  enable_if = host_os != "win" && pw_async2_DISPATCHER_BACKEND != ""
514}
515
516pw_test("system_async_test") {
517  sources = [ "system_async_test.cc" ]
518  deps = [
519    ":async",
520    "$dir_pw_allocator:testing",
521    "$dir_pw_channel:loopback_channel",
522    "$dir_pw_multibuf:testing",
523  ]
524
525  # TODO: b/317922402 - Run on Windows when thread detaching is supported.
526  enable_if = host_os != "win" && pw_async2_DISPATCHER_BACKEND != ""
527}
528
529group("system_examples") {
530  # TODO: b/303282642 - Remove this testonly
531  testonly = pw_unit_test_TESTONLY
532
533  deps = [ ":system_example($dir_pigweed/targets/host_device_simulator:host_device_simulator.speed_optimized)" ]
534  if (dir_pw_third_party_stm32cube_f4 != "" &&
535      dir_pw_third_party_freertos != "") {
536    deps += [ ":system_example($dir_pigweed/targets/stm32f429i_disc1_stm32cube:stm32f429i_disc1_stm32cube.size_optimized)" ]
537    deps += [ ":system_example($dir_pigweed/targets/stm32f429i_disc1_stm32cube:stm32f429i_disc1_stm32cube_clang.size_optimized)" ]
538  }
539  if (dir_pw_third_party_smartfusion_mss != "" &&
540      dir_pw_third_party_freertos != "") {
541    deps += [
542      ":system_example($dir_pigweed/targets/emcraft_sf2_som:emcraft_sf2_som.size_optimized)",
543      ":system_example($dir_pigweed/targets/emcraft_sf2_som:emcraft_sf2_som.speed_optimized)",
544      ":system_example($dir_pigweed/targets/emcraft_sf2_som:emcraft_sf2_som_debug.debug)",
545    ]
546  }
547  if (PICO_SRC_DIR != "" && dir_pw_third_party_freertos != "") {
548    deps += [
549      ":system_example($dir_pigweed/targets/rp2040:rp2040.debug)",
550      ":system_example($dir_pigweed/targets/rp2040:rp2040.size_optimized)",
551    ]
552  }
553  if (dir_pw_third_party_ambiq_SDK != "" && dir_pw_third_party_freertos != "") {
554    deps += [
555      ":system_example($dir_pigweed/targets/apollo4_pw_system:apollo4_pw_system.debug)",
556      ":system_example($dir_pigweed/targets/apollo4_pw_system:apollo4_pw_system.size_optimized)",
557    ]
558  }
559}
560
561pw_doc_group("docs") {
562  sources = [
563    "cli.rst",
564    "docs.rst",
565  ]
566  inputs = [
567    "Kconfig",
568    "system_async_test.cc",
569  ]
570}
571
572pw_test_group("tests") {
573  tests = [
574    ":async_packet_io_test",
575    ":system_async_test",
576  ]
577}
578