xref: /aosp_15_r20/external/pigweed/pw_system/BUILD.bazel (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
15load("@rules_python//python:proto.bzl", "py_proto_library")
16load("//pw_build:pw_cc_binary.bzl", "pw_cc_binary")
17load("//pw_build:pw_facade.bzl", "pw_facade")
18load(
19    "//pw_protobuf_compiler:pw_proto_library.bzl",
20    "pw_proto_filegroup",
21    "pwpb_proto_library",
22    "pwpb_rpc_proto_library",
23)
24load("//pw_system/py:console.bzl", "device_console", "device_simulator_console")
25load("//pw_unit_test:pw_cc_test.bzl", "pw_cc_test")
26load("//targets/host_device_simulator:transition.bzl", "host_device_simulator_binary")
27load("//targets/rp2040:flash.bzl", "flash_rp2040", "flash_rp2350")
28load("//targets/rp2040:transition.bzl", "rp2040_binary", "rp2350_binary")
29
30package(default_visibility = ["//visibility:public"])
31
32licenses(["notice"])
33
34cc_library(
35    name = "config",
36    hdrs = [
37        "public/pw_system/config.h",
38    ],
39    strip_include_prefix = "public",
40    visibility = ["//visibility:private"],
41    deps = [":config_override"],
42)
43
44label_flag(
45    name = "config_override",
46    build_setting_default = ":default_config",
47)
48
49cc_library(
50    name = "default_config",
51    defines = select({
52        "//pw_cpu_exception:enabled": [],
53        "//conditions:default": [
54            "PW_SYSTEM_ENABLE_CRASH_HANDLER=0",
55        ],
56    }),
57)
58
59cc_library(
60    name = "pw_system",
61    deps = [
62        ":init",
63        ":io",
64        ":extra_platform_libs",
65        ":target_hooks",
66        ":work_queue",
67        # pw_system has (transitive) dependencies on pw_assert and pw_log. So,
68        # we add deps on the backend_impl here, saving the user from having to
69        # add them manually to their cc_binary target.
70        #
71        # When implementing a backend for pw_assert or pw_log, *do not* depend
72        # on //pw_system:pw_system. Instead, depend on the appropriate
73        # component library. See :log_backend, below, for an examples.
74        "//pw_assert:check_backend_impl",
75        "//pw_assert:assert_backend_impl",
76        "//pw_log:backend_impl",
77    ],
78)
79
80# Any platform-specific pw_system components. At the very least, this should
81# include platform-specific initialization code. It may also include linker
82# scripts.
83#
84# TODO: https://github.com/bazelbuild/bazel/issues/22457 - Recommend using
85# @bazel_tool//tools/cpp:link_extra_libs instead, once they're not propagated
86# to the exec configuration.
87label_flag(
88    name = "extra_platform_libs",
89    build_setting_default = "//targets/host_device_simulator:boot",
90)
91
92cc_library(
93    name = "log",
94    srcs = [
95        "log.cc",
96    ],
97    hdrs = [
98        "public/pw_system/log.h",
99    ],
100    strip_include_prefix = "public",
101    deps = [
102        ":config",
103        ":rpc_server",
104        "//pw_log_rpc:log_service",
105        "//pw_log_rpc:rpc_log_drain",
106        "//pw_log_rpc:rpc_log_drain_thread",
107        "//pw_multisink",
108        "//pw_sync:lock_annotations",
109        "//pw_sync:mutex",
110    ],
111)
112
113cc_library(
114    name = "log_backend",
115    srcs = [
116        "log_backend.cc",
117    ],
118    deps = [
119        ":config",
120        ":log",
121        "//pw_bytes",
122        "//pw_chrono:system_clock",
123        "//pw_log:proto_utils",
124        "//pw_log:pw_log.facade",
125        "//pw_log_string:handler.facade",
126        "//pw_log_tokenized:handler.facade",
127        "//pw_log_tokenized:headers",
128        "//pw_metric:global",
129        "//pw_multisink",
130        "//pw_result",
131        "//pw_string",
132        "//pw_sync:interrupt_spin_lock",
133        "//pw_sync:lock_annotations",
134        "//pw_tokenizer",
135    ],
136    # Log backends, like assert backends, generally need to be alwayslink'ed
137    # because we don't inform Bazel correctly about dependencies on them. We
138    # only add them as deps of binary targets, not intermediate library targets,
139    # to avoid circular dependencies. But this may lead the linker to eagerly
140    # remove some symbols defined here as unused.
141    alwayslink = 1,
142)
143
144pw_facade(
145    name = "rpc_server",
146    hdrs = [
147        "public/pw_system/rpc_server.h",
148    ],
149    backend = ":rpc_server_backend",
150    strip_include_prefix = "public",
151    deps = [
152        "//pw_thread:thread_core",
153    ],
154)
155
156label_flag(
157    name = "rpc_server_backend",
158    build_setting_default = "//pw_system:hdlc_rpc_server",
159)
160
161cc_library(
162    name = "hdlc_rpc_server",
163    srcs = [
164        "hdlc_rpc_server.cc",
165    ],
166    deps = [
167        ":config",
168        ":io",
169        ":rpc_server.facade",
170        "//pw_assert",
171        "//pw_hdlc",
172        "//pw_hdlc:default_addresses",
173        "//pw_hdlc:rpc_channel_output",
174        "//pw_sync:mutex",
175        "//pw_thread:thread_core",
176        "//pw_trace",
177    ],
178)
179
180cc_library(
181    name = "thread_snapshot_service",
182    srcs = [
183        "thread_snapshot_service.cc",
184    ],
185    hdrs = [
186        "public/pw_system/thread_snapshot_service.h",
187    ],
188    strip_include_prefix = "public",
189    deps = [
190        "//pw_rpc",
191        "//pw_thread:thread_snapshot_service",
192    ],
193)
194
195pw_facade(
196    name = "io",
197    hdrs = [
198        "public/pw_system/io.h",
199    ],
200    backend = ":io_backend",
201    strip_include_prefix = "public",
202    deps = [
203        "//pw_stream",
204    ],
205)
206
207label_flag(
208    name = "io_backend",
209    build_setting_default = "//pw_system:sys_io_target_io",
210)
211
212pw_facade(
213    name = "device_handler",
214    hdrs = [
215        "public/pw_system/device_handler.h",
216    ],
217    backend = ":device_handler_backend",
218    strip_include_prefix = "public",
219    deps = [
220        "//pw_snapshot:snapshot_proto_pwpb",
221    ],
222)
223
224label_flag(
225    name = "device_handler_backend",
226    build_setting_default = "//pw_system:unknown_device_handler",
227)
228
229cc_library(
230    name = "unknown_device_handler",
231    srcs = [
232        "unknown_device_handler.cc",
233    ],
234    strip_include_prefix = "public",
235    deps = [
236        ":device_handler.facade",
237    ],
238)
239
240cc_library(
241    name = "init",
242    srcs = [
243        "init.cc",
244    ],
245    hdrs = [
246        "public/pw_system/init.h",
247    ],
248    strip_include_prefix = "public",
249    deps = [
250        ":device_service",
251        ":file_manager",
252        ":file_service",
253        ":log",
254        ":rpc_server",
255        ":target_hooks",
256        ":thread_snapshot_service",
257        ":trace_service",
258        ":transfer_service",
259        ":work_queue",
260        "//pw_metric:global",
261        "//pw_metric:metric_service_pwpb",
262        "//pw_rpc/pwpb:echo_service",
263        "//pw_thread:thread",
264    ] + select({
265        "//pw_cpu_exception:enabled": [
266            ":crash_handler",
267            ":crash_snapshot",
268        ],
269        "//conditions:default": [],
270    }),
271)
272
273cc_library(
274    name = "work_queue",
275    srcs = [
276        "work_queue.cc",
277    ],
278    hdrs = [
279        "public/pw_system/work_queue.h",
280    ],
281    strip_include_prefix = "public",
282    deps = [
283        ":config",
284        "//pw_work_queue",
285    ],
286)
287
288cc_library(
289    name = "sys_io_target_io",
290    srcs = [
291        "sys_io_target_io.cc",
292    ],
293    strip_include_prefix = "public",
294    deps = [
295        ":io.facade",
296        "//pw_stream",
297        "//pw_stream:sys_io_stream",
298    ],
299)
300
301cc_library(
302    name = "socket_target_io",
303    srcs = [
304        "socket_target_io.cc",
305    ],
306    strip_include_prefix = "public",
307    deps = [
308        ":config",
309        ":io.facade",
310        "//pw_assert",
311        "//pw_stream",
312        "//pw_stream:socket_stream",
313    ],
314)
315
316cc_library(
317    name = "transfer_handlers",
318    srcs = [
319        "transfer_handlers.cc",
320    ],
321    hdrs = [
322        "public/pw_system/transfer_handlers.h",
323    ],
324    strip_include_prefix = "public",
325    deps = [
326        ":config",
327        "//pw_persistent_ram",
328        "//pw_trace_tokenized:config",
329        "//pw_transfer",
330    ],
331)
332
333cc_library(
334    name = "file_manager",
335    srcs = [
336        "file_manager.cc",
337    ],
338    hdrs = [
339        "public/pw_system/file_manager.h",
340    ],
341    strip_include_prefix = "public",
342    deps = [
343        ":config",
344        ":trace_service",
345        ":transfer_handlers",
346        "//pw_file:flat_file_system",
347        "//pw_persistent_ram:flat_file_system_entry",
348    ] + select({
349        "//pw_cpu_exception:enabled": [
350            ":crash_snapshot",
351        ],
352        "//conditions:default": [],
353    }),
354)
355
356cc_library(
357    name = "transfer_service",
358    srcs = [
359        "transfer_service.cc",
360    ],
361    hdrs = [
362        "public/pw_system/transfer_service.h",
363    ],
364    strip_include_prefix = "public",
365    deps = [
366        ":file_manager",
367        "//pw_transfer",
368    ],
369)
370
371cc_library(
372    name = "file_service",
373    srcs = [
374        "file_service.cc",
375    ],
376    hdrs = [
377        "public/pw_system/file_service.h",
378    ],
379    strip_include_prefix = "public",
380    deps = [
381        ":file_manager",
382    ],
383)
384
385cc_library(
386    name = "trace_service",
387    srcs = [
388        "trace_service.cc",
389    ],
390    hdrs = [
391        "public/pw_system/trace_service.h",
392    ],
393    strip_include_prefix = "public",
394    deps = [
395        ":transfer_handlers",
396        "//pw_persistent_ram",
397        "//pw_trace_tokenized:trace_service_pwpb",
398    ],
399)
400
401cc_library(
402    name = "crash_handler",
403    srcs = [
404        "crash_handler.cc",
405    ],
406    hdrs = [
407        "public/pw_system/crash_handler.h",
408    ],
409    strip_include_prefix = "public",
410    deps = [
411        ":crash_snapshot",
412        ":device_handler",
413        ":log",
414        "//pw_assert_trap:message",
415        "//pw_cpu_exception:handler",
416    ],
417)
418
419cc_library(
420    name = "crash_snapshot",
421    srcs = [
422        "crash_snapshot.cc",
423    ],
424    hdrs = [
425        "public/pw_system/crash_snapshot.h",
426    ],
427    strip_include_prefix = "public",
428    deps = [
429        ":device_handler",
430        ":log",
431        ":transfer_handlers",
432        "//pw_cpu_exception:entry",
433        "//pw_multisink:util",
434        "//pw_persistent_ram",
435        "//pw_snapshot:snapshot_proto_pwpb",
436        "//pw_snapshot:uuid",
437    ],
438)
439
440pw_proto_filegroup(
441    name = "device_service_proto_and_options",
442    srcs = ["pw_system_protos/device_service.proto"],
443    options_files = ["pw_system_protos/device_service.options"],
444)
445
446proto_library(
447    name = "device_service_proto",
448    srcs = [":device_service_proto_and_options"],
449    strip_import_prefix = "/pw_system",
450)
451
452pwpb_proto_library(
453    name = "device_service_proto_pwpb",
454    deps = [":device_service_proto"],
455)
456
457pwpb_rpc_proto_library(
458    name = "device_service_pwpb_rpc",
459    pwpb_proto_library_deps = [":device_service_proto_pwpb"],
460    deps = [":device_service_proto"],
461)
462
463py_proto_library(
464    name = "device_service_py_pb2",
465    deps = [":device_service_proto"],
466)
467
468cc_library(
469    name = "device_service_pwpb",
470    srcs = [
471        "device_service_pwpb.cc",
472    ],
473    hdrs = [
474        "public/pw_system/device_service_pwpb.h",
475    ],
476    strip_include_prefix = "public",
477    deps = [
478        ":device_handler",
479        ":device_service_pwpb_rpc",
480    ],
481)
482
483cc_library(
484    name = "device_service",
485    srcs = [
486        "device_service.cc",
487    ],
488    hdrs = [
489        "public/pw_system/device_service.h",
490    ],
491    strip_include_prefix = "public",
492    deps = [
493        ":device_service_pwpb",
494    ],
495)
496
497cc_library(
498    name = "target_hooks",
499    hdrs = [
500        "public/pw_system/target_hooks.h",
501    ],
502    strip_include_prefix = "public",
503    deps = [
504        ":target_hooks_backend",
505        "//pw_thread:thread",
506    ],
507)
508
509label_flag(
510    name = "target_hooks_backend",
511    build_setting_default = ":target_hooks_multiplexer",
512)
513
514# This isn't the best solution, but it's close enough for now. Target hooks are
515# not generically related to an OS, and should be inject-able by downstream
516# projects. For now, assume the pre-baked OS-specific hooks are good enough.
517cc_library(
518    name = "target_hooks_multiplexer",
519    visibility = ["//targets:__pkg__"],
520    deps = select({
521        "//pw_build/constraints/rtos:freertos": [":freertos_target_hooks"],
522        "//conditions:default": [":stl_target_hooks"],
523    }),
524)
525
526cc_library(
527    name = "stl_target_hooks",
528    srcs = [
529        "stl_target_hooks.cc",
530    ],
531    strip_include_prefix = "public",
532    deps = [
533        ":config",
534        "//pw_thread:thread",
535        "//pw_thread_stl:thread",
536    ],
537)
538
539cc_library(
540    name = "freertos_target_hooks",
541    srcs = [
542        "freertos_target_hooks.cc",
543    ],
544    hdrs = [
545        "public/pw_system/target_hooks.h",
546    ],
547    strip_include_prefix = "public",
548    target_compatible_with = [
549        "//pw_build/constraints/rtos:freertos",
550    ],
551    deps = [
552        ":config",
553        "//pw_thread:thread",
554        "//pw_thread_freertos:thread",
555    ],
556)
557
558pw_cc_binary(
559    name = "system_example",
560    # This is marked as testonly because the example app pulls in the RPC unit
561    # test runner. In a real production binary, you wouldn't want to have any
562    # testonly dependencies.
563    testonly = True,
564    srcs = ["example_user_app_init.cc"],
565    # TODO(b/365184562): This target does not build with asan and fuzztest.
566    target_compatible_with = select({
567        "//pw_fuzzer:use_fuzztest": ["@platforms//:incompatible"],
568        "//conditions:default": [],
569    }),
570    deps = [
571        ":pw_system",
572        "//pw_unit_test:rpc_service",
573    ],
574)
575
576cc_library(
577    name = "async",
578    srcs = [
579        "pw_system_private/threads.h",
580        "system.cc",
581        "threads.cc",
582    ],
583    hdrs = ["public/pw_system/system.h"],
584    implementation_deps = [
585        ":async_packet_io",
586        ":device_service",
587        ":file_manager",
588        ":file_service",
589        ":log",
590        ":thread_snapshot_service",
591        ":transfer_service",
592        ":work_queue",
593        "//pw_allocator:best_fit_block_allocator",
594        "//pw_allocator:synchronized_allocator",
595        "//pw_async2:allocate_task",
596        "//pw_async2:pend_func_task",
597        "//pw_hdlc:router",
598        "//pw_multibuf:simple_allocator",
599        "//pw_rpc/pwpb:echo_service",
600        "//pw_sync:interrupt_spin_lock",
601        "//pw_thread:thread",
602    ] + select({
603        "//pw_cpu_exception:enabled": [
604            ":crash_handler",
605            ":crash_snapshot",
606        ],
607        "//conditions:default": [],
608    }),
609    strip_include_prefix = "public",
610    deps = [
611        "//pw_allocator:allocator",
612        "//pw_async2:dispatcher",
613        "//pw_channel",
614        "//pw_rpc",
615    ],
616)
617
618cc_library(
619    name = "async_packet_io",
620    srcs = ["async_packet_io.cc"],
621    hdrs = ["public/pw_system/internal/async_packet_io.h"],
622    implementation_deps = [
623        "//pw_assert",
624        "//pw_log",
625    ],
626    strip_include_prefix = "public",
627    visibility = ["//visibility:private"],
628    deps = [
629        ":config",
630        "//pw_allocator:allocator",
631        "//pw_async2:dispatcher",
632        "//pw_channel",
633        "//pw_channel:forwarding_channel",
634        "//pw_containers:inline_var_len_entry_queue",
635        "//pw_hdlc:router",
636        "//pw_multibuf",
637        "//pw_multibuf:simple_allocator",
638        "//pw_rpc",
639        "//pw_sync:lock_annotations",
640        "//pw_sync:mutex",
641        "//pw_sync:thread_notification",
642        "//pw_thread:thread",
643    ],
644)
645
646pw_cc_test(
647    name = "async_packet_io_test",
648    srcs = ["async_packet_io_test.cc"],
649    deps = [
650        ":async_packet_io",
651        "//pw_allocator:testing",
652        "//pw_channel:loopback_channel",
653        "//pw_multibuf:testing",
654    ],
655)
656
657pw_cc_test(
658    name = "system_async_test",
659    srcs = ["system_async_test.cc"],
660    deps = [
661        ":async",
662        "//pw_allocator:testing",
663        "//pw_channel:loopback_channel",
664        "//pw_multibuf:testing",
665    ],
666)
667
668pw_cc_binary(
669    name = "system_async_host_example",
670    testonly = True,
671    srcs = ["system_async_host_example.cc"],
672    deps = [
673        ":async",
674        "//pw_channel:epoll_channel",
675        "//pw_multibuf:testing",
676    ],
677)
678
679host_device_simulator_binary(
680    name = "system_async_host_simulator_example",
681    testonly = True,
682    binary = ":system_async_host_example",
683)
684
685host_device_simulator_binary(
686    name = "simulator_system_example",
687    testonly = True,
688    binary = ":system_example",
689)
690
691rp2040_binary(
692    name = "rp2040_system_example",
693    testonly = True,
694    binary = ":system_example",
695)
696
697rp2350_binary(
698    name = "rp2350_system_example",
699    testonly = True,
700    binary = ":system_example",
701)
702
703flash_rp2040(
704    name = "flash_rp2040_system_example",
705    testonly = True,
706    rp2040_binary = ":rp2040_system_example",
707)
708
709flash_rp2350(
710    name = "flash_rp2350_system_example",
711    testonly = True,
712    rp2350_binary = ":rp2350_system_example",
713)
714
715# Start :simulator_system_example and connect to it with pw console.
716device_simulator_console(
717    name = "simulator_system_example_console",
718    testonly = True,
719    host_binary = ":simulator_system_example",
720    script = "//pw_system/py:device_sim",
721)
722
723# Conect to a Pico running :system_example over serial with the
724# pw-system-console.
725device_console(
726    name = "rp2040_system_example_console",
727    testonly = True,
728    binary = ":rp2040_system_example",
729    script = "//pw_system/py:pw_system_console",
730)
731
732device_console(
733    name = "rp2350_system_example_console",
734    testonly = True,
735    binary = ":rp2350_system_example",
736    script = "//pw_system/py:pw_system_console",
737)
738
739filegroup(
740    name = "doxygen",
741    srcs = [
742        "public/pw_system/system.h",
743    ],
744)
745