-
-
Notifications
You must be signed in to change notification settings - Fork 33
Description
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_libraryin amy_cc_librarymacro 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!