Skip to content
Snippets Groups Projects
Unverified Commit 6ff3e4fa authored by armandomontanez's avatar armandomontanez Committed by GitHub
Browse files

Expand bazel build to include configuration options and broader support. (#1731)

* Add host Bazel build

Updates target_compatible_with across the repo to ensure that wildcard
builds for both host and rp2040 succeed.

* Get unit tests building

* Add Python script to identify build system differences

Uses the build system tags to make it easier to identify differences
between the CMake and Bazel builds.

* Temporarily disable pico divider test

* Support PICO_BARE_METAL in Bazel

* Support PICO_NO_GC_SECTIONS in Bazel

* Support boot2 configuration in Bazel

Adds support for PICO_DEFAULT_BOOT_STAGE2 and
PICO_DEFAULT_BOOT_STAGE2_FILE in the Bazel build.

* Allowlist some CMake-only options

* Support CXX configuration options in Bazel

* Move multiple_choice_flag.bzl

* Support all pico boards

* Support linking multiple stdio implementations

Changes the Bazel build so stdio implementations are no longer mutually
exclusive.

* Add PICO_BOOT_STAGE2_LINK_IMAGE

* Support PICO_CMSIS_PATH in Bazel

* Support PICO_USE_DEFAULT_MAX_PAGE_SIZE in Bazel

* Silence PICO_CMSIS_VENDOR and PICO_CMSIS_DEVICE differences

* Support PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS in Bazel

* Properly support version defines

* Support embedding binary info in Bazel

* Embed build type in binary

* Support different linker scripts in Bazel build

* Finish out missing PICO_BUILD_DEFINE in Bazel build

* Support PICO_NO_TARGET_NAME

* Reorganize initial configuration options in Bazel

Cleans up and reorganizes some of the initial configuration options
added to the Bazel build so everything is consistent.

* Add builds for pioasm and elf2uf2

* Use Python rules from rules_python

* Actually link in output formats in pioasm tool

* Make tools have public visibility

* Add UF2 Bazel aspect

* Add TODOs for pioasm/uf2 helpers

* Fix compile flag typo

* Update Bazel SDK configuration strings to match recent CMake changes

* Fix pico_divider test

* Clean up straggling TODOs

* Clarify pico_stdio_test compatibility

* Initial Bazel Pico W support

* Add new files from develop

* Clean up compatibility expressions in Bazel build

* Clean up rp2 constraint handling in Bazel

* More Bazel docs cleanup

* Format Bazel build files

* Consolidate transitions in the Pico SDK

* Make every _allowlist_function_transition explicit

* More docs cleanup

* Add a few missing defines

* Improve PICO_CONFIG_HEADER correctness in Bazel

* Minor docs clarifications
parent 0dc17e51
No related branches found
No related tags found
No related merge requests found
Showing
with 929 additions and 302 deletions
......@@ -8,7 +8,7 @@ bazel_dep(name = "bazel_skylib", version = "1.6.1")
# module will not ensure that the root Bazel module has that same version of
# rules_cc. For that reason, this primarily acts as a FYI. You'll still need
# to explicitly list this dependency in your own project's MODULE.bazel file.
bazel_dep(name = "rules_cc", version = "0.0.10")
bazel_dep(name = "rules_cc", version = "0.0.9")
# rules_cc v0.0.10 is not yet cut, so manually pull in the desired version.
# This does not apply to dependent projects, so it needs to be copied to your
......@@ -63,6 +63,33 @@ http_archive(
sha256 = "ac57109bba00d26ffa33312d5f334990ec9a9a4d82bf890ed8b825b4610d1da2",
)
# TODO: Provide btstack as a proper Bazel module.
http_archive(
name = "btstack",
url = "https://github.com/bluekitchen/btstack/archive/72ef1732c954d938091467961e41f4aa9b976b34.zip",
strip_prefix = "btstack-72ef1732c954d938091467961e41f4aa9b976b34",
build_file = "//src/rp2_common/pico_btstack:btstack.BUILD",
sha256 = "f45d72b5d404dd2f8e311287de6f2ba3561fc8ae956737eeb611b277aadc2391",
)
# TODO: Provide btstack as a proper Bazel module.
http_archive(
name = "cyw43-driver",
url = "https://github.com/georgerobotics/cyw43-driver/archive/8ef38a6d32c54f850bff8f189bdca19ded33792a.zip",
strip_prefix = "cyw43-driver-8ef38a6d32c54f850bff8f189bdca19ded33792a",
build_file = "//src/rp2_common/pico_cyw43_driver:cyw43-driver.BUILD",
sha256 = "0b44a19ea58537ee954357606cde5ed20c3a42be77adfebb07b7c0e4740f6228",
)
# TODO: Provide lwip as a proper Bazel module.
http_archive(
name = "lwip",
url = "https://github.com/lwip-tcpip/lwip/archive/239918ccc173cb2c2a62f41a40fd893f57faf1d6.zip",
strip_prefix = "lwip-239918ccc173cb2c2a62f41a40fd893f57faf1d6",
build_file = "//src/rp2_common/pico_lwip:lwip.BUILD",
sha256 = "7ee9e02f2719c0422377e1fcce5a21716ca2e2e855cca56695f9ef7cb020e5dd",
)
register_toolchains(
"//bazel/toolchain:arm_gcc_linux-x86_64",
"//bazel/toolchain:arm_gcc_win-x86_64",
......
load("@rules_python//python:defs.bzl", "py_binary")
package(default_visibility = ["//visibility:public"])
py_binary(
......@@ -18,17 +20,38 @@ py_binary(
# configuring these `label_flag`s:
#
# # Specify the library that provides "pico_config_extra_headers.h"
# --@pico-sdk//bazel/config:pico_config_extra_headers=//my_proj:my_custom_headers
# --@pico-sdk//bazel/config:PICO_CONFIG_EXTRA_HEADER=//my_proj:my_custom_headers
#
# # Specify the library that provides "pico_config_platform_headers.h"
# --@pico-sdk//bazel/config:pico_config_platform_headers=//my_proj:my_custom_platform_headers
# --@pico-sdk//bazel/config:PICO_CONFIG_PLATFORM_HEADER=//my_proj:my_custom_platform_headers
cc_library(
name = "generate_config_header",
hdrs = ["include/pico/config_autogen.h"],
includes = ["include"],
visibility = ["//:__subpackages__"],
deps = [
"//bazel/config:pico_config_extra_headers",
"//bazel/config:pico_config_platform_headers",
"//bazel/config:PICO_CONFIG_EXTRA_HEADER",
"//bazel/config:PICO_CONFIG_PLATFORM_HEADER",
],
)
genrule(
name = "empty_extra_headers_file",
outs = ["generated_extra_include/pico_config_extra_headers.h"],
cmd = "echo > $@",
cmd_bat = "copy NUL $@",
visibility = ["//visibility:private"],
)
cc_library(
name = "no_extra_headers",
hdrs = ["generated_extra_include/pico_config_extra_headers.h"],
includes = ["generated_extra_include"],
visibility = ["//visibility:private"],
)
# An empty stub, useful for label_flag flags that need to point to a library,
# but for some purposes the library needs to be a no-op.
cc_library(
name = "empty_cc_lib",
)
# Bazel build
The Bazel build for the Pico SDK is currently community-maintained, and should
be considered an experimental work-in-progress. There are missing features,
and you may encounter significant breakages with future versions.
You are welcome and encouraged to file issues for any problems you encounter
along the way.
## Using the Pico SDK in a Bazel project.
......@@ -23,7 +17,7 @@ Second, in the same file you'll need to add an explicit dependency on
# module will not ensure that the root Bazel module has that same version of
# rules_cc. For that reason, this primarily acts as a FYI. You'll still need
# to explicitly list this dependency in your own project's MODULE.bazel file.
bazel_dep(name = "rules_cc", version = "0.0.10")
bazel_dep(name = "rules_cc", version = "0.0.9")
# rules_cc v0.0.10 is not yet cut, so manually pull in the desired version.
# This does not apply to dependent projects, so it needs to be copied to your
......@@ -65,45 +59,33 @@ Raspberry Pi Pico:
$ bazelisk build --platforms=@pico-sdk//bazel/platform:rp2040 //...
```
## SDK configuration [experimental]
These configuration options are a work in progress and may see significant
breaking changes in future versions.
## SDK configuration
An exhaustive list of build system configuration options is available in
`//bazel/config:BUILD.bazel`.
### Selecting a different board
Currently there are three configurable flags for targeting a different board:
1. `pico_config_extra_headers`: This should always point to a `cc_library `that
provides a `"pico_config_extra_headers.h"` header. You can configure this
by including a flag like the following in your build invocation:
```
--@pico-sdk//bazel/config:pico_config_extra_headers=//path/to:custom_extra_headers
```
2. `pico_config_platform_headers`: This should always point to a `cc_library`
that provides a `"pico_config_platform_headers.h"` header.
```
--@pico-sdk//bazel/config:pico_config_platform_headers=//path/to:custom_platform_headers
```
3. `pico_config_header`: This should point to a `cc_library` that sets all
necessary SDK defines. Most notably, `PICO_BOARD`, `PICO_CONFIG_HEADER`,
`PICO_ON_DEVICE`, `PICO_NO_HARDWARE`, and `PICO_BUILD`. See
`//src/boards:BUILD.bazel` for working examples. Any `defines` set on this
library will propagate to the rest of the Pico SDK. To set this configuration
option, pass a flag like the following in your Bazel build invocation:
```
--@pico-sdk//bazel/config:pico_config_platform_headers=//path/to:pico_board_config
A different board can be selected specifying `--@pico-sdk//bazel/config:PICO_BOARD`:
```console
$ bazelisk build --platforms=//bazel/platform:rp2040 --@pico-sdk//bazel/config:PICO_BOARD=pico_w //...
```
### Selecting a stdio mode
To select a different stdio mode, add it to your `platform` definition. For
example:
```python
platform(
name = "rp2040",
constraint_values = [
"@pico-sdk//bazel/constraint:rp2040",
"@pico-sdk//bazel/constraint:stdio_usb", # Configures stdio_mode.
"@platforms//cpu:armv6-m",
],
)
If you have a bespoke board definition, you can configure the Pico SDK to use it
by pointing `--@pico-sdk//bazel/config:PICO_CONFIG_HEADER` to a `cc_library`
that defines `PICO_BOARD` and either a `PICO_CONFIG_HEADER` define or a
`pico/config_autogen.h` header. Make sure any required `includes`, `hdrs`, and
`deps` are also provided.
## Generating UF2 firmware images
Creation of UF2 images can be done as explicit build steps on a per-binary
rule basis, or through an aspect. Running a wildcard build with the
`pico_uf2_aspect` enabled is the easiest way to create a UF2 for every ELF
firmware image.
```console
$ bazel build --platforms=@pico-sdk//bazel/platform:rp2040 \
--aspects @pico-sdk//tools:uf2_aspect.bzl%pico_uf2_aspect \
--output_groups=+pico_uf2_files \
//...
```
## Building the Pico SDK itself
......@@ -121,17 +103,14 @@ To build all of the Pico SDK, run the following command:
$ bazelisk build --platforms=//bazel/platform:rp2040 //...
```
**Note:** Since the Bazel build does not yet have any `cc_binary` rules with a
`main()` function, there won't be any binaries to flash on your board. For now,
this only builds the SDK as a collection of libraries.
## Known issues and limitations
The Bazel build is currently experimental and incomplete. At this time, only the
stock Pi Pico board is supported, and the only configuration options are
changing the STDIO mode between UART and USB serial.
Keep in mind the following limitations:
* Pico-W is not yet supported.
* Selecting an alternative board is not yet supported.
* Nearly all preexisting CMake configuration options are not yet supported.
* Targeting the host build of the Pico SDK is not yet supported.
The Bazel build for the Pico SDK is relatively new, but most features and
configuration options available in the CMake build are also available in Bazel.
You are welcome and encouraged to file issues for any problems and limitations
you encounter along the way.
Currently, the following features are not supported:
* "None" variants of pico_double, pico_float, and pico_printf are not yet
supported.
* The pioasm parser cannot be built from source via Bazel.
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "int_flag", "string_flag")
package(default_visibility = ["//visibility:public"])
# This should always point to a cc_library that provides
# a "pico_config_extra_headers.h".
# PICO_BAZEL_CONFIG: PICO_BOARD, The board name being built for, type=string, default=pico, group=build
string_flag(
name = "PICO_BOARD",
build_setting_default = "pico",
)
# PICO_BAZEL_CONFIG: PICO_BARE_METAL, Flag to exclude anything except base headers from the build, type=bool, default=0, group=build
bool_flag(
name = "PICO_BARE_METAL",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_NO_GC_SECTIONS, Disable -ffunction-sections -fdata-sections and --gc-sections, type=bool, default=0, advanced=true, group=pico_standard_link
bool_flag(
name = "PICO_NO_GC_SECTIONS",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_DEFAULT_BOOT_STAGE2_FILE, Boot stage 2 file to use; this should point to a filegroup with the .S file to use, type=string, group=build
label_flag(
name = "PICO_DEFAULT_BOOT_STAGE2_FILE",
build_setting_default = "//src/rp2_common/boot_stage2:build_selected_boot2",
)
# PICO_BAZEL_CONFIG: PICO_DEFAULT_BOOT_STAGE2, Simpler alternative to specifying PICO_DEFAULT_BOOT_STAGE2_FILE where the file is src/rp2_common/boot_stage2/{PICO_DEFAULT_BOOT_STAGE2}.S, type=string, default=compile_time_choice, group=build
string_flag(
name = "PICO_DEFAULT_BOOT_STAGE2",
build_setting_default = "compile_time_choice",
)
# PICO_BAZEL_CONFIG: PICO_BOOT_STAGE2_LINK_IMAGE, [Bazel only] The final boot_stage2 image target to link in. Use this to fully override/replace boot_stage2, default=@pico-sdk//src/rp2_common/boot_stage2:boot_stage2, group=build
label_flag(
name = "PICO_BOOT_STAGE2_LINK_IMAGE",
build_setting_default = "//src/rp2_common/boot_stage2:boot_stage2",
)
# PICO_BAZEL_CONFIG: PICO_CXX_ENABLE_EXCEPTIONS, Enabled CXX exception handling, type=bool, default=0, group=pico_cxx_options
bool_flag(
name = "PICO_CXX_ENABLE_EXCEPTIONS",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_CXX_ENABLE_RTTI, Enabled CXX rtti, type=bool, default=0, group=pico_cxx_options
bool_flag(
name = "PICO_CXX_ENABLE_RTTI",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_CXX_ENABLE_CXA_ATEXIT, Enabled cxa-atexit, type=bool, default=0, group=pico_cxx_options
bool_flag(
name = "PICO_CXX_ENABLE_CXA_ATEXIT",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_STDIO_UART, OPTION: Globally enable stdio UART, type=bool, default=1, group=pico_stdlib
bool_flag(
name = "PICO_STDIO_UART",
build_setting_default = True,
)
# PICO_BAZEL_CONFIG: PICO_STDIO_USB, OPTION: Globally enable stdio USB, type=bool, default=0, group=pico_stdlib
bool_flag(
name = "PICO_STDIO_USB",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_STDIO_SEMIHOSTING, OPTION: Globally enable stdio semihosting, type=bool, default=0, group=pico_stdlib
bool_flag(
name = "PICO_STDIO_SEMIHOSTING",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_CMSIS_PATH, Label of a cc_ibrary providing CMSIS core, default="included stub CORE only impl", group=build
label_flag(
name = "PICO_CMSIS_PATH",
build_setting_default = "//src/rp2_common/cmsis:cmsis_core",
)
# PICO_BAZEL_CONFIG: PICO_USE_DEFAULT_MAX_PAGE_SIZE, Don't shrink linker max page to 4096, type=bool, default=0, advanced=true, group=pico_standard_link
bool_flag(
name = "PICO_USE_DEFAULT_MAX_PAGE_SIZE",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS, Maximum number of milliseconds to wait during initialization for a CDC connection from the host (negative means indefinite) during initialization, type=int, default=0, group=pico_stdio_usb
int_flag(
name = "PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS",
build_setting_default = 0,
)
# PICO_BAZEL_CONFIG: PICO_TINYUSB_LIB, [Bazel only] The library that provides TinyUSB, default=@tinyusb//:tinyusb, group=build
label_flag(
name = "PICO_TINYUSB_LIB",
build_setting_default = "@tinyusb//:tinyusb",
)
# PICO_BAZEL_CONFIG: PICO_DEFAULT_BINARY_INFO, [Bazel only] The library that provides custom_pico_binary_info to link into all binaries, default=//src/rp2_common/pico_standard_link:default_binary_info, group=pico_standard_link
label_flag(
name = "PICO_DEFAULT_BINARY_INFO",
build_setting_default = "//src/rp2_common/pico_standard_link:default_binary_info",
)
# PICO_BAZEL_CONFIG: PICO_BAZEL_BUILD_TYPE, The type of build (e.g. Debug or Release) to embed in binary info, type=string, default=pico, group=build
string_flag(
name = "PICO_BAZEL_BUILD_TYPE",
build_setting_default = "Debug",
)
# PICO_BAZEL_CONFIG: PICO_DEFAULT_LINKER_SCRIPT, [Bazel only] The library that provides a linker script to link into all binaries, default=//src/rp2_common/pico_standard_link:default_linker_script, group=pico_standard_link
label_flag(
name = "pico_config_extra_headers",
build_setting_default = ":no_extra_headers",
name = "PICO_DEFAULT_LINKER_SCRIPT",
build_setting_default = "//src/rp2_common/pico_standard_link:default_linker_script",
)
# This should always point to a cc_library that provides
# a "pico_config_platform_headers.h".
# PICO_BAZEL_CONFIG: PICO_NO_TARGET_NAME, Don't define PICO_TARGET_NAME, type=bool, default=0, group=build
bool_flag(
name = "PICO_NO_TARGET_NAME",
build_setting_default = False,
)
# PICO_BAZEL_CONFIG: PICO_CONFIG_EXTRA_HEADER, [Bazel only] The cc_library that provides "pico_config_extra_headers.h", default=//bazel:no_extra_headers, group=pico_base
label_flag(
name = "pico_config_platform_headers",
build_setting_default = ":no_platform_headers",
name = "PICO_CONFIG_EXTRA_HEADER",
build_setting_default = "//bazel:no_extra_headers",
)
# This should always point to a cc_library that defines PICO_CONFIG_HEADER and
# any other defines that should be applied when building the SDK.
# PICO_BAZEL_CONFIG: PICO_CONFIG_PLATFORM_HEADER, [Bazel only] The cc_library that provides "pico_config_platform_headers.h" and defines PICO_BOARD, default=//src/common/pico_base:default_platform_headers, group=pico_base
label_flag(
name = "pico_config_header",
name = "PICO_CONFIG_PLATFORM_HEADER",
build_setting_default = "//src/boards:default",
)
genrule(
name = "empty_extra_headers_file",
outs = ["generated_include/pico_config_extra_headers.h"],
cmd = "echo > $@",
cmd_bat = "copy NUL $@",
visibility = ["//visibility:private"],
# PICO_BAZEL_CONFIG: PICO_CONFIG_HEADER, [Bazel only] The cc_library that defines PICO_CONFIG_HEADER or pico/config_autogen.h and other SDK critical defines (overrides PICO_BOARD setting), default=//bazel:generate_config_header, group=pico_base
label_flag(
name = "PICO_CONFIG_HEADER",
build_setting_default = "//bazel:generate_config_header",
)
genrule(
name = "empty_platform_headers_file",
outs = ["generated_include/pico_config_platform_headers.h"],
cmd = "echo > $@",
cmd_bat = "copy NUL $@",
visibility = ["//visibility:private"],
# PICO_BAZEL_CONFIG: PICO_BTSTACK_CONFIG, [Bazel only] The cc_library that provides btstack_config.h, default=//bazel:empty_cc_lib, group=wireless
label_flag(
name = "PICO_BTSTACK_CONFIG",
build_setting_default = "//bazel:empty_cc_lib",
)
cc_library(
name = "no_extra_headers",
hdrs = ["generated_include/pico_config_extra_headers.h"],
includes = ["generated_include"],
visibility = ["//visibility:private"],
# 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",
build_setting_default = "//bazel:empty_cc_lib",
)
cc_library(
name = "no_platform_headers",
hdrs = ["generated_include/pico_config_platform_headers.h"],
includes = ["generated_include"],
visibility = ["//visibility:private"],
# PICO_BAZEL_CONFIG: PICO_FREERTOS_LIB, [Bazel only] The cc_library that provides FreeRTOS, default=//bazel:empty_cc_lib, group=wireless
label_flag(
name = "PICO_FREERTOS_LIB",
build_setting_default = "//bazel:empty_cc_lib",
)
......@@ -21,38 +21,87 @@ constraint_value(
constraint_setting = ":sdk_target",
)
# This constraint value is used to guide parts of the build that apply to all
# rp2-class chips.
config_setting(
name = "rp2",
constraint_values = [
":rp2040",
],
)
# This constraint setting guides Bazel's build file evaluation differences
# across different stdio configurations (e.g. stdio_usb needs TinyUSB).
constraint_setting(
name = "stdio_mode",
default_constraint_value = "stdio_uart",
name = "wireless_support",
default_constraint_value = "no_wireless",
)
# When this constraint value is active, stdio is built against a hardware UART.
constraint_value(
name = "stdio_uart",
constraint_setting = ":stdio_mode",
name = "no_wireless",
constraint_setting = ":wireless_support",
)
# When this constraint value is active, stdio is built against TinyUSB-based
# USB serial.
constraint_value(
name = "stdio_usb",
constraint_setting = ":stdio_mode",
name = "cyw43_wireless",
constraint_setting = ":wireless_support",
)
# When this constraint value is active, stdio is built against an ARM
# semihosting library.
constraint_value(
name = "stdio_semihosting",
constraint_setting = ":stdio_mode",
config_setting(
name = "is_pico_w",
flag_values = {"//bazel/config:PICO_BOARD": "pico_w"},
)
config_setting(
name = "pico_baremetal_enabled",
flag_values = {"//bazel/config:PICO_BARE_METAL": "True"},
)
config_setting(
name = "pico_no_gc_sections_enabled",
flag_values = {"//bazel/config:PICO_NO_GC_SECTIONS": "True"},
)
config_setting(
name = "pico_cxx_enable_exceptions_enabled",
flag_values = {"//bazel/config:PICO_CXX_ENABLE_EXCEPTIONS": "True"},
)
config_setting(
name = "pico_cxx_enable_rtti_enabled",
flag_values = {"//bazel/config:PICO_CXX_ENABLE_RTTI": "True"},
)
config_setting(
name = "pico_cxx_enable_cxa_atexit_enabled",
flag_values = {"//bazel/config:PICO_CXX_ENABLE_RTTI": "True"},
)
config_setting(
name = "pico_stdio_uart_enabled",
flag_values = {"//bazel/config:PICO_STDIO_UART": "True"},
)
config_setting(
name = "pico_stdio_usb_enabled",
flag_values = {"//bazel/config:PICO_STDIO_USB": "True"},
)
config_setting(
name = "pico_stdio_semihosting_enabled",
flag_values = {"//bazel/config:PICO_STDIO_SEMIHOSTING": "True"},
)
config_setting(
name = "pico_use_default_max_page_size_enabled",
flag_values = {"//bazel/config:PICO_USE_DEFAULT_MAX_PAGE_SIZE": "True"},
)
config_setting(
name = "pico_no_target_name_enabled",
flag_values = {"//bazel/config:PICO_NO_TARGET_NAME": "True"},
)
config_setting(
name = "pico_btstack_config_unset",
flag_values = {"//bazel/config:PICO_BTSTACK_CONFIG": "@pico-sdk//bazel:empty_cc_lib"},
)
config_setting(
name = "pico_lwip_config_unset",
flag_values = {"//bazel/config:PICO_LWIP_CONFIG": "@pico-sdk//bazel:empty_cc_lib"},
)
config_setting(
name = "pico_freertos_unset",
flag_values = {"//bazel/config:PICO_FREERTOS_LIB": "@pico-sdk//bazel:empty_cc_lib"},
)
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("@rules_cc//cc:defs.bzl", "cc_library")
def _pico_generate_pio_header_impl(ctx):
generated_headers = []
for f in ctx.files.srcs:
out = ctx.actions.declare_file(
"{}_pio_generated/{}.h".format(ctx.label.name, f.basename),
)
generated_headers.append(out)
ctx.actions.run(
executable = ctx.executable._pioasm_tool,
arguments = [
"-o",
"c-sdk",
f.path,
out.path,
],
inputs = [f],
outputs = [out],
)
cc_ctx = cc_common.create_compilation_context(
headers = depset(direct = generated_headers),
includes = depset(direct = [generated_headers[0].dirname]),
)
return [
DefaultInfo(files = depset(direct = generated_headers)),
CcInfo(compilation_context = cc_ctx),
]
pico_generate_pio_header = rule(
implementation = _pico_generate_pio_header_impl,
doc = """Generates a .h header file for each listed pio source.
Each source file listed in `srcs` will be available as `[pio file name].h` on
the include path if you depend on this rule from a `cc_library`.
pico_generate_pio_header(
name = "my_fun_pio",
srcs = ["my_fun_pio.pio"],
)
# This library can #include "my_fun_pio.pio.h".
cc_library(
name = "libfoo",
deps = [":my_fun_pio"],
srcs = ["libfoo.c"],
)
""",
attrs = {
"srcs": attr.label_list(mandatory = True, allow_files = True),
"_pioasm_tool": attr.label(
default = "@pico-sdk//tools/pioasm:pioasm",
cfg = "exec",
executable = True,
),
},
provides = [CcInfo],
)
# Because the syntax for target_compatible_with when used with config_setting
# rules is both confusing and verbose, provide some helpers that make it much
# easier and clearer to express compatibility.
#
# Context: https://github.com/bazelbuild/bazel/issues/12614
def compatible_with_config(config_label):
"""Expresses compatibility with a config_setting."""
return select({
config_label: [],
"//conditions:default": ["@platforms//:incompatible"],
})
def incompatible_with_config(config_label):
"""Expresses incompatibility with a config_setting."""
return select({
config_label: ["@platforms//:incompatible"],
"//conditions:default": [],
})
def compatible_with_rp2():
"""Expresses a rule is compatible with the rp2 family."""
return incompatible_with_config("//bazel/constraint:host")
def compatible_with_pico_w():
"""Expresses a rule is compatible a Pico W."""
return select({
"@pico-sdk//bazel/constraint:cyw43_wireless": [],
"@pico-sdk//bazel/constraint:is_pico_w": [],
"//conditions:default": ["@platforms//:incompatible"],
})
def pico_board_config(name, platform_includes, **kwargs):
"""A helper macro for declaring a Pico board to use with PICO_CONFIG_HEADER.
This generates pico_config_platform_headers.h using the list of
includes provided in `platform_includes`, and the final artifact is
a cc_library that you can configure //bazel/config:PICO_CONFIG_HEADER to
point to.
"""
_hdr_dir = "{}_generated_includes".format(name)
_hdr_path = "{}/pico_config_platform_headers.h".format(_hdr_dir)
write_file(
name = "{}_platform_headers_file".format(name),
out = _hdr_path,
content = ['#include "{}"'.format(inc) for inc in platform_includes],
)
kwargs.setdefault("hdrs", [])
kwargs["hdrs"].append(_hdr_path)
kwargs.setdefault("includes", [])
kwargs["includes"].append(_hdr_dir)
cc_library(
name = name,
**kwargs
)
......@@ -2,11 +2,11 @@
// is checked in directly.
//
// You can change what is included by configuring these `label_flag`s:
// --@pico-sdk//bazel/config:pico_config_extra_headers=//my_proj:my_custom_headers
// --@pico-sdk//bazel/config:pico_config_platform_headers=//my_proj:my_custom_headers
// --@pico-sdk//bazel/config:PICO_CONFIG_EXTRA_HEADER=//my_proj:my_custom_headers
// --@pico-sdk//bazel/config:PICO_CONFIG_PLATFORM_HEADER=//my_proj:my_custom_headers
// This header must be provided by //bazel/config:pico_config_extra_headers:
// This header must be provided by //bazel/config:PICO_CONFIG_EXTRA_HEADER:
#include "pico_config_extra_headers.h"
// This header must be provided by //bazel/config:pico_config_platform_headers:
// This header must be provided by //bazel/config:PICO_CONFIG_PLATFORM_HEADER:
#include "pico_config_platform_headers.h"
......@@ -2,6 +2,9 @@ load("@rules_cc//cc/toolchains:args.bzl", "cc_args")
load("@rules_cc//cc/toolchains:args_list.bzl", "cc_args_list")
load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature")
load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain")
load("configurable_feature.bzl", "configurable_toolchain_feature")
package(default_visibility = ["//visibility:public"])
cc_args(
name = "cortex-m0",
......@@ -44,6 +47,43 @@ cc_args(
],
)
configurable_toolchain_feature(
name = "gc_sections",
copts = [
"-ffunction-sections",
"-fdata-sections",
],
disable_if = "//bazel/constraint:pico_no_gc_sections_enabled",
linkopts = ["-Wl,--gc-sections"],
)
configurable_toolchain_feature(
name = "cxx_no_exceptions",
cxxopts = [
"-fno-exceptions",
"-fno-unwind-tables",
],
disable_if = "//bazel/constraint:pico_cxx_enable_exceptions_enabled",
)
configurable_toolchain_feature(
name = "cxx_no_rtti",
cxxopts = ["-fno-rtti"],
disable_if = "//bazel/constraint:pico_cxx_enable_rtti_enabled",
)
configurable_toolchain_feature(
name = "cxx_no_cxa_atexit",
cxxopts = ["-fno-use-cxa-atexit"],
disable_if = "//bazel/constraint:pico_cxx_enable_cxa_atexit_enabled",
)
configurable_toolchain_feature(
name = "override_max_page_size",
disable_if = "//bazel/constraint:pico_use_default_max_page_size_enabled",
linkopts = ["-Wl,-z,max-page-size=4096"],
)
# TODO: Make this shim unnecessary.
cc_args_list(
name = "all_opt_debug_args",
......@@ -134,6 +174,11 @@ _HOST_CPU_CONSTRAINTS = {
toolchain_features = [
"@pico-sdk//bazel/toolchain:legacy_features",
"@pico-sdk//bazel/toolchain:override_debug",
"@pico-sdk//bazel/toolchain:gc_sections",
"@pico-sdk//bazel/toolchain:cxx_no_exceptions",
"@pico-sdk//bazel/toolchain:cxx_no_rtti",
"@pico-sdk//bazel/toolchain:cxx_no_cxa_atexit",
"@pico-sdk//bazel/toolchain:override_max_page_size",
],
) for host_os, host_cpu in HOSTS]
......
load("@rules_cc//cc/toolchains:args.bzl", "cc_args")
load("@rules_cc//cc/toolchains:args_list.bzl", "cc_args_list")
load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature")
def configurable_toolchain_feature(name, copts = [], cxxopts = [], linkopts = [], enable_if = None, disable_if = None):
if enable_if != None and disable_if != None:
fail("Cannot specify both enable_if and disable_if")
if enable_if == None and disable_if == None:
fail("Must specify at least one of enable_if and disable_if")
if enable_if == None:
enable_if = "//conditions:default"
if disable_if == None:
disable_if = "//conditions:default"
all_args = []
if copts:
cc_args(
name = name + "_cc_args",
actions = ["@rules_cc//cc/toolchains/actions:compile_actions"],
args = copts,
)
all_args.append(name + "_cc_args")
if cxxopts:
cc_args(
name = name + "_cxx_args",
actions = ["@rules_cc//cc/toolchains/actions:cpp_compile_actions"],
args = cxxopts,
)
all_args.append(name + "_cxx_args")
if linkopts:
cc_args(
name = name + "_link_args",
actions = ["@rules_cc//cc/toolchains/actions:link_actions"],
args = linkopts,
)
all_args.append(name + "_link_args")
cc_args_list(
name = name + "_args",
args = all_args,
)
cc_feature(
name = name,
feature_name = name,
args = [":{}_args".format(name)],
enabled = select({
disable_if: False,
enable_if: True,
}),
)
def declare_flag_choices(flag, choices):
"""Declares a `config_setting` for each known choice for the provided flag.
The name of each config setting uses the name of the `config_setting` is:
[flag label name]_[choice]
This can be used with select_choice() to map `config_setting`s to values.
Args:
flag: The flag that guides the declared `config_setting`s.
pkg: The package that declare_flag_choices() was declared in.
choice_map: A mapping of distinct choices to
"""
flag_name = flag.split(":")[1]
[
native.config_setting(
name = "{}_{}".format(flag_name, choice),
flag_values = {flag: choice},
)
for choice in choices
]
def flag_choice(flag, pkg, choice_map):
"""Creates a `select()` based on choices declared by `declare_choices()`.
Args:
flag: The flag that guides the select.
pkg: The package that `declare_flag_choices()` was called in.
choice_map: A mapping of distinct choices to the final intended value.
"""
return {
"{}:{}_{}".format(
pkg.split(":")[0],
flag.split(":")[1],
choice,
): val
for choice, val in choice_map.items()
}
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
def _pico_sdk_define_impl(ctx):
val = ctx.attr.from_flag[BuildSettingInfo].value
if type(val) == "string":
# Strings need quotes.
val = "\"{}\"".format(val)
elif type(val) == "bool":
# Convert bools to 0 or 1.
val = 1 if val else 0
cc_ctx = cc_common.create_compilation_context(
defines = depset(
direct = ["{}={}".format(ctx.attr.define_name, val)],
),
)
return [CcInfo(compilation_context = cc_ctx)]
pico_sdk_define = rule(
implementation = _pico_sdk_define_impl,
doc = """A simple rule that offers a skylib flag as a define.
These can be listed in the `deps` attribute of a `cc_library` to get access
to the value of a define.
Example:
bool_flag(
name = "my_flag",
build_setting_default = False,
)
pico_sdk_define(
name = "flag_define",
define_name = "MY_FLAG_DEFINE",
from_flag = ":my_flag",
)
""",
attrs = {
"define_name": attr.string(mandatory = True),
"from_flag": attr.label(mandatory = True),
},
)
# A transition in Bazel is a way to force changes to the way the build is
# evaluated for all dependencies of a given rule.
#
# Imagine the following simple dependency graph:
#
# ->: depends on
# a -> b -> c
#
# Normally, if you set `defines` on a, they couldn't apply to b or c because
# they are dependencies of a. There's no way for b or c to know about a's
# settings, because they don't even know a exists!
#
# We can fix this via a transition! If we put a transition in front of `a`
# that sets --copts=-DFOO=42, we're telling Bazel to build a and all of its
# dependencies under that configuration.
#
# Note: Flags must be referenced as e.g. `//command_line_option:copt` in
# transitions.
#
# `declare_transition()` eliminates the frustrating amount of boilerplate. All
# you need to do is provide a set of attrs, and then a `flag_overrides`
# dictionary that tells `declare_transition()` which attrs to pull flag values
# from. The common `src` attr tells the transition which build rule to apply
# the transition to.
def declare_transtion(attrs, flag_overrides, executable = True):
def declare_transtion(attrs, flag_overrides = None, append_to_flags = None, executable = True):
"""A helper that drastically simplifies declaration of a transition.
A transition in Bazel is a way to force changes to the way the build is
evaluated for all dependencies of a given rule.
Imagine the following simple dependency graph:
->: depends on
a -> b -> c
Normally, if you set `defines` on a, they couldn't apply to b or c because
they are dependencies of a. There's no way for b or c to know about a's
settings, because they don't even know a exists!
We can fix this via a transition! If we put a transition in front of `a`
that sets --copts=-DFOO=42, we're telling Bazel to build a and all of its
dependencies under that configuration.
Note: Flags must be referenced as e.g. `//command_line_option:copt` in
transitions.
`declare_transition()` eliminates the frustrating amount of boilerplate. All
you need to do is provide a set of attrs, and then a `flag_overrides`
dictionary that tells `declare_transition()` which attrs to pull flag values
from. The common `src` attr tells the transition which build rule to apply
the transition to.
"""
def _flag_override_impl(settings, attrs):
return {
final_overrides = {}
if flag_overrides != None:
final_overrides = {
key: str(getattr(attrs, value))
for key, value in flag_overrides.items()
}
if append_to_flags != None:
for flag, field in append_to_flags.items():
accumulated_flags = final_overrides.get(flag, settings.get(flag, []))
accumulated_flags.extend(
[str(val) for val in getattr(attrs, field)],
)
final_overrides[flag] = accumulated_flags
return final_overrides
output_flags = []
if flag_overrides != None:
output_flags.extend(flag_overrides.keys())
if append_to_flags != None:
output_flags.extend(append_to_flags.keys())
_transition = transition(
implementation = _flag_override_impl,
inputs = [],
outputs = flag_overrides.keys(),
inputs = append_to_flags.keys() if append_to_flags != None else [],
outputs = output_flags,
)
def _symlink_artifact_impl(ctx):
......@@ -56,15 +75,18 @@ def declare_transtion(attrs, flag_overrides, executable = True):
executable = executable,
mandatory = True,
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
} | attrs,
)
# This transition is applied before building the boot_stage2 image.
rp2040_bootloader_binary = declare_transtion(
attrs = {
"_malloc": attr.label(default = "//src/rp2_common/boot_stage2:no_malloc"),
"_malloc": attr.label(default = "//bazel:empty_cc_lib"),
# 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(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
flag_overrides = {
# We don't want --custom_malloc to ever apply to the bootloader, so
......@@ -72,3 +94,37 @@ rp2040_bootloader_binary = declare_transtion(
"//command_line_option:custom_malloc": "_malloc",
},
)
# This transition sets SDK configuration options required to build test binaries
# for the kitchen_sink suite of tests.
kitchen_sink_test_binary = declare_transtion(
attrs = {
"bt_stack_config": attr.label(mandatory = True),
"lwip_config": attr.label(mandatory = True),
# 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(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
flag_overrides = {
"@pico-sdk//bazel/config:PICO_BTSTACK_CONFIG": "bt_stack_config",
"@pico-sdk//bazel/config:PICO_LWIP_CONFIG": "lwip_config",
},
)
# This is a general purpose transition that applies the listed copt flags to
# all transitive dependencies.
extra_copts_for_all_deps = declare_transtion(
attrs = {
"extra_copts": attr.string_list(),
# 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(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
append_to_flags = {
"//command_line_option:copt": "extra_copts",
},
)
load("//bazel:defs.bzl", "pico_board_config")
load("//bazel/util:multiple_choice_flag.bzl", "declare_flag_choices", "flag_choice")
package(default_visibility = ["//visibility:public"])
# TODO: Add a macro/helper to support the rest of the boards.
cc_library(
name = "unsupported_boards",
srcs = [
"include/boards/adafruit_feather_rp2040.h",
"include/boards/adafruit_itsybitsy_rp2040.h",
"include/boards/adafruit_kb2040.h",
"include/boards/adafruit_macropad_rp2040.h",
"include/boards/adafruit_qtpy_rp2040.h",
"include/boards/adafruit_trinkey_qt2040.h",
"include/boards/arduino_nano_rp2040_connect.h",
"include/boards/datanoisetv_rp2040_dsp.h",
"include/boards/eetree_gamekit_rp2040.h",
"include/boards/garatronic_pybstick26_rp2040.h",
"include/boards/melopero_shake_rp2040.h",
"include/boards/none.h",
"include/boards/nullbits_bit_c_pro.h",
"include/boards/pico_w.h",
"include/boards/pimoroni_badger2040.h",
"include/boards/pimoroni_interstate75.h",
"include/boards/pimoroni_keybow2040.h",
"include/boards/pimoroni_motor2040.h",
"include/boards/pimoroni_pga2040.h",
"include/boards/pimoroni_picolipo_16mb.h",
"include/boards/pimoroni_picolipo_4mb.h",
"include/boards/pimoroni_picosystem.h",
"include/boards/pimoroni_plasma2040.h",
"include/boards/pimoroni_servo2040.h",
"include/boards/pimoroni_tiny2040.h",
"include/boards/pimoroni_tiny2040_2mb.h",
"include/boards/pololu_3pi_2040_robot.h",
"include/boards/seeed_xiao_rp2040.h",
"include/boards/solderparty_rp2040_stamp.h",
"include/boards/solderparty_rp2040_stamp_carrier.h",
"include/boards/solderparty_rp2040_stamp_round_carrier.h",
"include/boards/sparkfun_micromod.h",
"include/boards/sparkfun_promicro.h",
"include/boards/sparkfun_thingplus.h",
"include/boards/vgaboard.h",
"include/boards/waveshare_rp2040_lcd_0.96.h",
"include/boards/waveshare_rp2040_lcd_1.28.h",
"include/boards/waveshare_rp2040_one.h",
"include/boards/waveshare_rp2040_plus_16mb.h",
"include/boards/waveshare_rp2040_plus_4mb.h",
"include/boards/waveshare_rp2040_zero.h",
"include/boards/wiznet_w5100s_evb_pico.h",
],
includes = ["include"],
visibility = ["//visibility:private"],
)
# Known board choices:
BOARD_CHOICES = [
"adafruit_feather_rp2040",
"adafruit_itsybitsy_rp2040",
"adafruit_kb2040",
"adafruit_macropad_rp2040",
"adafruit_qtpy_rp2040",
"adafruit_trinkey_qt2040",
"arduino_nano_rp2040_connect",
"datanoisetv_rp2040_dsp",
"eetree_gamekit_rp2040",
"garatronic_pybstick26_rp2040",
"melopero_shake_rp2040",
"none",
"nullbits_bit_c_pro",
"pico",
"pico_w",
"pimoroni_badger2040",
"pimoroni_interstate75",
"pimoroni_keybow2040",
"pimoroni_motor2040",
"pimoroni_pga2040",
"pimoroni_picolipo_16mb",
"pimoroni_picolipo_4mb",
"pimoroni_picosystem",
"pimoroni_plasma2040",
"pimoroni_servo2040",
"pimoroni_tiny2040",
"pimoroni_tiny2040_2mb",
"pololu_3pi_2040_robot",
"seeed_xiao_rp2040",
"solderparty_rp2040_stamp",
"solderparty_rp2040_stamp_carrier",
"solderparty_rp2040_stamp_round_carrier",
"sparkfun_micromod",
"sparkfun_promicro",
"sparkfun_thingplus",
"vgaboard",
"waveshare_rp2040_lcd_0.96",
"waveshare_rp2040_lcd_1.28",
"waveshare_rp2040_one",
"waveshare_rp2040_plus_16mb",
"waveshare_rp2040_plus_4mb",
"waveshare_rp2040_zero",
"wiznet_w5100s_evb_pico",
"cytron_maker_pi_rp2040",
"metrotech_xerxes_rp2040",
"pololu_zumo_2040_robot",
"weact_studio_rp2040_16mb",
"weact_studio_rp2040_2mb",
"weact_studio_rp2040_4mb",
"weact_studio_rp2040_8mb",
]
cc_library(
name = "stdio_defines",
defines = select({
"//bazel/constraint:stdio_semihosting": ["LIB_PICO_STDIO_SEMIHOSTING=1"],
"//bazel/constraint:stdio_uart": ["LIB_PICO_STDIO_UART=1"],
"//bazel/constraint:stdio_usb": ["LIB_PICO_STDIO_USB=1"],
}),
)
BOARD_CHOICE_FILES = ["include/boards/" + c + ".h" for c in BOARD_CHOICES]
cc_library(
name = "common_board_defines",
defines = [
"PICO_ON_DEVICE=1",
"PICO_NO_HARDWARE=0",
"PICO_BUILD=1",
],
)
BOARD_CHOICE_MAP = {c: [":{}".format(c)] for c in BOARD_CHOICES}
cc_library(
name = "pico",
hdrs = ["include/boards/pico.h"],
# PICO_BUILD_DEFINE: PICO_BOARD, Name of board, type=string, default=CMake PICO_BOARD variable, group=pico_base
[
pico_board_config(
name = board,
hdrs = BOARD_CHOICE_FILES,
defines = [
'PICO_BOARD=\\"rp2040\\"',
'PICO_CONFIG_HEADER="boards/pico.h"',
'PICO_BOARD=\\"{}\\"'.format(board),
],
includes = ["include"],
deps = [
":common_board_defines",
":stdio_defines",
platform_includes = [
"cmsis/rename_exceptions.h",
"boards/{}.h".format(board),
],
deps = ["//src/rp2_common/cmsis:rename_exceptions"],
)
for board in BOARD_CHOICES
]
cc_library(
name = "host",
hdrs = ["include/boards/none.h"],
defines = [
'PICO_BOARD=\\"none\\"',
'PICO_CONFIG_HEADER="boards/none.h"',
"PICO_ON_DEVICE=0",
"PICO_NO_HARDWARE=1",
"PICO_BUILD=1",
],
includes = ["include"],
# Creates a config_setting for each known board option with the name:
# PICO_BOARD_[choice]
declare_flag_choices(
"//bazel/config:PICO_BOARD",
BOARD_CHOICES,
)
alias(
cc_library(
name = "default",
actual = select({
"//bazel/constraint:rp2": ":pico",
"//bazel/constraint:host": ":host",
}),
deps = select(
flag_choice(
"//bazel/config:PICO_BOARD",
":__pkg__",
BOARD_CHOICE_MAP,
) | {
"//bazel/constraint:host": [":none"],
"//conditions:default": [":none"],
},
),
)
......@@ -2,14 +2,31 @@ load("@bazel_skylib//rules:run_binary.bzl", "run_binary")
package(default_visibility = ["//visibility:public"])
# PICO_BAZEL_CONFIG: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base
PICO_SDK_VERSION_STRING = module_version() if module_version() != None else "0.0.1-WORKSPACE"
_version_parts = PICO_SDK_VERSION_STRING.split(".")
# PICO_BAZEL_CONFIG: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, group=pico_base
PICO_SDK_VERSION_MAJOR = int(_version_parts[0])
# PICO_BAZEL_CONFIG: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, group=pico_base
PICO_SDK_VERSION_MINOR = int(_version_parts[1])
_revision_parts = _version_parts[2].split("-")
# PICO_BAZEL_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, group=pico_base
PICO_SDK_VERSION_REVISION = int(_revision_parts[0])
# PICO_BAZEL_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base
PICO_SDK_VERSION_PRE_RELEASE_ID = _revision_parts[1] if len(_revision_parts) > 1 else None
run_binary(
name = "version_header",
srcs = ["include/pico/version.h.in"],
outs = ["generated_include/pico/version.h"],
args = [
"--version-string={}".format(
module_version() if module_version() != None else "0.0.1-WORKSPACE",
),
"--version-string={}".format(PICO_SDK_VERSION_STRING),
"--template=$(location include/pico/version.h.in)",
"--output=$(location generated_include/pico/version.h)",
],
......@@ -17,9 +34,20 @@ run_binary(
visibility = ["//visibility:private"],
)
# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, group=pico_base
# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, group=pico_base
# PICO_BUILD_DEFINE: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, group=pico_base
# PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base
# PICO_BUILD_DEFINE: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base
cc_library(
name = "version",
hdrs = ["generated_include/pico/version.h"],
defines = [
'PICO_SDK_VERSION_STRING=\\"{}\\"'.format(PICO_SDK_VERSION_STRING),
"PICO_SDK_VERSION_MAJOR={}".format(PICO_SDK_VERSION_MAJOR),
'PICO_SDK_VERSION_MINOR={}"'.format(PICO_SDK_VERSION_MINOR),
'PICO_SDK_VERSION_REVISION={}"'.format(PICO_SDK_VERSION_REVISION),
] + [] if PICO_SDK_VERSION_PRE_RELEASE_ID == None else ['PICO_SDK_VERSION_PRE_RELEASE_ID=\\"{}\\"'.format(PICO_SDK_VERSION_PRE_RELEASE_ID)],
includes = ["generated_include"],
)
......@@ -27,7 +55,7 @@ alias(
name = "platform_defs",
actual = select({
"//bazel/constraint:host": "//src/host/pico_platform:platform_defs",
"//bazel/constraint:rp2": "//src/rp2_common/pico_platform:platform_defs",
"//conditions:default": "//src/rp2_common/pico_platform:platform_defs",
}),
)
......@@ -35,7 +63,28 @@ alias(
name = "pico_platform",
actual = select({
"//bazel/constraint:host": "//src/host/pico_platform:pico_platform",
"//bazel/constraint:rp2": "//src/rp2_common/pico_platform:pico_platform",
"//conditions:default": "//src/rp2_common/pico_platform:pico_platform",
}),
)
# PICO_BAZEL_CONFIG: PICO_NO_HARDWARE, OPTION: Whether the build is not targeting an RP2040 device, type=bool, default=1 when PICO_PLATFORM is host, 0 otherwise, group=build
# PICO_BUILD_DEFINE: PICO_NO_HARDWARE, Whether the build is not targeting an RP2040 device, type=bool, default=1 when PICO_PLATFORM is host, 0 otherwise, group=build
# PICO_BAZEL_CONFIG: PICO_ON_DEVICE, OPTION: Whether the build is targeting an RP2040 device, type=bool, default=0 when PICO_PLATFORM is host, 1 otherwise, group=build
# PICO_BUILD_DEFINE: PICO_ON_DEVICE, Whether the build is targeting an RP2040 device, type=bool, default=0 when PICO_PLATFORM is host, 1 otherwise, group=build
# PICO_BUILD is undocumented in CMake.
cc_library(
name = "common_sdk_defines",
defines = select({
"//bazel/constraint:host": [
"PICO_ON_DEVICE=0",
"PICO_NO_HARDWARE=1",
"PICO_BUILD=1",
],
"//conditions:default": [
"PICO_ON_DEVICE=1",
"PICO_NO_HARDWARE=0",
"PICO_BUILD=1",
],
}),
)
......@@ -61,6 +110,7 @@ cc_library(
"//src/common/pico_sync:__pkg__",
"//src/common/pico_time:__pkg__",
"//src/common/pico_util:__pkg__",
"//src/host/hardware_timer:__pkg__",
"//src/host/pico_platform:__pkg__",
"//src/rp2_common/boot_stage2:__pkg__",
"//src/rp2_common/hardware_claim:__pkg__",
......@@ -81,23 +131,24 @@ cc_library(
"//src/rp2_common/pico_standard_link:__pkg__",
],
deps = [
":common_sdk_defines",
":version",
"//bazel:generate_config_header",
"//bazel/config:pico_config_header",
"//bazel/config:PICO_CONFIG_HEADER",
],
)
cc_library(
name = "pico_base",
implementation_deps = select({
"//bazel/constraint:host": [],
"//conditions:default": [
"//src/rp2_common/pico_platform:platform_link_deps",
],
}),
deps = [
# :pico_platform creates circular dependencies, so break them
# via an intermediate.
":pico_platform",
":pico_base_interface",
"//src/rp2_common/cmsis:cmsis_core",
"//src/rp2_common/boot_stage2",
"//src/rp2_common/pico_bootrom",
"//src/rp2_common/pico_runtime",
"//src/rp2_common/pico_standard_link",
],
)
package(default_visibility = ["//visibility:public"])
# TODO: Flags to support PICO_PROGRAM_*.
cc_library(
name = "pico_binary_info",
hdrs = [
......
load("@rules_cc//cc:defs.bzl", "cc_library")
# PICO_BUILD_DEFINE: PICO_PROGRAM_NAME, Provided by PICO_DEFAULT_BINARY_INFO or a manually linked custom_pico_binary_info target, type=string, group=pico_binary_info
# PICO_BUILD_DEFINE: PICO_PROGRAM_DESCRIPTION, Provided by PICO_DEFAULT_BINARY_INFO or a manually linked custom_pico_binary_info target, type=string, group=pico_binary_info
# PICO_BUILD_DEFINE: PICO_PROGRAM_URL, Provided by PICO_DEFAULT_BINARY_INFO or a manually linked custom_pico_binary_info target, type=string, group=pico_binary_info
# PICO_BUILD_DEFINE: PICO_PROGRAM_VERSION_STRING, Provided by PICO_DEFAULT_BINARY_INFO or a manually linked custom_pico_binary_info target, type=string, group=pico_binary_info
# PICO_BUILD_DEFINE: PICO_TARGET_NAME, The name of the build target being compiled, type=string, default=target name, group=build
def custom_pico_binary_info(name = None, program_name = None, program_description = None, program_url = None, program_version_string = None, build_target_name = None):
_all_defines = []
if program_name != None:
_all_defines.append('PICO_PROGRAM_NAME=\\"{}\\"'.format(program_name))
if program_description != None:
_all_defines.append('PICO_PROGRAM_DESCRIPTION=\\"{}\\"'.format(program_description))
if program_url != None:
_all_defines.append('PICO_PROGRAM_URL=\\"{}\\"'.format(program_url))
if program_version_string != None:
_all_defines.append('PICO_PROGRAM_VERSION_STRING=\\"{}\\"'.format(program_version_string))
# TODO: There's no practical way to support this correctly without a
# `pico_cc_binary` wrapper. Either way, this would be the right place to put
# it.
_build_target_name_defines = []
if build_target_name != None:
_build_target_name_defines.append('PICO_TARGET_NAME=\\"{}\\"'.format(build_target_name))
cc_library(
name = name,
defines = _all_defines + select({
"@pico-sdk//bazel/constraint:pico_no_target_name_enabled": [],
"//conditions:default": _build_target_name_defines,
}),
srcs = ["@pico-sdk//src/rp2_common/pico_standard_link:binary_info_srcs"],
deps = [
"@pico-sdk//src/rp2_common/pico_standard_link:PICO_BAZEL_BUILD_TYPE",
"@pico-sdk//src/common/pico_base:version",
"@pico-sdk//src/common/pico_binary_info",
"@pico-sdk//src/rp2_common/boot_stage2:config",
],
alwayslink = True,
)
......@@ -8,6 +8,7 @@ cc_library(
hdrs = ["include/pico/bit_ops.h"],
includes = ["include"],
visibility = [
"//src/host/pico_bit_ops:__pkg__",
"//src/rp2_common/pico_bit_ops:__pkg__",
],
deps = [
......@@ -19,13 +20,10 @@ cc_library(
name = "pico_bit_ops",
hdrs = ["include/pico/bit_ops.h"],
includes = ["include"],
# TODO: Add `select()` for host redirections.
target_compatible_with = select({
"//bazel/constraint:rp2": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
deps = [
"//src/common/pico_base",
"//src/rp2_common/pico_bit_ops",
],
] + select({
"//bazel/constraint:host": ["//src/host/pico_bit_ops"],
"//conditions:default": ["//src/rp2_common/pico_bit_ops"],
}),
)
......@@ -7,7 +7,7 @@ cc_library(
deps = [
"//src/common/pico_base",
] + select({
"//bazel/constraint:rp2": ["//src/rp2_common/hardware_divider"],
"//bazel/constraint:host": ["//src/host/hardware_divider"],
"//conditions:default": ["//src/rp2_common/pico_divider"],
}),
)
......@@ -6,39 +6,46 @@ cc_library(
name = "pico_stdlib_interface",
hdrs = ["include/pico/stdlib.h"],
includes = ["include"],
# TODO: Add `select()` for host redirections.
target_compatible_with = select({
"//bazel/constraint:rp2": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
visibility = [
"//src/host/pico_stdio:__pkg__",
"//src/host/pico_stdlib:__pkg__",
"//src/rp2_common/pico_stdlib:__pkg__",
"//src/rp2_common/tinyusb:__pkg__",
],
deps = [
"//src/common/pico_base",
"//src/common/pico_time",
] + select({
"//bazel/constraint:host": [
"//src/host/hardware_gpio",
"//src/host/hardware_uart",
],
"//conditions:default": [
"//src/rp2_common/hardware_gpio",
"//src/rp2_common/hardware_uart",
"//src/rp2_common/pico_stdio",
],
}),
)
cc_library(
name = "pico_stdlib",
hdrs = ["include/pico/stdlib.h"],
includes = ["include"],
# TODO: Add `select()` for host redirections.
target_compatible_with = select({
"//bazel/constraint:rp2": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
deps = [
"//src/common/pico_base",
"//src/common/pico_time",
] + select({
"//bazel/constraint:host": [
"//src/host/hardware_gpio",
"//src/host/hardware_uart",
"//src/host/pico_stdio",
"//src/host/pico_stdlib",
],
"//conditions:default": [
"//src/rp2_common/hardware_gpio",
"//src/rp2_common/hardware_uart",
"//src/rp2_common/pico_stdio",
"//src/rp2_common/pico_stdlib",
],
}),
)
......@@ -16,14 +16,15 @@ cc_library(
"include/pico/sync.h",
],
includes = ["include"],
# TODO: Add `select()` for host redirections.
target_compatible_with = select({
"//bazel/constraint:rp2": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
deps = [
"//src/common/pico_base:pico_base_interface",
"//src/common/pico_time:pico_time_headers",
] + select({
"//bazel/constraint:host": [
"//src/host/hardware_sync",
],
"//conditions:default": [
"//src/rp2_common/hardware_sync",
],
}),
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment