-
Notifications
You must be signed in to change notification settings - Fork 64
Prototypical Bazel Integration #428
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| libs/3rdparty/googletest/googletest/test | ||
| libs/3rdparty/googletest/googlemock/test |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # OpenBSW Bazel Configuration | ||
| # =========================== | ||
|
|
||
| # Common C/C++ standards | ||
| build --cxxopt=-std=c++14 | ||
| build --conlyopt=-std=c99 | ||
| build --host_cxxopt=-std=c++14 | ||
| build --host_conlyopt=-std=c99 | ||
|
|
||
| # Strict action environment for reproducibility | ||
| build --incompatible_strict_action_env | ||
|
|
||
| # Enable platform-based toolchain resolution | ||
| build --incompatible_enable_cc_toolchain_resolution | ||
|
|
||
| # =========================== | ||
| # Platform configurations | ||
| # =========================== | ||
|
|
||
| # POSIX + FreeRTOS (default development config) | ||
| build:posix-freertos --define platform=posix | ||
| build:posix-freertos --define rtos=freertos | ||
| build:posix-freertos --define executable=referenceapp | ||
| build:posix-freertos --copt=-DSUPPORT_FREERTOS | ||
| build:posix-freertos --copt=-DPLATFORM_SUPPORT_CAN | ||
| build:posix-freertos --copt=-DPLATFORM_SUPPORT_ETHERNET | ||
| build:posix-freertos --copt=-DPLATFORM_SUPPORT_TRANSPORT | ||
| build:posix-freertos --copt=-DPLATFORM_SUPPORT_STORAGE | ||
|
|
||
| # POSIX + ThreadX | ||
| build:posix-threadx --define platform=posix | ||
| build:posix-threadx --define rtos=threadx | ||
| build:posix-threadx --define executable=referenceapp | ||
| build:posix-threadx --copt=-DSUPPORT_THREADX | ||
| build:posix-threadx --copt=-DPLATFORM_SUPPORT_CAN | ||
| build:posix-threadx --copt=-DPLATFORM_SUPPORT_ETHERNET | ||
| build:posix-threadx --copt=-DPLATFORM_SUPPORT_TRANSPORT | ||
| build:posix-threadx --copt=-DPLATFORM_SUPPORT_STORAGE | ||
|
Comment on lines
+34
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These preprocessor defines / flags should also be tied to the toolchains directly. E.g. |
||
|
|
||
| # S32K148 + FreeRTOS (ARM cross-compilation) | ||
| build:s32k148-freertos --define platform=s32k148 | ||
| build:s32k148-freertos --define rtos=freertos | ||
| build:s32k148-freertos --define executable=referenceapp | ||
|
Comment on lines
+41
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| build:s32k148-freertos --platforms=//bazel/platforms:s32k148 | ||
| build:s32k148-freertos --copt=-DSUPPORT_FREERTOS | ||
| build:s32k148-freertos --copt=-mcpu=cortex-m4 | ||
| build:s32k148-freertos --copt=-mthumb | ||
| build:s32k148-freertos --copt=-mfloat-abi=hard | ||
| build:s32k148-freertos --copt=-mfpu=fpv4-sp-d16 | ||
|
Comment on lines
+45
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These architecture flags need to be tied to the specific S32K148 toolchain not set globaly here. They can be part of a default_compile_flags feature / flag_set and will be set when the toolchain is selected via toolchain resolution.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly, bascially the same point as above I think, needs to be properly integrated into the toolchain. As said, it's not included in this PR but we can share a properly working toolchain setup during the process of our bazel integration :) |
||
|
|
||
| # S32K148 + ThreadX (ARM cross-compilation) | ||
| build:s32k148-threadx --define platform=s32k148 | ||
| build:s32k148-threadx --define rtos=threadx | ||
| build:s32k148-threadx --define executable=referenceapp | ||
| build:s32k148-threadx --platforms=//bazel/platforms:s32k148 | ||
| build:s32k148-threadx --copt=-DSUPPORT_THREADX | ||
| build:s32k148-threadx --copt=-mcpu=cortex-m4 | ||
| build:s32k148-threadx --copt=-mthumb | ||
| build:s32k148-threadx --copt=-mfloat-abi=hard | ||
| build:s32k148-threadx --copt=-mfpu=fpv4-sp-d16 | ||
|
|
||
| # =========================== | ||
| # Unit test configuration | ||
| # =========================== | ||
|
|
||
| build:unit-test --define platform=posix | ||
| build:unit-test --define rtos=freertos | ||
| build:unit-test --define executable=unittest | ||
| build:unit-test --copt=-DSUPPORT_FREERTOS | ||
| test:unit-test --test_output=errors | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be defined globally but instead using dedicated test targets. |
||
|
|
||
| # =========================== | ||
| # Feature flags | ||
| # =========================== | ||
|
|
||
| # Enable tracing support | ||
| build:tracing --define tracing=on | ||
|
|
||
| # =========================== | ||
| # Convenience aliases | ||
| # =========================== | ||
|
|
||
| # Try importing a user-specific .bazelrc (optional, not checked in) | ||
| try-import %workspace%/user.bazelrc | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 7.6.1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a specific reason to pick this version? If there's no specific requirements, I would advise picking a LTS release from here: https://bazel.build/release:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @the-nick-fischer , so there was no major reason, it's just that in internal projects we used version 7.6 and thus started from there. I personally would also like to go with the latest version 8 (since as you say 9 is still very new), but we have to see about compatability in case a project who wants to integrate might only support bazel 7. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,3 +25,4 @@ doc/api/doc-coverage.info | |
| doc/api/doxygenOut | ||
| tools/puncover_tool/output/ | ||
| venv | ||
| bazel-* | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,223 @@ | ||
| # Bazel Support for OpenBSW | ||
|
|
||
| ## Status | ||
|
|
||
| Bazel build support has been implemented and **verified working**. The POSIX + FreeRTOS reference application builds successfully (271 actions, 246 targets across 145 packages). This document describes the architecture and usage. | ||
|
|
||
| ### Build Verification | ||
|
|
||
| - `bazel build --config=posix-freertos //executables/referenceApp/application:app` — **PASSES** ✅ | ||
| - Produces a fully linked ELF 64-bit x86-64 binary | ||
| - All BSW libraries, 3rdparty dependencies, FreeRTOS port, and platform BSP compile and link | ||
|
|
||
| ## Overview | ||
|
|
||
| The repository now has full Bazel build definitions alongside the existing CMake build system. It supports 27 BSW libraries, 6 BSP modules, 2 safety modules, dual RTOS (FreeRTOS/ThreadX), POSIX and ARM platforms, and Rust integration. | ||
|
|
||
| --- | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ```bash | ||
| # Build the reference app (POSIX + FreeRTOS) | ||
| bazel build --config=posix-freertos //executables/referenceApp/application:app | ||
|
|
||
| # Run unit tests | ||
| bazel test --config=unit-test //... | ||
|
|
||
| # Build with Rust support | ||
| bazel build --config=posix-freertos --config=rust //executables/referenceApp/application:app | ||
|
|
||
| # Build the Rust library standalone | ||
| bazel build //executables/referenceApp/rustHelloWorld:rust_hello_world | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 1. Bazel Foundation Files | ||
|
|
||
| | File | Purpose | | ||
| |------|---------| | ||
| | `MODULE.bazel` | Bzlmod module definition — declares rules_cc, rules_rust, platforms deps | | ||
| | `.bazelversion` | Pins Bazel version to 7.6.1 | | ||
| | `.bazelrc` | Build configs: `--config=posix-freertos`, `--config=s32k148-freertos`, `--config=unit-test` | | ||
| | `BUILD.bazel` | Root BUILD file | | ||
|
|
||
| ## 2. Toolchain Configuration | ||
|
|
||
| - **POSIX (host)**: Uses the default CC toolchain — works out of the box. | ||
| - **ARM cross-compilation**: A skeleton `cc_toolchain` for `arm-none-eabi-gcc` is provided in `bazel/toolchains/`. You need to update tool paths for your installation. | ||
|
|
||
| Implementation structure: | ||
|
|
||
| ``` | ||
| bazel/ | ||
| toolchains/ | ||
| BUILD.bazel # cc_toolchain definitions | ||
| arm_none_eabi.bzl # ARM toolchain config (TODO: update tool paths) | ||
| platforms/ | ||
| BUILD.bazel # platform(name="posix"), platform(name="s32k148") | ||
| configs/ | ||
| BUILD.bazel # config_setting for RTOS, platform, feature selection | ||
| app_config/ | ||
| BUILD.bazel # Configurable alias targets for injectable dependencies | ||
| ``` | ||
|
|
||
| ## 3. BUILD Files | ||
|
|
||
| Each library has a `BUILD.bazel` with explicit source lists, headers, and dependencies. **82 BUILD files** were created across: | ||
|
|
||
| - 27 libraries in `libs/bsw/` | ||
| - 6 modules in `libs/bsp/` | ||
| - 6 dependencies in `libs/3rdparty/` (etl, printf, freeRtos, lwip, threadx; googletest uses upstream) | ||
| - 2 modules in `libs/safety/` | ||
| - 2 platforms in `platforms/` (posix fully implemented, s32k1xx skeleton) | ||
| - 2 executables in `executables/` | ||
| - Rust integration in `executables/referenceApp/rustHelloWorld/` | ||
| - Configuration infrastructure in `bazel/` | ||
|
|
||
| **For header-only libraries** (like `async`, `estd`): | ||
|
|
||
| ```python | ||
| cc_library( | ||
| name = "async", | ||
| hdrs = glob(["include/**/*.h"]), | ||
| includes = ["include"], | ||
| deps = ["//libs/bsw/asyncImpl", ...], | ||
| visibility = ["//visibility:public"], | ||
| ) | ||
| ``` | ||
|
|
||
| **For compiled libraries** (like `transport`, `docan`): | ||
|
|
||
| ```python | ||
| cc_library( | ||
| name = "transport", | ||
| srcs = glob(["src/**/*.cpp"]), | ||
| hdrs = glob(["include/**/*.h"]), | ||
| includes = ["include"], | ||
| deps = ["//libs/bsw/common", "//libs/3rdparty/etl", ...], | ||
| visibility = ["//visibility:public"], | ||
| ) | ||
| ``` | ||
|
|
||
| You'll need **~40+ BUILD.bazel files** across: | ||
|
|
||
| - 28 libraries in `libs/bsw/` | ||
| - 6 modules in `libs/bsp/` | ||
| - 7 dependencies in `libs/3rdparty/` | ||
| - 2 modules in `libs/safety/` | ||
| - 2 platforms in `platforms/` | ||
| - 2 executables in `executables/` | ||
|
|
||
| ## 4. Handling Conditional Compilation (RTOS Selection) | ||
|
|
||
| CMake uses `BUILD_TARGET_RTOS` to alias libraries. In Bazel, use `select()`: | ||
|
|
||
| ```python | ||
| cc_library( | ||
| name = "asyncPlatform", | ||
| deps = select({ | ||
| "//bazel/configs:freertos": ["//libs/bsw/asyncFreeRtos"], | ||
| "//bazel/configs:threadx": ["//libs/bsw/asyncThreadX"], | ||
| }), | ||
| ) | ||
| ``` | ||
|
|
||
| With corresponding `config_setting` rules: | ||
|
|
||
| ```python | ||
| config_setting( | ||
| name = "freertos", | ||
| define_values = {"rtos": "freertos"}, | ||
| ) | ||
| ``` | ||
|
|
||
| ## 5. 3rdparty Dependencies | ||
|
|
||
| Since all deps are **vendored in-repo**, wrap each with a BUILD file: | ||
|
|
||
| | Dependency | Approach | | ||
| |---|---| | ||
| | **etl** | `cc_library` with `hdrs = glob(...)` — it's mostly header-only | | ||
| | **freeRtos** | `cc_library` with platform-specific source selection via `select()` | | ||
| | **threadx** | `cc_library` — follow their Bazel support or write custom | | ||
| | **lwip** | `cc_library` — replicate the file list from `Filelists.cmake` | | ||
| | **printf** | `cc_library` — simple single-file library | | ||
| | **googletest** | Already has BUILD.bazel upstream — use it directly or via `MODULE.bazel` | | ||
| | **corrosion** | Not needed — Bazel has native `rules_rust` | | ||
|
|
||
| ## 6. Rust Integration | ||
|
|
||
| Replace Corrosion with **[rules_rust](https://github.com/aspect-build/rules_rust)**: | ||
|
|
||
| ```python | ||
| # MODULE.bazel | ||
| bazel_dep(name = "rules_rust", version = "0.xx.0") | ||
|
|
||
| # executables/referenceApp/rustHelloWorld/BUILD.bazel | ||
| rust_static_library( | ||
| name = "rust_hello_world", | ||
| srcs = ["src/lib.rs"], | ||
| edition = "2021", | ||
| ) | ||
| ``` | ||
|
|
||
| ## 7. `.bazelrc` Configuration | ||
|
|
||
| Mirror the CMake presets: | ||
|
|
||
| ```bash | ||
| # .bazelrc | ||
|
|
||
| # Common | ||
| build --cxxopt=-std=c++14 | ||
| build --conlyopt=-std=c99 | ||
|
|
||
| # POSIX + FreeRTOS | ||
| build:posix-freertos --platforms=//bazel/platforms:posix | ||
| build:posix-freertos --define rtos=freertos | ||
|
|
||
| # S32K148 + FreeRTOS | ||
| build:s32k148-freertos --platforms=//bazel/platforms:s32k148 | ||
| build:s32k148-freertos --define rtos=freertos | ||
| build:s32k148-freertos --crosstool_top=//bazel/toolchains:arm_none_eabi | ||
|
|
||
| # Unit tests | ||
| build:unit-test --define executable=unittest | ||
| test:unit-test --test_output=all | ||
| ``` | ||
|
|
||
| ## 8. Unit Test BUILD Files | ||
|
|
||
| ```python | ||
| cc_test( | ||
| name = "some_test", | ||
| srcs = ["test/SomeTest.cpp"], | ||
| deps = [ | ||
| "//libs/bsw/some_lib", | ||
| "//libs/3rdparty/googletest", | ||
| ], | ||
| ) | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Remaining TODOs | ||
|
|
||
| | Item | Status | Notes | | ||
| |------|--------|-------| | ||
| | POSIX + FreeRTOS build | ✅ Done | Full reference app builds and links (271 actions) | | ||
| | POSIX + ThreadX build | Implemented | Targets defined; needs ThreadX port validation | | ||
| | Unit test framework | Scaffolded | Individual `cc_test` targets need adding per test file | | ||
| | ARM cross-compilation | Skeleton | Update tool paths in `bazel/toolchains/arm_none_eabi.bzl` | | ||
| | S32K1xx BSP drivers | Skeleton | Only bspInterruptsImpl and bspMcu defined; add remaining HW drivers | | ||
| | Rust integration | Implemented | `rules_rust` via MODULE.bazel | | ||
| | `middleware` library | Known issue | `ETL_ASSERT_FAIL` called with string literal vs `etl::exception`; pre-existing code issue | | ||
|
|
||
| ## Key Challenges | ||
|
|
||
| 1. **ARM cross-compilation toolchain** — Update `bazel/toolchains/arm_none_eabi.bzl` with your actual `arm-none-eabi-gcc` paths and compiler flags (`-mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16`). | ||
| 2. **LWIP integration** — Uses `glob()` for sources; verify the glob matches `Filelists.cmake`. | ||
| 3. **FreeRTOS portability** — Platform-specific port files selected via `select()` on `//bazel/configs:posix` vs `//bazel/configs:s32k148`. | ||
| 4. **Config headers** — Application-injected headers (e.g., `FreeRTOSConfig.h`, `lwipopts.h`, `etl_profile.h`) are resolved via `bazel/app_config/` alias targets that switch based on `--define executable=`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These flags globally apply to any kind of build command you issue to bazel.
Instead, they should be applied on a per toolchain basis using features / flag_sets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for sure, I think that was only done as a quick fix since toolchains are not yet properly integrated in this prototypical PR. We already have examples of proper toolchain setups which we can share.