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