Skip to content

Initial Pico/2 W Bazel support #2049

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down Expand Up @@ -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,
)
7 changes: 4 additions & 3 deletions bazel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions bazel/config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
50 changes: 45 additions & 5 deletions bazel/constraint/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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"},
Expand Down Expand Up @@ -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"},
Expand All @@ -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_lwip_config_unset",
flag_values = {"//bazel/config:PICO_LWIP_CONFIG": "//bazel:empty_cc_lib"},
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 = "//bazel/config:PICO_LWIP_CONFIG",
value = "//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_values = {"//bazel/config:PICO_FREERTOS_LIB": "//bazel:empty_cc_lib"},
flag = "//bazel/config:PICO_FREERTOS_LIB",
value = "//bazel:empty_cc_lib",
)
1 change: 1 addition & 0 deletions bazel/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
})

Expand Down
59 changes: 59 additions & 0 deletions bazel/pico_btstack_make_gatt_header.bzl
Original file line number Diff line number Diff line change
@@ -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(),
)
37 changes: 37 additions & 0 deletions bazel/util/label_flag_matches.bzl
Original file line number Diff line number Diff line change
@@ -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"},
)
12 changes: 11 additions & 1 deletion bazel/util/transition.bzl
Original file line number Diff line number Diff line change
@@ -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.

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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(
Expand All @@ -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",
},
)

Expand Down
18 changes: 14 additions & 4 deletions src/rp2_common/pico_async_context/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand Down
Loading