diff --git a/MODULE.bazel b/MODULE.bazel index 8b4148ce..febc67d4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -5,7 +5,7 @@ module( bazel_dep(name = "platforms", version = "0.0.9") bazel_dep(name = "bazel_skylib", version = "1.6.1") -bazel_dep(name = "rules_python", version = "0.22.1") +bazel_dep(name = "rules_python", version = "0.36.0") bazel_dep(name = "picotool", version = "2.0.0") bazel_dep(name = "rules_cc", version = "0.0.10") @@ -132,3 +132,19 @@ register_toolchains( # Require users to opt-in to the Pico SDK's toolchains. dev_dependency = True, ) + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + configure_coverage_tool = True, + python_version = "3.9", +) + +use_repo(python, "pythons_hub") +register_toolchains( + "@pythons_hub//:all", + dev_dependency = True, +) +register_toolchains( + "@rules_python//python/runtime_env_toolchains:all", + dev_dependency = True, +) diff --git a/bazel/README.md b/bazel/README.md index 1f3c092b..35b2045c 100644 --- a/bazel/README.md +++ b/bazel/README.md @@ -6,7 +6,7 @@ First, in your `MODULE.bazel` file, add a dependency on the Pico SDK and `rules_cc`: ```python -bazel_dep(name = "pico-sdk", version = "2.0.1") +bazel_dep(name = "pico-sdk", version = "2.1.0") ``` ### Register toolchains @@ -92,11 +92,12 @@ you encounter along the way. Currently, the following features are not supported: +* Pico W wireless libraries work, but may not have complete feature parity with + the CMake build. +* Bazel does not yet provide RISC-V support for Pico 2/RP2350. * The pioasm parser cannot be built from source via Bazel. * Windows MSVC wildcard build (`bazel build //...`) does not work when targeting host. -* Bazel does not yet provide RISC-V support for Pico 2/RP2350. -* Pico W wireless libraries have link issues. ## Contributing When making changes to the Bazel build, please run the Bazel validation script diff --git a/bazel/config/BUILD.bazel b/bazel/config/BUILD.bazel index 2a5066c1..4e622af5 100644 --- a/bazel/config/BUILD.bazel +++ b/bazel/config/BUILD.bazel @@ -151,6 +151,17 @@ string_flag( ], ) +# PICO_BAZEL_CONFIG: PICO_ASYNC_CONTEXT_IMPL, The default implementation for pico_async_context to link, type=string, default=threadsafe_background, group=build +string_flag( + name = "PICO_ASYNC_CONTEXT_IMPL", + build_setting_default = "threadsafe_background", + values = [ + "poll", + "threadsafe_background", + "freertos", + ], +) + # PICO_BAZEL_CONFIG: PICO_BINARY_INFO_ENABLED, Whether to include binary info in final firmware, type=bool, default=1, group=pico_stdlib bool_flag( name = "PICO_BINARY_INFO_ENABLED", @@ -248,6 +259,24 @@ label_flag( build_setting_default = "//bazel:empty_cc_lib", ) +# PICO_BAZEL_CONFIG: PICO_BT_ENABLE_BLE, [Bazel only] Whether or not to link in BLE portions of the btstack as part of //src/rp2_common/pico_btstack. Also defines ENABLE_BLE=1, type=bool, default=False, group=wireless +bool_flag( + name = "PICO_BT_ENABLE_BLE", + build_setting_default = False, +) + +# PICO_BAZEL_CONFIG: PICO_BT_ENABLE_CLASSIC, [Bazel only] Whether or not to link in classic BT portions of the btstack as part of //src/rp2_common/pico_btstack. Also defines ENABLE_CLASSIC=1, type=bool, default=False, group=wireless +bool_flag( + name = "PICO_BT_ENABLE_CLASSIC", + build_setting_default = False, +) + +# PICO_BAZEL_CONFIG: PICO_BT_ENABLE_MESH, [Bazel only] Whether or not to link in mesh BT portions of the btstack as part of //src/rp2_common/pico_btstack. Also defines ENABLE_MESH=1, type=bool, default=False, group=wireless +bool_flag( + name = "PICO_BT_ENABLE_MESH", + build_setting_default = False, +) + # PICO_BAZEL_CONFIG: PICO_LWIP_CONFIG, [Bazel only] The cc_library that provides lwipopts.h, default=//bazel:empty_cc_lib, group=wireless label_flag( name = "PICO_LWIP_CONFIG", diff --git a/bazel/constraint/BUILD.bazel b/bazel/constraint/BUILD.bazel index 05cccb92..a4fe918b 100644 --- a/bazel/constraint/BUILD.bazel +++ b/bazel/constraint/BUILD.bazel @@ -1,3 +1,5 @@ +load("//bazel/util:label_flag_matches.bzl", "label_flag_matches") + package(default_visibility = ["//visibility:public"]) # This constraint represents the dimension that guides the Pico SDK build. This @@ -48,6 +50,11 @@ config_setting( flag_values = {"//bazel/config:PICO_BOARD": "pico_w"}, ) +config_setting( + name = "is_pico2_w", + flag_values = {"//bazel/config:PICO_BOARD": "pico2_w"}, +) + config_setting( name = "pico_toolchain_clang_enabled", flag_values = {"//bazel/config:PICO_TOOLCHAIN": "clang"}, @@ -173,6 +180,21 @@ config_setting( flag_values = {"//bazel/config:PICO_DEFAULT_PRINTF_IMPL": "compiler"}, ) +config_setting( + name = "pico_async_context_poll_enabled", + flag_values = {"//bazel/config:PICO_ASYNC_CONTEXT_IMPL": "poll"}, +) + +config_setting( + name = "pico_async_context_threadsafe_background_enabled", + flag_values = {"//bazel/config:PICO_ASYNC_CONTEXT_IMPL": "threadsafe_background"}, +) + +config_setting( + name = "pico_async_context_freertos_enabled", + flag_values = {"//bazel/config:PICO_ASYNC_CONTEXT_IMPL": "freertos"}, +) + config_setting( name = "pico_use_default_max_page_size_enabled", flag_values = {"//bazel/config:PICO_USE_DEFAULT_MAX_PAGE_SIZE": "True"}, @@ -199,16 +221,34 @@ config_setting( ) config_setting( - name = "pico_btstack_config_unset", - flag_values = {"//bazel/config:PICO_BTSTACK_CONFIG": "//bazel:empty_cc_lib"}, + name = "pico_bt_enable_ble_enabled", + flag_values = {"//bazel/config:PICO_BT_ENABLE_BLE": "True"}, ) config_setting( + name = "pico_bt_enable_classic_enabled", + flag_values = {"//bazel/config:PICO_BT_ENABLE_CLASSIC": "True"}, +) + +config_setting( + name = "pico_bt_enable_mesh_enabled", + flag_values = {"//bazel/config:PICO_BT_ENABLE_MESH": "True"}, +) + +label_flag_matches( name = "pico_lwip_config_unset", - flag_values = {"//bazel/config:PICO_LWIP_CONFIG": "//bazel:empty_cc_lib"}, + flag = "//bazel/config:PICO_LWIP_CONFIG", + value = "//bazel:empty_cc_lib", ) -config_setting( - name = "pico_freertos_unset", - flag_values = {"//bazel/config:PICO_FREERTOS_LIB": "//bazel:empty_cc_lib"}, +label_flag_matches( + name = "pico_btstack_config_unset", + flag = "//bazel/config:PICO_BTSTACK_CONFIG", + value = "//bazel:empty_cc_lib", +) + +label_flag_matches( + name = "pico_freertos_unset", + flag = "//bazel/config:PICO_FREERTOS_LIB", + value = "//bazel:empty_cc_lib", ) diff --git a/bazel/defs.bzl b/bazel/defs.bzl index 0e9df1a2..888f59ce 100644 --- a/bazel/defs.bzl +++ b/bazel/defs.bzl @@ -88,6 +88,7 @@ def compatible_with_pico_w(): return select({ "@pico-sdk//bazel/constraint:cyw43_wireless": [], "@pico-sdk//bazel/constraint:is_pico_w": [], + "@pico-sdk//bazel/constraint:is_pico2_w": [], "//conditions:default": ["@platforms//:incompatible"], }) diff --git a/bazel/pico_btstack_make_gatt_header.bzl b/bazel/pico_btstack_make_gatt_header.bzl new file mode 100644 index 00000000..e9468fbf --- /dev/null +++ b/bazel/pico_btstack_make_gatt_header.bzl @@ -0,0 +1,59 @@ +load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cpp_toolchain", "use_cc_toolchain") + +def _pico_btstack_make_gatt_header_impl(ctx): + cc_toolchain = find_cpp_toolchain(ctx) + feature_configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cc_toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + + out = ctx.actions.declare_file( + "{}_gatt_generated/{}.h".format(ctx.label.name, ctx.file.src.basename.removesuffix(".gatt")), + ) + + ctx.actions.run( + executable = ctx.executable._make_gat_header_tool, + arguments = [ + ctx.file.src.path, + out.path, + "-I", + ctx.file._btstack_hdr.dirname, + ] + [ + + ], + inputs = [ + ctx.file.src, + ctx.file._btstack_hdr, + ], + outputs = [out], + ) + + cc_ctx = cc_common.create_compilation_context( + headers = depset(direct = [out]), + includes = depset(direct = [out.dirname]), + ) + + return [ + DefaultInfo(files = depset(direct = [out])), + CcInfo(compilation_context = cc_ctx) + ] + +pico_btstack_make_gatt_header = rule( + implementation = _pico_btstack_make_gatt_header_impl, + attrs = { + "src": attr.label(mandatory = True, allow_single_file = True), + "_btstack_hdr": attr.label( + default = "@btstack//:src/bluetooth_gatt.h", + allow_single_file = True, + ), + "_make_gat_header_tool": attr.label( + default = "@btstack//:compile_gatt", + cfg = "exec", + executable = True, + ), + }, + fragments = ["cpp"], + toolchains = use_cc_toolchain(), +) diff --git a/bazel/util/label_flag_matches.bzl b/bazel/util/label_flag_matches.bzl new file mode 100644 index 00000000..a8375843 --- /dev/null +++ b/bazel/util/label_flag_matches.bzl @@ -0,0 +1,37 @@ +"""A wrapper that enables a `config_setting` matcher for label_flag flags.""" + +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain") + +def _match_label_flag_impl(ctx): + matches = str(ctx.attr.expected_value.label) == str(ctx.attr.flag.label) + return [ + config_common.FeatureFlagInfo(value = str(matches)), + BuildSettingInfo(value = matches), + ] + +_match_label_flag = rule( + implementation = _match_label_flag_impl, + attrs = { + "expected_value": attr.label( + mandatory = True, + doc = "The expected flag value", + ), + "flag": attr.label( + mandatory = True, + doc = "The flag to extract a value from", + ), + }, +) + +def label_flag_matches(*, name, flag, value): + _match_label_flag( + name = name + "._impl", + expected_value = native.package_relative_label(value), + flag = flag, + ) + + native.config_setting( + name = name, + flag_values = {":{}".format(name + "._impl"): "True"}, + ) diff --git a/bazel/util/transition.bzl b/bazel/util/transition.bzl index 9e07be3c..67f0d616 100644 --- a/bazel/util/transition.bzl +++ b/bazel/util/transition.bzl @@ -1,3 +1,9 @@ +def _normalize_flag_value(val): + """Converts flag values to transition-safe primitives.""" + if type(val) == "label": + return str(val) + return val + def declare_transtion(attrs, flag_overrides = None, append_to_flags = None, executable = True): """A helper that drastically simplifies declaration of a transition. @@ -31,7 +37,7 @@ def declare_transtion(attrs, flag_overrides = None, append_to_flags = None, exec final_overrides = {} if flag_overrides != None: final_overrides = { - key: str(getattr(attrs, value)) + key: _normalize_flag_value(getattr(attrs, value)) for key, value in flag_overrides.items() } if append_to_flags != None: @@ -108,6 +114,8 @@ kitchen_sink_test_binary = declare_transtion( attrs = { "bt_stack_config": attr.label(mandatory = True), "lwip_config": attr.label(mandatory = True), + "enable_ble": attr.bool(default = False), + "enable_bt_classic": attr.bool(default = False), # This could be shared, but we don't in order to make it clearer that # a transition is in use. "_allowlist_function_transition": attr.label( @@ -117,6 +125,8 @@ kitchen_sink_test_binary = declare_transtion( flag_overrides = { "@pico-sdk//bazel/config:PICO_BTSTACK_CONFIG": "bt_stack_config", "@pico-sdk//bazel/config:PICO_LWIP_CONFIG": "lwip_config", + "@pico-sdk//bazel/config:PICO_BT_ENABLE_BLE": "enable_ble", + "@pico-sdk//bazel/config:PICO_BT_ENABLE_CLASSIC": "enable_bt_classic", }, ) diff --git a/src/rp2_common/pico_async_context/BUILD.bazel b/src/rp2_common/pico_async_context/BUILD.bazel index 8d57b52f..a2de0acd 100644 --- a/src/rp2_common/pico_async_context/BUILD.bazel +++ b/src/rp2_common/pico_async_context/BUILD.bazel @@ -2,8 +2,18 @@ load("//bazel:defs.bzl", "compatible_with_rp2", "incompatible_with_config") package(default_visibility = ["//visibility:public"]) -cc_library( +alias( name = "pico_async_context", + actual = select({ + "//bazel/constraint:pico_async_context_poll_enabled": ":pico_async_context_poll", + "//bazel/constraint:pico_async_context_threadsafe_background_enabled": ":pico_async_context_threadsafe_background", + "//bazel/constraint:pico_async_context_freertos_enabled": ":pico_async_context_freertos", + "//conditions:default": "//bazel:incompatible_cc_lib", + }), +) + +cc_library( + name = "pico_async_context_base", srcs = ["async_context_base.c"], hdrs = [ "include/pico/async_context.h", @@ -26,7 +36,7 @@ cc_library( "//bazel/constraint:pico_freertos_unset", ), deps = [ - ":pico_async_context", + ":pico_async_context_base", "//bazel/config:PICO_FREERTOS_LIB", "//src/common/pico_sync", "//src/common/pico_time", @@ -42,7 +52,7 @@ cc_library( includes = ["include"], target_compatible_with = compatible_with_rp2(), deps = [ - ":pico_async_context", + ":pico_async_context_base", "//src/common/pico_sync", "//src/common/pico_time", "//src/rp2_common:pico_platform", @@ -56,7 +66,7 @@ cc_library( includes = ["include"], target_compatible_with = compatible_with_rp2(), deps = [ - ":pico_async_context", + ":pico_async_context_base", "//src/common/pico_sync", "//src/common/pico_time", "//src/rp2_common:pico_platform", diff --git a/src/rp2_common/pico_btstack/BUILD.bazel b/src/rp2_common/pico_btstack/BUILD.bazel index 0f843b47..5d88ad69 100644 --- a/src/rp2_common/pico_btstack/BUILD.bazel +++ b/src/rp2_common/pico_btstack/BUILD.bazel @@ -2,6 +2,28 @@ load("//bazel:defs.bzl", "compatible_with_pico_w", "incompatible_with_config") package(default_visibility = ["//visibility:public"]) +# Prefer using this target to link in all the enabled bt modules, as it will +# link the appropriate libraries and set the appropraite defines based on the +# following flags: +# +# --@pico-sdk//bazel/constraint:PICO_BT_ENABLE_BLE +# --@pico-sdk//bazel/constraint:PICO_BT_ENABLE_CLASSIC +# --@pico-sdk//bazel/constraint:PICO_BT_ENABLE_MESH +cc_library( + name = "pico_btstack", + deps = ["pico_btstack_base"] + select({ + "//bazel/constraint:pico_bt_enable_ble_enabled": [":pico_btstack_ble"], + "//conditions:default": [], + }) + select({ + "//bazel/constraint:pico_bt_enable_classic_enabled": [":pico_btstack_classic"], + "//conditions:default": [], + }) + select({ + "//bazel/constraint:pico_bt_enable_mesh_enabled": [":pico_btstack_mesh"], + "//conditions:default": [], + }), + target_compatible_with = incompatible_with_config("//bazel/constraint:pico_btstack_config_unset"), +) + # Prefer these aliases to directly referencing @btstack, as it's possible that # name may change. alias( @@ -19,9 +41,19 @@ alias( actual = "@btstack//:pico_btstack_classic", ) +alias( + name = "pico_btstack_mesh", + actual = "@btstack//:pico_btstack_mesh", +) + alias( name = "pico_btstack_sbc_encoder", - actual = "@btstack//:pico_btstack_classic", + actual = "@btstack//:pico_btstack_sbc_encoder", +) + +alias( + name = "pico_btstack_sbc_decoder", + actual = "@btstack//:pico_btstack_sbc_decoder", ) alias( @@ -63,11 +95,12 @@ cc_library( cc_library( name = "pico_btstack_stdin", srcs = ["btstack_stdin_pico.c"], - target_compatible_with = incompatible_with_config( - "//bazel/constraint:pico_btstack_config_unset", - ) + compatible_with_pico_w(), + target_compatible_with = compatible_with_pico_w() + incompatible_with_config("//bazel/constraint:pico_btstack_config_unset"), deps = [ + ":pico_btstack_base", + "//bazel/config:PICO_BTSTACK_CONFIG", "//src/rp2_common:pico_platform", "//src/rp2_common/pico_stdio", ], + alwayslink = True, ) diff --git a/src/rp2_common/pico_btstack/btstack.BUILD b/src/rp2_common/pico_btstack/btstack.BUILD index ac009d9e..7ec56537 100644 --- a/src/rp2_common/pico_btstack/btstack.BUILD +++ b/src/rp2_common/pico_btstack/btstack.BUILD @@ -1,7 +1,14 @@ -load("@pico-sdk//bazel:defs.bzl", "incompatible_with_config") +load("@rules_python//python:defs.bzl", "py_binary") +load("@pico-sdk//bazel:defs.bzl", "compatible_with_config", "incompatible_with_config") package(default_visibility = ["//visibility:public"]) +# Expose the gatt header for pico_btstack_make_gatt_header. +exports_files( + ["src/bluetooth_gatt.h"], + visibility = ["@pico-sdk//bazel:__pkg__"], +) + _DISABLE_WARNINGS = [ "-Wno-cast-qual", "-Wno-format", @@ -14,15 +21,44 @@ _DISABLE_WARNINGS = [ "-Wno-unused-parameter", ] +cc_library( + name = "pico_btstack_base_headers", + hdrs = glob(["**/*.h"]), + visibility = ["//visibility:private"], + defines = select({ + "@pico-sdk//bazel/constraint:pico_bt_enable_ble_enabled": ["ENABLE_BLE=1"], + "//conditions:default": [], + }) + select({ + "@pico-sdk//bazel/constraint:pico_bt_enable_mesh_enabled": ["ENABLE_MESH=1"], + "//conditions:default": [], + }) + select({ + "@pico-sdk//bazel/constraint:pico_bt_enable_classic_enabled": ["ENABLE_CLASSIC=1"], + "//conditions:default": [], + }), + includes = [ + ".", + "3rd-party/bluedroid/decoder/include", + "3rd-party/bluedroid/encoder/include", + "3rd-party/md5", + "3rd-party/micro-ecc", + "3rd-party/rijndael", + "3rd-party/segger-rtt", + "3rd-party/yxml", + "platform/embedded", + "src", + ], + deps = [ + "@pico-sdk//bazel/config:PICO_BTSTACK_CONFIG" + ], +) + cc_library( name = "pico_btstack_base", srcs = [ - "3rd-party/md5/md5.c", "3rd-party/micro-ecc/uECC.c", "3rd-party/rijndael/rijndael.c", "3rd-party/segger-rtt/SEGGER_RTT.c", "3rd-party/segger-rtt/SEGGER_RTT_printf.c", - "3rd-party/yxml/yxml.c", "platform/embedded/btstack_tlv_flash_bank.c", "platform/embedded/hci_dump_embedded_stdout.c", "platform/embedded/hci_dump_segger_rtt_stdout.c", @@ -30,6 +66,7 @@ cc_library( "src/btstack_audio.c", "src/btstack_base64_decoder.c", "src/btstack_crypto.c", + "src/btstack_hid.c", "src/btstack_hid_parser.c", "src/btstack_linked_list.c", "src/btstack_memory.c", @@ -48,25 +85,13 @@ cc_library( "src/hci_event.c", "src/l2cap.c", "src/l2cap_signaling.c", - "src/mesh/gatt-service/mesh_provisioning_service_server.c", - "src/mesh/gatt-service/mesh_proxy_service_server.c", + "3rd-party/md5/md5.c", + "3rd-party/yxml/yxml.c", ], - hdrs = glob(["**/*.h"]), copts = _DISABLE_WARNINGS, - includes = [ - ".", - "3rd-party/md5", - "3rd-party/micro-ecc", - "3rd-party/rijndael", - "3rd-party/segger-rtt", - "3rd-party/yxml", - "platform/embedded", - "src", - ], - target_compatible_with = incompatible_with_config( - "@pico-sdk//bazel/constraint:pico_btstack_config_unset", - ), - deps = ["@pico-sdk//bazel/config:PICO_BTSTACK_CONFIG"], + target_compatible_with = incompatible_with_config("@pico-sdk//bazel/constraint:pico_btstack_config_unset"), + deps = [":pico_btstack_base_headers"], + alwayslink = True, ) cc_library( @@ -76,25 +101,27 @@ cc_library( "src/ble/att_db_util.c", "src/ble/att_dispatch.c", "src/ble/att_server.c", - "src/ble/gatt-service/ancs_client.c", - "src/ble/gatt-service/battery_service_client.c", "src/ble/gatt-service/battery_service_server.c", + "src/ble/gatt-service/battery_service_client.c", "src/ble/gatt-service/cycling_power_service_server.c", "src/ble/gatt-service/cycling_speed_and_cadence_service_server.c", - "src/ble/gatt-service/device_information_service_client.c", "src/ble/gatt-service/device_information_service_server.c", + "src/ble/gatt-service/device_information_service_client.c", "src/ble/gatt-service/heart_rate_service_server.c", "src/ble/gatt-service/hids_client.c", "src/ble/gatt-service/hids_device.c", "src/ble/gatt-service/nordic_spp_service_server.c", "src/ble/gatt-service/ublox_spp_service_server.c", + "src/ble/gatt-service/ancs_client.c", "src/ble/gatt_client.c", "src/ble/le_device_db_memory.c", "src/ble/le_device_db_tlv.c", "src/ble/sm.c", ], copts = _DISABLE_WARNINGS, - deps = [":pico_btstack_base"], + target_compatible_with = compatible_with_config("@pico-sdk//bazel/constraint:pico_bt_enable_ble_enabled"), + deps = [":pico_btstack_base_headers"], + alwayslink = True, ) cc_library( @@ -146,12 +173,70 @@ cc_library( "src/classic/spp_server.c", ], copts = _DISABLE_WARNINGS, - deps = [":pico_btstack_base"], + target_compatible_with = compatible_with_config("@pico-sdk//bazel/constraint:pico_bt_enable_classic_enabled"), + deps = [ + ":pico_btstack_base", + ":pico_btstack_base_headers", + ], + alwayslink = True, +) + +cc_library( + name = "pico_btstack_mesh", + srcs = [ + "src/mesh/adv_bearer.c", + "src/mesh/beacon.c", + "src/mesh/gatt_bearer.c", + "src/mesh/gatt-service/mesh_provisioning_service_server.c", + "src/mesh/gatt-service/mesh_proxy_service_server.c", + "src/mesh/mesh.c", + "src/mesh/mesh_access.c", + "src/mesh/mesh_configuration_client.c", + "src/mesh/mesh_configuration_server.c", + "src/mesh/mesh_crypto.c", + "src/mesh/mesh_foundation.c", + "src/mesh/mesh_generic_default_transition_time_client.c", + "src/mesh/mesh_generic_default_transition_time_server.c", + "src/mesh/mesh_generic_level_client.c", + "src/mesh/mesh_generic_level_server.c", + "src/mesh/mesh_generic_on_off_client.c", + "src/mesh/mesh_generic_on_off_server.c", + "src/mesh/mesh_health_server.c", + "src/mesh/mesh_iv_index_seq_number.c", + "src/mesh/mesh_keys.c", + "src/mesh/mesh_lower_transport.c", + "src/mesh/mesh_network.c", + "src/mesh/mesh_node.c", + "src/mesh/mesh_peer.c", + "src/mesh/mesh_proxy.c", + "src/mesh/mesh_upper_transport.c", + "src/mesh/mesh_virtual_addresses.c", + "src/mesh/pb_adv.c", + "src/mesh/pb_gatt.c", + "src/mesh/provisioning.c", + "src/mesh/provisioning_device.c", + "src/mesh/provisioning_provisioner.c", + ], + copts = _DISABLE_WARNINGS, + target_compatible_with = compatible_with_config("@pico-sdk//bazel/constraint:pico_bt_enable_mesh_enabled"), + deps = [ + ":pico_btstack_base_headers", + ":pico_btstack_ble", + ], + alwayslink = True, +) + +cc_library( + name = "pico_btstack_sbc_common", + srcs = ["src/classic/btstack_sbc_bluedroid.c"], + deps = [":pico_btstack_base_headers"], + target_compatible_with = incompatible_with_config("@pico-sdk//bazel/constraint:pico_btstack_config_unset"), ) cc_library( name = "pico_btstack_sbc_encoder", srcs = [ + "src/classic/btstack_sbc_encoder_bluedroid.c", "3rd-party/bluedroid/encoder/srce/sbc_analysis.c", "3rd-party/bluedroid/encoder/srce/sbc_dct.c", "3rd-party/bluedroid/encoder/srce/sbc_dct_coeffs.c", @@ -160,11 +245,43 @@ cc_library( "3rd-party/bluedroid/encoder/srce/sbc_enc_coeffs.c", "3rd-party/bluedroid/encoder/srce/sbc_encoder.c", "3rd-party/bluedroid/encoder/srce/sbc_packing.c", - "src/classic/btstack_sbc_encoder_bluedroid.c", ], copts = _DISABLE_WARNINGS, includes = ["3rd-party/bluedroid/decoder/include"], - deps = [":pico_btstack_base"], + deps = [ + ":pico_btstack_base_headers", + ":pico_btstack_sbc_common", + ], + alwayslink = True, +) + +cc_library( + name = "pico_btstack_sbc_decoder", + srcs = [ + "src/classic/btstack_sbc_decoder_bluedroid.c", + "3rd-party/bluedroid/decoder/srce/readsamplesjoint.inc", + "3rd-party/bluedroid/decoder/srce/alloc.c", + "3rd-party/bluedroid/decoder/srce/bitalloc.c", + "3rd-party/bluedroid/decoder/srce/bitalloc-sbc.c", + "3rd-party/bluedroid/decoder/srce/bitstream-decode.c", + "3rd-party/bluedroid/decoder/srce/decoder-oina.c", + "3rd-party/bluedroid/decoder/srce/decoder-private.c", + "3rd-party/bluedroid/decoder/srce/decoder-sbc.c", + "3rd-party/bluedroid/decoder/srce/dequant.c", + "3rd-party/bluedroid/decoder/srce/framing.c", + "3rd-party/bluedroid/decoder/srce/framing-sbc.c", + "3rd-party/bluedroid/decoder/srce/oi_codec_version.c", + "3rd-party/bluedroid/decoder/srce/synthesis-sbc.c", + "3rd-party/bluedroid/decoder/srce/synthesis-dct8.c", + "3rd-party/bluedroid/decoder/srce/synthesis-8-generated.c", + ], + copts = _DISABLE_WARNINGS, + includes = ["3rd-party/bluedroid/decoder/include"], + deps = [ + ":pico_btstack_base_headers", + ":pico_btstack_sbc_common", + ], + alwayslink = True, ) cc_library( @@ -175,7 +292,10 @@ cc_library( ], copts = _DISABLE_WARNINGS, includes = ["platform/lwip"], - deps = [":pico_btstack_base"], + deps = [ + ":pico_btstack_base_headers", + "@pico-sdk//src/rp2_common/pico_lwip:pico_lwip_nosys", + ], ) cc_library( @@ -193,5 +313,17 @@ cc_library( "platform/freertos", "platform/lwip", ], - deps = [":pico_btstack_base"], + deps = [ + ":pico_btstack_base_headers", + "@pico-sdk//src/rp2_common/pico_lwip:pico_lwip_freertos", + ], +) + +py_binary( + name = "compile_gatt", + srcs = [ + "tool/compile_gatt.py", + ], + # TODO: Add pip pins. + # deps = ["@python_packages//pycryptodomex"] ) diff --git a/src/rp2_common/pico_cyw43_arch/BUILD.bazel b/src/rp2_common/pico_cyw43_arch/BUILD.bazel index 6484bf5b..286184e7 100644 --- a/src/rp2_common/pico_cyw43_arch/BUILD.bazel +++ b/src/rp2_common/pico_cyw43_arch/BUILD.bazel @@ -2,6 +2,36 @@ load("//bazel:defs.bzl", "compatible_with_pico_w", "incompatible_with_config") package(default_visibility = ["//visibility:public"]) +alias( + name = "pico_cyw43_arch", + actual = select({ + "//bazel/constraint:pico_lwip_config_unset": ":select_no_lwip", + "//conditions:default": ":select_lwip", + }) +) + +alias( + name = "select_lwip", + actual = select({ + "//bazel/constraint:pico_async_context_poll_enabled": ":pico_cyw43_arch_lwip_poll", + "//bazel/constraint:pico_async_context_threadsafe_background_enabled": ":pico_cyw43_arch_lwip_threadsafe_background", + "//bazel/constraint:pico_async_context_freertos_enabled": ":pico_cyw43_arch_lwip_freertos", + "//conditions:default": "//bazel:incompatible_cc_lib", + }), + visibility = ["//visibility:private"], +) + +alias( + name = "select_no_lwip", + actual = select({ + "//bazel/constraint:pico_async_context_poll_enabled": ":pico_cyw43_arch_poll", + "//bazel/constraint:pico_async_context_threadsafe_background_enabled": ":pico_cyw43_arch_threadsafe_background", + "//bazel/constraint:pico_async_context_freertos_enabled": ":pico_cyw43_arch_freertos", + "//conditions:default": "//bazel:incompatible_cc_lib", + }), + visibility = ["//visibility:private"], +) + # Tuple is async_context type and whether or not lwip is enabled. _CONFIGURATIONS = [ ("freertos", False), @@ -13,8 +43,8 @@ _CONFIGURATIONS = [ ] # This produces the following labels: -# pico_cyw43_arch_sys_freertos -# pico_cyw43_arch_lwip_sys_freertos +# pico_cyw43_arch_freertos +# pico_cyw43_arch_lwip_freertos # pico_cyw43_arch_poll # pico_cyw43_arch_lwip_poll # pico_cyw43_arch_threadsafe_background @@ -36,20 +66,24 @@ _CONFIGURATIONS = [ defines = [ "LIB_PICO_CYW43_ARCH=1", "PICO_CYW43_ARCH_{}=1".format(kind.upper()), - "CYW43_LWIP={}".format(1 if use_lwip else 0), ], includes = ["include"], target_compatible_with = compatible_with_pico_w() + ( incompatible_with_config("//bazel/constraint:pico_freertos_unset") if kind == "freertos" else [] + ) + ( + incompatible_with_config("//bazel/constraint:pico_lwip_config_unset") if use_lwip else [] ), deps = [ "//src/rp2_common:pico_platform", "//src/rp2_common/pico_async_context:pico_async_context_{}".format(kind), "//src/rp2_common/pico_cyw43_driver", - "//src/rp2_common/pico_lwip", "//src/rp2_common/pico_unique_id", ] + ( - ["//src/rp2_common/pico_lwip:pico_lwip_freertos"] if kind == "freertos" else ["//src/rp2_common/pico_lwip:pico_lwip_nosys"] + ["//src/rp2_common/pico_lwip:pico_lwip_freertos"] if kind == "freertos" and use_lwip else [] + ) + ( + ["//src/rp2_common/pico_lwip:pico_lwip_nosys"] if kind != "freertos" and use_lwip else [] + ) + ( + ["//src/rp2_common/pico_lwip"] if use_lwip else [] ), ) for kind, use_lwip in _CONFIGURATIONS diff --git a/src/rp2_common/pico_cyw43_driver/BUILD.bazel b/src/rp2_common/pico_cyw43_driver/BUILD.bazel index 965a0b28..23bec36a 100644 --- a/src/rp2_common/pico_cyw43_driver/BUILD.bazel +++ b/src/rp2_common/pico_cyw43_driver/BUILD.bazel @@ -27,6 +27,7 @@ cc_library( deps = [ ":cyw43_bus_pio", ":cyw43_configport", + ":pico_btstack_cyw43", "//src/rp2_common:pico_platform", "//src/rp2_common/hardware_clocks", "//src/rp2_common/hardware_dma", @@ -36,21 +37,25 @@ cc_library( "//src/rp2_common/pico_async_context", "//src/rp2_common/pico_unique_id", "@cyw43-driver//:cyw43_driver", - ] + - # Only depend on the btstack if its configuration is set up. - select({ + ] + select({ "//bazel/constraint:pico_btstack_config_unset": [], - "//conditions:default": [":pico_cyw43_btstack"], + "//conditions:default": [ + "//src/rp2_common/pico_btstack:pico_btstack", + ], }), + alwayslink = True, ) cc_library( - name = "pico_cyw43_btstack", - srcs = [ - "btstack_chipset_cyw43.c", - "btstack_cyw43.c", - "btstack_hci_transport_cyw43.c", - ], + name = "pico_btstack_cyw43", + srcs = select({ + "//bazel/constraint:pico_btstack_config_unset": [], + "//conditions:default": [ + "btstack_cyw43.c", + "btstack_chipset_cyw43.c", + "btstack_hci_transport_cyw43.c", + ], + }), hdrs = [ "include/pico/btstack_chipset_cyw43.h", "include/pico/btstack_cyw43.h", @@ -60,13 +65,18 @@ cc_library( deps = [ ":cyw43_bus_pio", ":cyw43_configport", - "//bazel/config:PICO_BTSTACK_CONFIG", - "//src/rp2_common/pico_btstack:btstack_run_loop_async_context", - "//src/rp2_common/pico_btstack:pico_btstack_base", - "//src/rp2_common/pico_btstack:pico_btstack_flash_bank", - "//src/rp2_common/pico_cyw43_driver/cybt_shared_bus:cybt_shared_bus_driver", "@cyw43-driver//:cyw43_driver", - ], + ] + select({ + "//bazel/constraint:pico_btstack_config_unset": [], + "//conditions:default": [ + "//bazel/config:PICO_BTSTACK_CONFIG", + "//src/rp2_common/pico_cyw43_driver/cybt_shared_bus:cybt_shared_bus_driver", + "//src/rp2_common/pico_btstack:btstack_run_loop_async_context", + "//src/rp2_common/pico_btstack:pico_btstack", + "//src/rp2_common/pico_btstack:pico_btstack_flash_bank", + ], + }), + alwayslink = True, ) pico_generate_pio_header( diff --git a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel index a1e24b0d..24e53b3f 100644 --- a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel +++ b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel @@ -11,4 +11,5 @@ cc_library( deps = [ "@cyw43-driver//:cyw43_driver", ], + alwayslink = True, ) diff --git a/src/rp2_common/pico_cyw43_driver/cyw43-driver.BUILD b/src/rp2_common/pico_cyw43_driver/cyw43-driver.BUILD index 58148d86..582faa6d 100644 --- a/src/rp2_common/pico_cyw43_driver/cyw43-driver.BUILD +++ b/src/rp2_common/pico_cyw43_driver/cyw43-driver.BUILD @@ -12,6 +12,13 @@ cc_library( ], hdrs = glob(["**/*.h"]), defines = select({ + "@pico-sdk//bazel/constraint:pico_lwip_config_unset": [ + "CYW43_LWIP=0", + ], + "//conditions:default": [ + "CYW43_LWIP=1", + ], + })+ select({ "@pico-sdk//bazel/constraint:pico_btstack_config_unset": [ "CYW43_ENABLE_BLUETOOTH=0", ], @@ -26,6 +33,10 @@ cc_library( target_compatible_with = compatible_with_pico_w(), deps = [ "@pico-sdk//src/rp2_common/pico_cyw43_driver:cyw43_configport", - "@pico-sdk//src/rp2_common/pico_lwip", - ], + ] + select({ + "@pico-sdk//bazel/constraint:pico_lwip_config_unset": [], + "//conditions:default": [ + "@pico-sdk//src/rp2_common/pico_lwip", + ], + }), ) diff --git a/src/rp2_common/pico_lwip/BUILD.bazel b/src/rp2_common/pico_lwip/BUILD.bazel index 5c98e541..c98ff92a 100644 --- a/src/rp2_common/pico_lwip/BUILD.bazel +++ b/src/rp2_common/pico_lwip/BUILD.bazel @@ -25,11 +25,13 @@ cc_library( "//src/rp2_common/pico_async_context", "//src/rp2_common/pico_rand", ], + alwayslink = True, ) cc_library( name = "pico_lwip_nosys", srcs = ["lwip_nosys.c"], + includes = ["include"], hdrs = ["include/pico/lwip_nosys.h"], target_compatible_with = compatible_with_pico_w(), deps = [ @@ -39,6 +41,7 @@ cc_library( "//src/rp2_common/pico_async_context", "//src/rp2_common/pico_rand", ], + alwayslink = True, ) # Prefer these aliases to directly referencing @lwip, as it's possible that diff --git a/src/rp2_common/pico_lwip/lwip.BUILD b/src/rp2_common/pico_lwip/lwip.BUILD index 39b7ed2d..c94b881c 100644 --- a/src/rp2_common/pico_lwip/lwip.BUILD +++ b/src/rp2_common/pico_lwip/lwip.BUILD @@ -1,4 +1,4 @@ -load("@pico-sdk//bazel:defs.bzl", "incompatible_with_config") +load("@pico-sdk//bazel:defs.bzl", "incompatible_with_config", "compatible_with_config") package(default_visibility = ["//visibility:public"]) @@ -11,9 +11,10 @@ cc_library( "contrib/ports/freertos/include/arch", "src/include", ], - visibility = ["//visibility:private"], + visibility = [ + "@pico-sdk//src/rp2_common/pico_lwip:__pkg__", + ], deps = [ - "@pico-sdk//bazel/config:PICO_LWIP_CONFIG", "@pico-sdk//src/rp2_common/pico_lwip:pico_lwip_config", ], ) @@ -21,29 +22,25 @@ cc_library( cc_library( name = "pico_lwip_core", srcs = glob(["src/core/*.c"]), - target_compatible_with = incompatible_with_config( - "@pico-sdk//bazel/constraint:pico_lwip_config_unset", - ), deps = [ ":pico_lwip_headers", - ] + select({ - "@pico-sdk//bazel/constraint:pico_freertos_unset": [], - "//conditions:default": [ - ":pico_lwip_contrib_freertos", - ], - }), + "@pico-sdk//bazel/config:PICO_LWIP_CONFIG", + ], + target_compatible_with = incompatible_with_config("@pico-sdk//bazel/constraint:pico_lwip_config_unset") ) cc_library( name = "pico_lwip_core4", srcs = glob(["src/core/ipv4/*.c"]), deps = [":pico_lwip_core"], + alwayslink = True, ) cc_library( name = "pico_lwip_core6", srcs = glob(["src/core/ipv6/*.c"]), deps = [":pico_lwip_core"], + alwayslink = True, ) cc_library( diff --git a/test/kitchen_sink/BUILD.bazel b/test/kitchen_sink/BUILD.bazel index 9ecbe23e..1bd595c3 100644 --- a/test/kitchen_sink/BUILD.bazel +++ b/test/kitchen_sink/BUILD.bazel @@ -6,10 +6,6 @@ package(default_visibility = ["//visibility:public"]) cc_library( name = "btstack_config", hdrs = ["btstack_config.h"], - defines = [ - "ENABLE_CLASSIC=1", - "ENABLE_BLE=1", - ], includes = ["."], ) @@ -113,6 +109,7 @@ cc_binary( deps = [ ":kitchen_sink_common", "//src/rp2_common/pico_cyw43_arch:pico_cyw43_arch_lwip_poll", + "//src/rp2_common/pico_btstack:pico_btstack", ], ) @@ -133,6 +130,8 @@ kitchen_sink_test_binary( src = ":kitchen_sink_lwip_poll_actual", bt_stack_config = ":btstack_config", lwip_config = ":lwip_config", + enable_ble = True, + enable_bt_classic = True, target_compatible_with = compatible_with_rp2(), ) @@ -142,5 +141,7 @@ kitchen_sink_test_binary( src = ":kitchen_sink_lwip_background_actual", bt_stack_config = ":btstack_config", lwip_config = ":lwip_config", + enable_ble = True, + enable_bt_classic = True, target_compatible_with = compatible_with_rp2(), ) diff --git a/test/kitchen_sink/CMakeLists.txt b/test/kitchen_sink/CMakeLists.txt index aaa3d31b..afc77e55 100644 --- a/test/kitchen_sink/CMakeLists.txt +++ b/test/kitchen_sink/CMakeLists.txt @@ -180,7 +180,7 @@ if (TARGET pico_cyw43_arch) target_link_libraries(kitchen_sink_lwip_poll pico_btstack_ble pico_btstack_classic pico_btstack_cyw43) endif() - # for lwipopts.h + # for lwipopts.h and btstack_config.h. target_include_directories(kitchen_sink_lwip_poll PRIVATE ${CMAKE_CURRENT_LIST_DIR}) diff --git a/tools/bazel_build.py b/tools/bazel_build.py index 546eb7d9..522f2831 100755 --- a/tools/bazel_build.py +++ b/tools/bazel_build.py @@ -145,6 +145,22 @@ BUILD_CONFIGURATIONS = ( ) ), }, + { + "name": "Pico 2 W", + "args": ( + "--platforms=//bazel/platform:rp2350", + "--@pico-sdk//bazel/config:PICO_BOARD=pico2_w", + ), + "extra_targets": (), + "exclusions": frozenset( + ( + # Host only. + "//test/pico_float_test:hazard3_test_gen", + # No RISC-V on RP2040. + "//test/pico_float_test:pico_float_test_hazard3", + ) + ), + }, ) diff --git a/tools/compare_build_systems.py b/tools/compare_build_systems.py index d2426778..badeadee 100755 --- a/tools/compare_build_systems.py +++ b/tools/compare_build_systems.py @@ -147,9 +147,16 @@ BAZEL_ONLY_ALLOWLIST = ( "PICO_DEFAULT_PRINTF_IMPL", "PICO_DEFAULT_RAND_IMPL", "PICO_BINARY_INFO_ENABLED", + "PICO_ASYNC_CONTEXT_IMPL", # Allows selection of clang/gcc when using the dynamically fetched # toolchains. "PICO_TOOLCHAIN", + # In CMake, linking these libraries also sets defines for adjacent + # libraries. That's an antipattern in Bazel, so there's flags to control + # which modules to enable instead. + "PICO_BT_ENABLE_BLE", + "PICO_BT_ENABLE_CLASSIC", + "PICO_BT_ENABLE_MESH", )