Giter Club home page Giter Club logo

bazel-embedded's Introduction

bazel-embedded

CI

drawing

At this point it is relatively easy to add support for new architectures, that have gcc based compilers. In future we will be adding clang support, so that we can make use of clangs static-analyzers. If you would like an architecture added to this repository let us know.

Currently supported hosts:

  • Windows
  • Mac/Unix
  • Linux

Current support is limited to Arm Cortex-M Devices:

  • Cortex M0
  • Cortex M1
  • Cortex M3
  • Cortex M4 (with/out fpu)
  • Cortex M7 (with/out fpu)

What is included

List of support;

  • Toolchains
  • Static analysers
  • A collection of BUILD file templates for common embedded libraries
  • Utilities for programming targets
  • Utilities for debugging targets
  • Parallel execution for a test "farm" of embedded test devices

Our company needs feature X and would pay for its development

Reach out to @silvergasp.

Getting started

Add the following to your WORKSPACE file

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

git_repository(
    name = "bazel_embedded",
    commit = "d3cbe4eff9a63d3dee63067d61096d681daca33b",
    remote = "https://github.com/bazelembedded/bazel-embedded.git",
    shallow_since = "1585022166 +0800",
)

load("@bazel_embedded//:bazel_embedded_deps.bzl", "bazel_embedded_deps")

bazel_embedded_deps()

load("@bazel_embedded//platforms:execution_platforms.bzl", "register_platforms")

register_platforms()

load(
    "@bazel_embedded//toolchains/compilers/gcc_arm_none_eabi:gcc_arm_none_repository.bzl",
    "gcc_arm_none_compiler",
)

gcc_arm_none_compiler()

load("@bazel_embedded//toolchains/gcc_arm_none_eabi:gcc_arm_none_toolchain.bzl", "register_gcc_arm_none_toolchain")

register_gcc_arm_none_toolchain()

load("@bazel_embedded//tools/openocd:openocd_repository.bzl", "openocd_deps")

openocd_deps()

Add the following to your .bazelrc file

# Enable toolchain resolution with cc
build --incompatible_enable_cc_toolchain_resolution

Cross Compile your target

bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m0
bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m1
bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m3
bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m4
bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m7
bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m4_fpu
bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m7_fpu

Explore the examples for more in depth details...

You may choose to upload your code to a microcontroller using the openocd package which allows you to program using SWD or JTAG. An example of this is shown below;

BUILD

load("@rules_cc//cc:defs.bzl", "cc_binary")
load("@bazel_embedded//tools/openocd:defs.bzl", "openocd_debug_server", "openocd_flash")

# This target can be run to launch a gdb server on port 3333
openocd_debug_server(
    name = "main_debug_server",
    device_configs = [
        "target/stm32h7x_dual_bank.cfg",
    ],
    interface_configs = [
        "interface/stlink.cfg",
    ],
    transport = "hla_swd",
)
# The target to flash
cc_binary(
    name = "main",
    srcs = ["main.cc"],
    linkopts = [
        # app_code.ld is a linker script in the same directory
        "-T $(location :app_code.ld)",
        "-lc",
        "-lm",
        "-lnosys",
        "-u _printf_float",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":app_code.ld",
        "//libs/cpp/board_support:board_support_package",
    ],
)
# Run this target to upload to the microcontroller
openocd_flash(
    name = "main_flash",
    device_configs = [
        "target/stm32h7x_dual_bank.cfg",
    ],
    image = ":main.stripped",
    interface_configs = [
        "interface/stlink.cfg",
    ],
    transport = "hla_swd",
)

Alternatively, an execution wrapper can be used to execute a binary on an embedded target using openocd, and bazel's --run_under command line option.

BUILD

load("@bazel_embedded//tools/openocd:defs.bzl", "openocd_execution_wrapper")

openocd_execution_wrapper(
    name = "test_wrapper",
    baud_rate = "115200",
    device_configs = [
        "target/stm32h7x_dual_bank.cfg",
    ],
    fail_string = "FAILED",
    interface_configs = [
        "interface/stlink.cfg",
    ],
    port = "/dev/ttyACM0",
    success_string = "PASSED",
    transport = "hla_swd",
)
bazel run //:your_target --platforms=@bazel_embedded//platforms:cortex_m7_fpu --run_under=//:test_wrapper
bazel test //:your_target --platforms=@bazel_embedded//platforms:cortex_m7_fpu --run_under=//:test_wrapper

This will pipe the serial output from the microcontroller over /dev/ttyACM0 to stdout. If a line contains 'PASSED', the wrapper will return 0, if a line contains 'FAILED' the wrapper will return 1. This is useful if you are wrapping a cc_test. If success_string or fail_string is not specified, the wrapper will not exit unless sent a sigterm (e.g. by CTRL-C). Leaving these empty can be useful when wrapping a standard cc_binary.

How to have your embedded code coexist with host code

There are a number of cases where you may want to build and test everything but running.

bazel build //...

However by default this will capture and build all libraries for the host. This includes libraries that are only compatible with the host system. This can lead to scenarios where code will not compile on your host breaking a wildcards for building. As of bazel 4.0, incompatible target skipping is now supported which allows you to specify the constraint_values that your target is compatible. Bazel will then skip targets included in the wildcard that are not supported. If a target is built with the wrong target explicitly bazel will issue a warning saying that your target is not supported with the given platform.

e.g.

# Linux only
cc_library(
    name = "linux_only_lib",
    srcs = ["some_lib.cc"],
    target_compatible_with = [
        "@platforms//os:linux",
    ],
)

# Compatible with everything
cc_library(
    name = "generic",
    srcs = ["generic.cc"],
)

# Cortex m4 only
cc_library(
    name = "cortex_m4_only_lib",
    srcs = ["some_lib_m4.cc"],
    target_compatible_with = [
        "@platforms//cpu:armv7e-m",
    ],
)

# All cortex-m architectures
cc_library(
    name = "cortex_m_all_lib",
    srcs = ["some_lib_m_all.cc"],
    # Allow all cortex m architectures using a select statement. Reject anything else
    target_compatible_with = select({
        "@platforms//cpu:armv6-m": [],
        "@platforms//cpu:armv7-m": [],
        "@platforms//cpu:armv7e-m": [],
        "//conditions:default": ["@platforms//:incompatible"],
    ],
)

# Depends on platform specific target therefore can only be built with cortex m4
cc_library(
    name = "depends_on_m4",
    deps = [":cortex_m4_only_lib"],
)

For reference the following architectures constraint values map to cpu layouts.

"@platforms//cpu:armv6-m" -> Cortex-M0, Cortex-M0+, Cortex-M1

"@platforms//cpu:armv7-m" -> Cortex-M3

"@platforms//cpu:armv7e-m" -> Cortex-M4, Cortex-M7

Feature configuration

Bazel can be configured using features. Each toolchain in this repository aims to implement a consistent behaviour for a given set of features. The list of available configuration features can be listed using the following command.

bazel run @bazel_embedded//toolchains/features:print_all_features

From here you may use each feature from the command line, the following example enables all warnings as errors and optimises for release;

bazel build //toolchains/compilation_tests/... --platforms=@bazel_embedded//platforms:cortex_m0 --features=all_warnings_as_errors,opt

bazel-embedded's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

bazel-embedded's Issues

GCC toolchain declaration shouldn't use global platforms

Hi,

I think I bumped into an issue regarding toolchain - platform compatibility. Namely, in toolchains/gcc_arm_none_eabi/gcc_arm_none_toolchain.bzl there's defined a list of allowed architectures which, among other options, contains armv8-m.base that I'm currently using in my project.

This option is not available in bazel's platforms so once toolchain resolution comes to "@platforms//cpu:" + architecture, it breaks.

An alternative would probably be to use "//constraints/cpu:" + architecture, so that it uses CPUs defined in workspace which can then be used both when declaring platforms, and devices (used by toolchains).

My setup works with that approach, but I'm not sure if it could have undesired consequences elsewhere. What do you think about that?

Unable to build sample on Windows 11

When running the arm-none-eabi-simple example on Windows 11, I get the following error:

Error in fail: OS configuration not available for: windows 11

It appears that when I run gcc_arm_none_compiler(), it calls get_platform_specific_config to determine the toolchain config, but windows 11 is not a supported key.

Add support for generating .map files

I'm not too familiar with bazel toolchain specifications, so I'm not sure which component would be responsible for this, but I'd like to have .map files generated alongside the elf files when using bazel_embedded platforms. Is that something that's been looked at?

Add support for mac-osx and windows

As it currently stands only linux is fully supported. The following functionality needs to be added and tested for complete cross platform support.
OSX:

  • Openocd repository fetch
  • Openocd runs as expected when integrating with debugger hardware
  • Add to CI

Windows:

  • Openocd repository fetch
  • Openocd runs as expected when integrating with debugger hardware
  • Compiler support
  • Add to CI

Toolchain resolution seemingly failing and falling back to /usr/bin/gcc in some cases

I'm having trouble with the bazel-embedded rules in some cases. In a plain Ubuntu host, I can build my target with --platforms=@bazel_embedded//platforms:cortex_m7_fpu and it works fine and invokes external/bazel_embedded/toolchains/gcc_arm_none_eabi/gcc_wrappers/nix/gcc

(cd /home/parallels/.cache/bazel/_bazel_parallels/14af9fa9524e44cf06682e101a7eaa03/execroot/haystack && \
  exec env - \
    PATH=/home/parallels/.cache/bazelisk/downloads/bazelbuild/bazel-4.2.1-linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/parallels/go/bin:/home/parallels/gcc/gcc-arm-none-eabi-10-2020-q4-major/bin:/home/parallels/.gem/ruby/2.7.0/bin \
    PWD=/proc/self/cwd \
  external/bazel_embedded/toolchains/gcc_arm_none_eabi/gcc_wrappers/nix/gcc

However when I run the same thing in a docker environment (based on Ubuntu) it attempts to use /usr/bin/gcc and fails because -mthumb doesn't exist.

(cd /root/.cache/bazel/_bazel_root/18e8352205c71478753c3b63796033c0/execroot/haystack && \
  exec env - \
    PATH=/root/.cache/bazelisk/downloads/bazelbuild/bazel-4.2.1-linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
    PWD=/proc/self/cwd \
  /usr/bin/gcc ...

I used the --toolchain_resolution_debug flag and interestingly, in both the working and non-working case it output the exact same thing (I diff'd and they were exactly the same):

Starting local Bazel server and connecting to it...
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: target platform @bazel_embedded//platforms:cortex_m7_fpu: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv6-m_none; mismatching values: armv6-m, none
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: target platform @bazel_embedded//platforms:cortex_m7_fpu: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7-m_none; mismatching values: armv7-m, none
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: target platform @bazel_embedded//platforms:cortex_m7_fpu: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv4-sp-d16; mismatching values: fpv4-sp-d16
INFO: ToolchainResolution:   Type @bazel_tools//tools/cpp:toolchain_type: target platform @bazel_embedded//platforms:cortex_m7_fpu: execution @local_config_platform//:host: Selected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m0: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m1: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m3: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m4: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m4_fpu: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m7: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:cortex_m7_fpu: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:stm32f2xx: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:stm32f3xx: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:stm32f4xx: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:stm32f7xx: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:stm32g4xx: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: execution platform @bazel_embedded//platforms:stm32h7xx: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16; mismatching values: x86_64
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: target platform @bazel_embedded//platforms:cortex_m7_fpu: Rejected toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_none; mismatching values: none
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: target platform @bazel_embedded//platforms:cortex_m7_fpu: Rejected toolchain @local_config_cc//:cc-compiler-armeabi-v7a; mismatching values: arm, android
INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: target platform @bazel_embedded//platforms:cortex_m7_fpu: Rejected toolchain @local_config_cc//:cc-compiler-k8; mismatching values: x86_64, linux
INFO: ToolchainResolution: Target platform @bazel_embedded//platforms:cortex_m7_fpu: Selected execution platform @local_config_platform//:host, type @bazel_tools//tools/cpp:toolchain_type -> toolchain @bazel_embedded//toolchains/gcc_arm_none_eabi:arm_none_eabi_armv7e-m_fpv5-d16
INFO: ToolchainResolution: Target platform @bazel_embedded//platforms:cortex_m7_fpu: Selected execution platform @local_config_platform//:host, 
INFO: ToolchainResolution: Target platform @local_config_platform//:host: Selected execution platform @local_config_platform//:host, 
INFO: ToolchainResolution: Target platform @local_config_platform//:host: Selected execution platform @local_config_platform//:host, 

Understanding the "Getting started" example code: register_execution_platforms() registers target platforms?

Hi,
the following is not an issue or a bug, but a request for better understanding - hope "Issues" is the right place, I didn't find a mailing list of alike for bazel-embedded.

I was trying to walk down the logic that starts at

load("@bazel_embedded//platforms:execution_platforms.bzl", "register_platforms")
register_platforms()

Following this call, it ends up at register_execution_platforms() which essentially passes platform() rules which define all sort of CMx CPUs.
As per Bazel's definition of an execution platform ("execution platform runs the build actions", see https://bazel.build/docs/platforms)
there seems to be a mismatch, at least in my understanding: A CMx is not an execution platform, it's a target platform.

Furthermore, if I look at an actual platform() rule, I find sth like this

platform(
     name = "cortex_m0",
     exec_properties = {
         "EXECUTOR": "cortex_m",
     },
     parents = [":cortex_m"],
)

exec_properties is a "map of strings that affect the way actions are executed remotely. Bazel makes no attempt to interpret this."
This kind of leads me to the assumption that "EXECUTOR" is some sort of tag or attribute which is used during the build actions
and which does "something" there. I haven't really found out what this "something" actually is or whether this assumption is true.

So, all in all:

  • I could use some help in understanding the execution versus target platform "mismatch" as explained above.
  • I would like to better understand what this "EXECUTOR" string is actually doing further down the line.

Hope this is the right place to ask these questions ... :-)
Thx
Arndt

Windows build does not include system headers

When building on Linux, the system headers are included in the build command, for example I can clearly see -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/c++/9.2.1 added to the command line

Linux:

  external/bazel_embedded/toolchains/gcc_arm_none_eabi/gcc_wrappers/nix/gcc -MD -MF bazel-out/k8-fastbuild/bin/stm32g4_example/_objs/main.elf/sysmem.d '-frandom-seed=bazel-out/k8-fastbuild/bin/stm32g4_example/_objs/main.elf/sysmem.o' -DUSE_HAL_DRIVER -DSTM32G473xx -iquote . -iquote bazel-out/k8-fastbuild/bin -iquote external/STM32CubeG4 -iquote bazel-out/k8-fastbuild/bin/external/STM32CubeG4 -iquote external/bazel_tools -iquote bazel-out/k8-fastbuild/bin/external/bazel_tools -isystem stm32g4_example/Core/Inc -isystem bazel-out/k8-fastbuild/bin/stm32g4_example/Core/Inc -isystem external/STM32CubeG4/Drivers/STM32G4xx_HAL_Driver/Inc -isystem bazel-out/k8-fastbuild/bin/external/STM32CubeG4/Drivers/STM32G4xx_HAL_Driver/Inc -isystem external/STM32CubeG4/Drivers/CMSIS/Include -isystem bazel-out/k8-fastbuild/bin/external/STM32CubeG4/Drivers/CMSIS/Include -isystem external/STM32CubeG4/Drivers/CMSIS/Device/ST/STM32G4xx/Include -isystem bazel-out/k8-fastbuild/bin/external/STM32CubeG4/Drivers/CMSIS/Device/ST/STM32G4xx/Include -isystem stm32g4_example -isystem bazel-out/k8-fastbuild/bin/stm32g4_example -Wall -Wpedantic '-Werror=date-time' -nostdinc -no-canonical-prefixes -fno-canonical-system-headers -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/newlib-nano -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/c++/9.2.1 -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/c++/9.2.1/arm-none-eabi -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/c++/9.2.1/backward -isystemexternal/com_gcc_arm_none_eabi_compiler/lib/gcc/arm-none-eabi/9.2.1/include -isystemexternal/com_gcc_arm_none_eabi_compiler/lib/gcc/arm-none-eabi/9.2.1/include-fixed -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include '-isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi-D__USES_INITFINI__/dev/null-mcpu=arm7tdmi-mfloat-abi=soft-marm-march=armv4t' -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/newlib-nano -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/c++/9.2.1 -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/c++/9.2.1/arm-none-eabi -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include/c++/9.2.1/backward -isystemexternal/com_gcc_arm_none_eabi_compiler/lib/gcc/arm-none-eabi/9.2.1/include -isystemexternal/com_gcc_arm_none_eabi_compiler/lib/gcc/arm-none-eabi/9.2.1/include-fixed -isystemexternal/com_gcc_arm_none_eabi_compiler/arm-none-eabi/include -ffunction-sections -fdata-sections '-march=armv7e-m' '-mfpu=fpv4-sp-d16' '-mfloat-abi=hard' -mlittle-endian -O -ffreestanding -fno-common -fstack-protector-strong -c stm32g4_example/Core/Src/sysmem.c -o bazel-out/k8-fastbuild/bin/stm32g4_example/_objs/main.elf/sysmem.o)

However on Windows none of the system includes are added to the command line, as a result my build fails when including any system headers.

Windows:

external/bazel_embedded/toolchains/gcc_arm_none_eabi/gcc_wrappers/windows/gcc.bat -MD -MF bazel-out/x64_windows-fastbuild/bin/stm32g4_example/_objs/frames/frames.d -frandom-seed=bazel-out/x64_windows-fastbuild/bin/stm32g4_example/_objs/frames/frames.o -iquote . -iquote bazel-out/x64_windows-fastbuild/bin -isystem stm32g4_example -isystem bazel-out/x64_windows-fastbuild/bin/stm32g4_example -Wall -Wpedantic -Werror=date-time -nostdinc -no-canonical-prefixes -fno-canonical-system-headers -isystem external/bazel_embedded_upstream_toolchain -ffunction-sections -fdata-sections -march=armv7e-m -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mlittle-endian -O -ffreestanding -fno-common -fstack-protector-strong -c bazel-out/x64_windows-fastbuild/bin/stm32g4_example/frames.c -o bazel-out/x64_windows-fastbuild/bin/stm32g4_example/_objs/frames/frames.o

Same command line for both cases:

bazel build -s //stm32g4_example:main --platforms=@bazel_embedded//platforms:cortex_m4_fpu

README doesn't mention openocd WORKSPACE requirements

I had trouble getting openocd targets working initially until I dug deeper and realized I need to add this to the WORKSPACE

load("@bazel_embedded//tools/openocd:openocd_repository.bzl", "openocd_deps")

openocd_deps()

The README should mention it.

Objcopy executable path not found?

I've been trying to use objcopy from the existing toolchains generated through this system. I'm a bit surprised to see that the path for objcopy is just empty... Am I doing something wrong? I want to create a simple rule to make a binary from the generated elf... Would love alternate suggestions:

def _impl(ctx):                           
    toolchain = find_cc_toolchain(ctx)    
    print(toolchain.cc.objdump_executable)
    print(toolchain.cc.objcopy_executable)

gen_binary = rule(                                   
    implementation = _impl,                          
    toolchains = [                                   
    ·   "@rules_cc//cc:toolchain_type",              
    ],                                               
    attrs = {                                        
    ·   "_cc_toolchain": attr.label(                 
    ·   ·   default = Label(                         
    ·   ·   ·   "@rules_cc//cc:current_cc_toolchain",
    ·   ·   ),                                       
    ·   ),                                           
    ·   "src": attr.label(allow_single_file = True), 
    },                                               
    outputs = {                                      
    ·   "elf": "%{name}.elf",                        
    ·   "bin": "%{name}.bin",                        
    },                                               
)                                                    

With the command:

bazel build //bootloader --platforms=@bazel_embedded//platforms:cortex_m4_fpu

and I get the following:

DEBUG: /.../project/toolchains/platforms.bzl:29:10: external/bazel_embedded/toolchains/gcc_arm_none_eabi/gcc_wrappers/nix/objdump
DEBUG: /.../project/toolchains/platforms.bzl:30:10:  <--- This is the objcopy print statement

Best approach for integrating a non-ARM toolchain

I'm working on integrating a riscv32 toolchain so I can use bazel-embedded as the compiler configuration for the OpenTitan project (https://opentitan.org). It appears there are some incompatible flags between ARM and riscv32 gcc compilers.

Experimentally, I'm handling these flag differences with if statements in toolchains/features/common/impl/gcc.bzl and toolchains/features/embedded/impl/gcc.bzl. This seems ugly to me and that it would be more appropriate to elevate some of the compiler flag selections to the platform or device configurations in platforms/BUILD and/or devices/riscv32/riscv32.bzl. (See lowRISC#1)

I'm creating this issue to solicit feedback on the best approach.

Bazel 7 support

ctx.host_configuration was removed in bazel 7.0 as of this commit. Because of this, _gcc_arm_none_toolchain_config_info_impl will fail when calling gcc_arm_none_toolchain. I'm not sure if there's more changes in 7.0 that prevent updating, but this was the first I see when running.

SunCertPathBuilderException: unable to find valid certification path to requested target

I started receiving this build failure today. This is running in a github workflow which had been fine for weeks up until today.

INFO: Repository com_gcc_arm_none_eabi_compiler instantiated at:
  /github/workspace/WORKSPACE:186:22: in <toplevel>
  /github/home/.cache/bazel/_bazel_root/3ef6b2ad9cc100f006a5d4a7217ff063/external/bazel_embedded/toolchains/compilers/gcc_arm_none_eabi/gcc_arm_none_repository.bzl:89:28: in gcc_arm_none_compiler
Repository rule gcc_arm_none_repository defined at:
  /github/home/.cache/bazel/_bazel_root/3ef6b2ad9cc100f006a5d4a7217ff063/external/bazel_embedded/toolchains/compilers/gcc_arm_none_eabi/gcc_arm_none_repository.bzl:77:42: in <toplevel>
WARNING: Download from https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=6e63531f-8cb1-40b9-bbfc-8a57cdfc01b4&la=en&hash=F761343D43A0587E8AC0925B723C04DBFB848339 failed: class javax.net.ssl.SSLHandshakeException PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
ERROR: An error occurred during the fetch of repository 'com_gcc_arm_none_eabi_compiler':
   Traceback (most recent call last):
	File "/github/home/.cache/bazel/_bazel_root/3ef6b2ad9cc100f006a5d4a7217ff063/external/bazel_embedded/toolchains/compilers/gcc_arm_none_eabi/gcc_arm_none_repository.bzl", line 30, column 40, in _com_gcc_arm_none_repository_impl
		repository_ctx.download_and_extract(
Error in download_and_extract: java.io.IOException: Error downloading [https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=6e63531f-8cb1-40b9-bbfc-8a57cdfc01b4&la=en&hash=F761343D43A0587E8AC0925B723C04DBFB848339] to /github/home/.cache/bazel/_bazel_root/3ef6b2ad9cc100f006a5d4a7217ff063/external/com_gcc_arm_none_eabi_compiler/temp17661210164835272010/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
ERROR: Error fetching repository: Traceback (most recent call last):
	File "/github/home/.cache/bazel/_bazel_root/3ef6b2ad9cc100f006a5d4a7217ff063/external/bazel_embedded/toolchains/compilers/gcc_arm_none_eabi/gcc_arm_none_repository.bzl", line 30, column 40, in _com_gcc_arm_none_repository_impl
		repository_ctx.download_and_extract(
Error in download_and_extract: java.io.IOException: Error downloading [https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=6e63531f-8cb1-40b9-bbfc-8a57cdfc01b4&la=en&hash=F761343D43A0587E8AC0925B723C04DBFB848339] to /github/home/.cache/bazel/_bazel_root/3ef6b2ad9cc100f006a5d4a7217ff063/external/com_gcc_arm_none_eabi_compiler/temp17661210164835272010/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
ERROR: no such package '@com_gcc_arm_none_eabi_compiler//': java.io.IOException: Error downloading [https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=6e63531f-8cb1-40b9-bbfc-8a57cdfc01b4&la=en&hash=F761343D43A0587E8AC0925B723C04DBFB848339] to /github/home/.cache/bazel/_bazel_root/3ef6b2ad9cc100f006a5d4a7217ff063/external/com_gcc_arm_none_eabi_compiler/temp17661210164835272010/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I'm unfamiliar with how Bazel + JDK manage certificates, so I'm not entirely sure if this is an issue specific to the bazel-embedded rules.

Target 'wasm64' not declared

When building my simple test project as follows:

bazel build //main:test --platforms=@bazel_embedded//platforms:cortex_m0

 no such target '@platforms//cpu:wasm64': target 'wasm32' not declared in package 'cpu'
 no such target '@platforms//cpu:wasm64': target 'wasm64' not declared in package 'cpu'

I had to manually add the 2 cpu to ../external/platforms/cpu/BUILD . Then it compiled.

Feature request: Support llvm-embedded-toolchain-for-arm

Were there any considerations for including https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm in the supported toolchains? It seems to be the home of the ARM-endorsed LLVM-toolchain. Their release-cycle is awesome, much better than the corresponding ARM-gcc toolchain, so it's the place to be if you want to use latest C++ features in your embedded projects. Also, switching from the newlib-based ARM-gcc to the picolibc-based LLVM-arm-embedded reduced our image sizes by ~150 kB due to better control of which symbols from libc get pulled in (mostly locale stuff that we don't need).

Extensibility guidance - customizing build flags for various embedded platforms

This is not a bug, but rather a request for information and/or documentation for your project. I'm a big fan, by the way, and the use of the long awaited platforms capabilities of bazel looks very promising. Last time I looked at this 3-5 years ago bazel was in an awkward transition from crosstool-style to platforms-style and everything was sort of half baked and not read yet.

Can you comment, here or in the project README, about what would be a good strategy for extending your project to customize it for a particular hardware platform? To be more specific I mean:

-> a set of custom copts/defines/includes for a given platform (ie, one Cortex-M MCU versus another; one board versus another, whatever).
-> customized copts/defines/includes for .S, .c, and .cc files, possibly also customized per target/library, and extensible to other target platforms should the need arise to switch microcontrollers

To get something working quickly, and because I'm not a bazel/skylark expert, I've started by wrapping the compatible-with cc_binary and cc_library you have set up with macros, adding in copt/include/define flags as necessary to match the recommended flags used by the target hardware and third party libraries. I tacked on an objcopy genrule to generate binary files from the .elf. Things like that. This works ok but has a number of unfortunate consequences that worry me long term:

  • wrapping cc_library in a my_cc_library macro is quick and easy but is obviously not extensible to other devices. While this is probably acceptable for drivers which could only run on one target platform, for higher level [c++] code it would be nice if I stuck with the native library/binary and instead extended the rules or toolchain in bazel-embedded. I don't know how to do this, but just like you customize M4F -> fpu/cpu copt flags, there might be a level where you select {Vendor, Product} -> copt flags, or even {Project, Vendor, Product} -> copt flags. For example, maybe one project uses no RTTI and no exceptions but another project does use them. Maybe the two share some pieces of a monorepo and maybe they run on the same type of device or maybe on distinct devices.

  • a lot of bazel target attributes (copts, defines, etc) are inherited/propagated: the copts of dependencies show up in the copts of libraries/binaries which depend upon them, producing an ever increasing chain of duplicated flags the more hierarchy there is. This works ok for something quick, but it's super verbose on the command line to have a copt flag duplicated for every level of hierarchy, and a more serious case I ran into is that gcc doesn't allow certain flags to be duplicated (like -specs=nano.specs) even if they're identical in each duplicate.

I guess what I'm asking is: what is the recipe for extending this nice set of features you have in bazel-embedded to customize it for a hardware platform? I don't particularly understand your STM32 examples with makefiles...why are there makefiles anyway if we're using bazel? Do I somehow add more "features" like you have for cpu/fpu? Do I do something else? I have an NXP driver library building in bazel, as well as startup code and various linker scripts, and the BUILD targets are super clean thanks to bazel and bazel-embedded. But, my issue is more about whether macros is the best way to do this, and the above issues with managing copt flags.

Could you show an example strategy that includes a set of compilation flags for .S files, a different set for .c files, a different set for .cc files? Ideally this would be specific to a hardware platform like stm_xyz or nxp_xyz, and not as generic as "arm-v7-m" or whatever architecture or core is used. I already have something like this somewhat working with my macros for a single target device, but for the aforementioned reasons, I suspect I may be doing it wrong!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.