-
-
Notifications
You must be signed in to change notification settings - Fork 31
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
Extensibility guidance - customizing build flags for various embedded platforms #46
Comments
No worries, there is definitely room for improvement in the documentation for this project. I'll answer questions inline and then convert that to more complete docs later.
There are a couple of ways of doing this at the moment. By far the simplest is to do this in your .bazelrc file. e.g.
These configs can be directly run from the command line e.g. The other option to explore is as you mentioned using macros. This is the approach that the pigweed project has taken, a few examples of this here. There is also some documentation that I wrote for the pigweed project here and here that I can likely partially duplicate in this repo regarding configurations with Bazel and more advanced information on platforms.
In terms of configuring flags and default libraries (e.g. libc++/libc) per project this is an area of active improvement and I am working on a far more flexible solution here though that toolchain currently only supports host x86_64 Linux, embedded ARM and RISCV are a WIP. In terms of selecting In terms of RTTI and exceptions, it is currently possible to disable these on all targets from the command line or per target using the set of toolchain features. Though I have just found a bug, filed as #47, in that these should really be inverted e.g. noexceptions. Using these features from the command line;
e.g. from a target; cc_library(
name = "main",
features = ["-exceptions"],
)
It is certainly possible to de-duplicate the flags on the command line, I did try this at some stage but found it quite challenging as I ran into ordering problems. This is certainly something that I exploring but as a lower priority. Just to clarify, using the copts attribute in a As a workaround for the
The makefiles themselves are actually created by STM32Cubemx when generating code. They are however unused in the build. I mostly just use them as a reference to know which files need to be included in the Bazel build and what defines I need. However recently I have been moving towards an approach that doesn't use Cubemx at all. So I can add examples in that regard. I would definitely peruse the Pigweed repo as that is probably the best open-source example that I could point you towards that is using this toolchain.
I will work towards providing better examples. If you have a specific query on open source code I'd be happy to point you in the right direction in the meantime. |
Thanks for the detailed response. I do like the I think one of the things that was throwing me off as I dug through a lot of subcommands output from bazel is that C libraries have fewer flags than CC libraries, and libraries / binaries have different flags as well. I was trying to force this with my own macros, but it appears to happen anyway from bazel/bazel-embedded. In retrospect, that makes sense since RTTI isn't relevant for C (for example). I noticed that -mthumb and -specs=... are only included for my [C++] binary, so I guess they are not relevant for compiling [C] libraries. I suppose this too makes sense since libraries just go to object file format and the whole thing doesn't get converted to [thumb] machine code until you make a binary out of it. Anyway, I'm trying it out using a more elaborate I did notice that passing |
By default, this toolchain disables exceptions as it is very rare to have an embedded RTOS that will correctly handle exceptions. I think the only RTOS that even attempts this is distortOS. As mentioned the features are misnamed and should be more descriptive as described in #47. Also to clarify, the noexceptions feature is enabled by default, do disable it you need to put a '-' in front of the command line. e.g. |
Gotcha, I didn’t realize the minus sign was part of the semantics. Yeah, I wasn’t planning on enabling exceptions I was just using that as an example to understand how to use features. Thanks for the help! |
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 amy_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!
The text was updated successfully, but these errors were encountered: