es-ude / EmbeddedSystemsBuildScripts

Bazel build scripts used for all projects of the embedded systems department
MIT License
4 stars 5 forks source link

How to use arm toolchain #35

Open nicolasfrick opened 3 years ago

nicolasfrick commented 3 years ago

While following the README to build for an ARM Cortex M3 I get stuck with the "default_embedded_binary" -> file '@ArmToolchain//:helpers.bzl' does not contain symbol 'default_embedded_binary' Is it actually possible to build for ARM? A minimal example to set up the WORKSPACE and BUILD files properly would be helpful.

pixelboehm commented 3 years ago

Please import and use default_arm_binary instead of default_embedded_binary, as this is at this point the macro for creating a binary for ARM devices.

pixelboehm commented 3 years ago

For an example on how to set up a BUILD file, please refer to the section Macros in the README.

nicolasfrick commented 3 years ago

@pixelboehm, thanks for your help. I've set up a simple test workspace and get the following build error:

ERROR: BUILD:5:1: Executing genrule //:main failed (Exit 1) bash failed: error executing command /bin/bash -c 'source external/bazel_tools/tools/genrule/genrule-setup.sh; /usr/bin/arm-none-eabi-objcopy -O binary bazel-out/k8-fastbuild/bin/main_ELF bazel-out/k8-fastbuild/bin/main.bin'

Use --sandbox_debug to see verbose messages from the sandbox /usr/bin/arm-none-eabi-objcopy:bazel-out/k8-fastbuild/bin/main_ELF: File format not recognized Target //:main failed to build

Are you using gcc-arm-none-eabi toolchain at the department? Anyway, I paste my workspace setup below.

WORKSPACE load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive( name = "EmbeddedSystemsBuildScripts", strip_prefix = "EmbeddedSystemsBuildScripts-1.0.1", urls = ["https://github.com/es-ude/EmbeddedSystemsBuildScripts/archive/v1.0.1.tar.gz"] )

load("@EmbeddedSystemsBuildScripts//Toolchains/Arm:arm.bzl", "arm_toolchain")

arm_toolchain()

BUILD load("@ArmToolchain//:helpers.bzl", "default_arm_binary", "generate_stm_upload_script")

generate_stm_upload_script(name = "arm_upload")

default_arm_binary( name = "main", srcs = ["main.c"], uploader = "arm_upload", linkopts = ["-T stm32f103xc.ld"] )

pixelboehm commented 3 years ago

Hey,

As far as i can tell, we are using arm-none-eabi-gcc as the toolchain. I'm not sure whether there may be a difference between that and gcc-arm-none-eabi since the tools seem similar (i.e. your error messages states, that it is using arm-none-eabi-objcopy).

I would recommend to install the arm-none-eabi-gcc toolchain. If that does not solve the problem, please tell us which operating system you are using.

Please keep in mind, that the linker script additionally needs to be passed as the parameter additional_linker_inputs in the default_arm_binary macro, as seen in this example:

default_arm_binary(
    name = "main",
    srcs = ["main.c"],
    deps = [":MyLib"],
    uploader = "arm_upload",
    additional_linker_inputs = ["MY_LINKER_FILE.ld"]
    linkopts = ["-T MY_LINKER_FILE.ld"]
)
nicolasfrick commented 3 years ago

Yes, it's the same tool. gcc-arm-none-eabi is just the package name I installed with apt (https://packages.debian.org/de/sid/gcc-arm-none-eabi). Anyway, I removed the package and installed the latest gcc-arm-none-eabi release from https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads. I get the same error.

Regarding your last recommendation, I tried building with the additional_linker_inputs parameter but get this error:

ERROR: BUILD:5:1: //:main_ELF: no such attribute 'additional_linker_inputs' in 'cc_binary' rule ERROR: error loading package '': Package '' contains errors

I guess I have the wrong setup. I tried building with the --platform option and argument gathered from bazel query kind(platform, @AToolchain//platforms/...) and get another error:

$ bazel build //:main --platforms //:arm_ElasticNode

INFO: Build option --incompatible_enable_cc_toolchain_resolution has changed, discarding analysis cache. ERROR: While resolving toolchains for target //:main: Target //:arm_ElasticNode was referenced as a platform, but does not provide PlatformInfo ERROR: Analysis of target '//:main' failed; build aborted: no such target '//:arm_ElasticNode': target 'arm_ElasticNode' not declared in package

I will move to pio for the time being and wait for an example BUILD and WORKSPACE file. Thank you anyway.

pixelboehm commented 3 years ago

I'm going to write a basic example setup here, if it is working, we will introduce that to the wiki:

WORKSPACE file:

workspace(
    name = "example_arm",
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "EmbeddedSystemsBuildScripts",
    strip_prefix = "EmbeddedSystemsBuildScripts-master",
    urls = ["https://github.com/es-ude/EmbeddedSystemsBuildScripts/archive/master.tar.gz"],
)

load("@EmbeddedSystemsBuildScripts//Toolchains/Arm:arm.bzl", "arm_toolchain")

arm_toolchain()

BUILD.bazel file

load("@ArmToolchain//:helpers.bzl", "default_arm_binary", "generate_stm_upload_script")

generate_stm_upload_script(name = "arm_upload")

default_arm_binary(
    name = "main",
    srcs = ["main.c"],
    additional_linker_inputs = ["your_linker_file.ld"],
    copts = [],
    linkopts = ["-T your_linker_file.ld"],
    uploader = "arm_upload",
    deps = [],
)

# This library may be optional on your side
cc_library(
    name = "Startup",
    srcs = ["your-startup-file.s"],
    copts = [
        "-x assembler-with-cpp",
    ],
    visibility = ["//visibility:public"],
    alwayslink = True,
)

.bazelrc file

build --incompatible_enable_cc_toolchain_resolution=true

The following things necessary and should be provided from your side:

Note:

Lastly, if you want to build your project for the Cortex-M4, as it is defined in the platform defintions, the command has to be the following:

bazel build //:main --platforms @ArmToolchain//platforms:arm_ElasticNode

But feel free to write your own platform definitions. You can put those in the BUILD.bazel and can refer to them via

bazel build //:main --platforms //:MyPlatform

The prefix "@ArmToolchain" in the first example is necessary, since the platform is defined in the ArmToolchain, and not in the project itself.

This should solve at least the "building" part of the project. Flashing a binary may need additional configuration on your side, depending on which tool you're want to us to for flashing.

Good luck and please let us know, whether it worked or not. We will then either fix the basic example and/or put in in our documentation.