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