Happy new year folks!
I’d love to get your views on a new approach to multilib. This is a follow up to LLVM Embedded Toolchains Working Group sync up - #19 by voltur01
The problem: for embedded development there are a lot of potential targets to build for, and a toolchain provider should provide a library for each one. It’s typically not obvious to a user of the toolchain which library they should use. A simplified example is if a user wants to build for Cortex-M4 then it may not be obvious whether they should use an armv7m or armv7em library.
The solution is called multilib. The user specifies
-mcpu=cortex-m4 and the multilib system chooses an appropriate library.
Clang already has Multilib and MultilibSet. However that system is too restrictive to be used in the development of LLVM Embedded Toolchain for Arm because:
a) It appears to be designed for the set of available library variants to be hard-coded in clang.
b) It can’t express backwards compatibility.
An example of backwards compatibility:
If I’m building my application with
-mfloat-abi=softfp then I can use a library built with either
-mfloat-abi=soft. The ABI is the same in both cases but the former requires an FPU.
softfp is backwards compatible with
However if I’m building my application with
-mfloat-abi=soft then a multilib system must assume that an FPU isn’t available and must only link with a library that was also built with
This directional compatibility can’t be expressed with Clang’s existing Multilib class.
A solution that was previously proposed was to introduce a DSL and this RFC explores that idea in detail. The idea is to introduce a new file that Clang ToolChains can recognise and parse each time
multilib.yaml expresses both which libraries are available and how to establish their compatibility.
The compatibility model starts with the idea that each library variant requires a set of attributes e.g. armv7m support, hardware floating point support. We can infer the set of available attributes from the command line arguments provided to clang e.g.
-mfloat-abi=hard implies hardware floating point support. As long as the set of attributes on a library is a subset of the attributes inferred from the command line arguments then the library is deemed compatible. If multiple libraries are compatible then the last in the list wins. However the file format could be extended in future to facilitate more sophisticated scoring for better optimisation.
The compatibility detection relies on string matching against command line arguments. However
--target=arm-none-eabi -march=armv7em -mfloat-abi=hard and
--target=thumbv7em-none-eabihf are equivalent so the arguments must be normalised. Clang already normalises arguments before passing them to
clang -cc1 so that functionality is reused.
The proposed format is explained in more detail in the prototype
multilib.yaml: ⚙ Changeset View
The C++ code is not intended to be production quality but I’m very interested to get thoughts on the interface it exposes to the user.