While GNAT compiler provides few runtimes for particular MCU/boards, it is a bit complicated to add support for new MCU/boards and to share such runtimes. I would like to discuss another way to construct runtime libraries for bare board applications - automatically generate runtime from the description. There is prototype of the tool to do it:
Right now only runtime is generated, application should provide own startup code and linker script.
If all you need is a light runtime (no tasking), then for Arm and RISC-V you can use the generic light runtimes for a particular CPU core (e.g. light-cortex-m4f for Arm or light-rv32i for RISC-V) that are shipped with GNAT, and use startup-gen to generate the startup code and linker script.
For tasking runtimes there will almost always be some customization required, since some code will be needed to configure the board-specific clock trees and/or timers needed for the runtime’s scheduler. The runtime also needs to be configured with the clock speed that has been configured so that it can correctly calculate task delays. Sometimes there are also other differences in things like interrupt management, depending on the target CPU/board. I’m not sure how your tool would manage those target-specific details?
For generating more custom runtimes, I tend to just reuse & extend the Python tooling from bb-runtimes. For example, a while back I created nrf52-runtimes to generate runtimes for the nrf52832, nrf52833, and nrf52840, each of which has a light, light-tasking, and embedded runtime (so 9 runtimes in total). The runtimes are defined in build-rts.py and there’s some custom sources in nrf52_src (for things like startup code, linker scripts, custom timer implementation), but there’s not much more to it than that to that.
I did take it a step further with nrf52-runtimes, since I wanted to distribute the runtimes in Alire and make them configurable. So I have a script to generate an Alire manifest from a template for each of the 9 runtimes, and I take advantage of crate configuration variables so the user can configure things like which RTC peripheral is used by the runtime and which source to use for the low frequency clock. I also set up a GitHub workflow to manage generating and uploading the generated runtimes as release artifacts. Though, those things aren’t needed if you don’t intend on adding the runtimes to Alire.
I agree with @damaki here. Unless there are fundamental changes in the way GNAT handles run-times or the Ada standard itself. This is mostly a solved problem.
A. No tasking required → startup-gen + (common light-* runtime or bare_runtime)
B. Tasking requirement → Need to customize the run-time in non generic ways
There is some room for improvement in the way run-times are customized, but not much I would say.
I observed few major issues with how runtimes handled now:
Lack of standard packages and language features I want to use (two examples are Ada.Numerics.* hierarchy and wide/wide_wide characters/strings support in light runtime)
Missing support for many cheap and popular boards
Fixed configuration of the clocks for many existing runtimes with tasking support
Compiler switches doesn’t allow to use of light-riscv64 runtime
First point is handled by the runtime generator almost well. Minimal customization of GNAT tasking packages works too.
PS. I was able to run blink-LED with delay 1.0; example on WeAct STM32G431 board last weekend.