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