[cfe-dev] Single instance 'clang', multi-target support for headers and libraries

Martin J. O'Riordan via cfe-dev cfe-dev at lists.llvm.org
Fri Jun 8 04:24:18 PDT 2018


Thanks Peter, responses inline ...

-----Original Message-----
From: Peter Smith [mailto:peter.smith at linaro.org] 
Sent: 07 June 2018 14:44
To: Martin J. O'Riordan <MartinO at theheart.ie>
Cc: Clang Dev <cfe-dev at lists.llvm.org>
Subject: Re: [cfe-dev] Single instance 'clang', multi-target support for headers and libraries

Hello Martin,

Sadly I'm not sure I can offer you much advice, I've put some comments and questions inline.

On 7 June 2018 at 11:44, Martin J. O'Riordan via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> This is question I believe is mostly a CLang issue, though there are 
> some interactions with LLVM, LibC++, Compiler-RT, LibCLC, and so on.

I suspect that this is more of a Toolchain creation issue rather than just clang. From what I can surmise there are two parts to this:
- How do I build an embedded toolchain based on clang that has per-target C libraries, compiler-rt, libcxx etc.
- Given such a toolchain how do we do as much of the library/include selection based on the target.

> For the most part the compilers I work on are cross-compilers for 
> embedded systems with varying degrees of OS support (from none at all, 
> to pretty much everything), and things like the local host’s suite of 
> header files are entirely inappropriate.

Agreed.

> If I configure and build GCC for a particular target triple with a 
> specific C library (e.g.: ‘glibc’, ‘newlib’, ‘uclibc’, ‘musl’), then 
> the corresponding suites of headers and libraries are particular to 
> that configuration.

I'm unfortunately not that familiar with building GCC. Just to confirm that you mean that these are the libraries/includes that the GCC cross compiler will use, and not libraries/includes that the GCC cross compiler will be built with.

[MartinO--> ] SFAIK, when GCC is given a different target triple, it looks for '<target-triple>-gcc' and uses it instead.  This in turn looks for target specific headers in '<target-triple>/include', auxiliary binaries (e.g.: 'as' or 'ld') in '<target-triple>/bin' and target specific libraries in '<target-triple>/lib'.  This makes the usage a lot more straightforward as there is no need to explicitly provide '-sysroot', or '-L' options to override defaults as the target specific 'gcc' automatically refers to target specific versions.

> The built cross-compiler has a sub-directory named after the triple (e.g.:
> ‘foo-unknown-elf’) which contains the ‘include’, ‘bin’ and ‘lib’ 
> directories specific to this particular configuration, and this allows 
> me to also configure and build GCC for multiple targets with different 
> choices of supporting C libraries, and they can co-exist in the same 
> base directory without cross contaminating each other.

By cross-compiler do you mean the cross toolchain? For example my gcc embedded toolchain has a (simplified) dir structure:
toolchain/arm-none-eabi/bin
toolchain/arm-none-eabi/lib
toolchain/arm-none-eabi/include
There is also
toolchain/lib/gcc/arm-none-eabi/7.2.1/...
With the main compiler binary in
toolchain/bin/arm-none-eabi-gcc (alongside the other binutils)

Do you mean the toolchain/(triple) directory here? If so I'm guessing that this is more along the lines of toolchain construction than building clang.

[MartinO--> ] Yes, this is what I meant, though toolchain conventions and the driver in 'clang' are intertwined.

> I would like to do something similar with CLang/LLVM but there does 
> not appear to be a convention for doing this, even though CLang 
> (unlike GCC) can have a single compiler instance that can handle multiple targets.

I'm not aware of such a convention either (at least outside the resource dir).

[MartinO--> ] The GCC approach allows for additional cross-compilers to be installed at different times, but there is a discrete set of toolchain binaries for each cross-compiler.  CLang is different to GCC in its ability to have a single binary instance support multiple targets (which I find really useful by the way).

> A related aspect is that if I want to also build the supporting 
> libraries for the selected target (e.g.: ‘libc++’, ‘compiler-rt’), 
> then I really need the CMake configuration tools for the LLVM projects 
> to be able to incorporate building the selected C library in advance 
> of cross-compiling these other libraries; that is, the ‘include’ files 
> from the selected C library would need to be staged as part of the 
> build process, and the libraries (e.g.: ‘libc’, ‘libm’) would also 
> need to be built for this cross-compiled target, before ‘libc++’ or 
> the ‘compiler-rt’ libraries are built.

If I understand you correctly you want to integrate the build system of third party C-libraries into CMAKE? Or is it limited to just selecting the header files from each of the C-libraries.

AFAIK there is a cmake recipe to build compiler-rt (when placed in the runtimes directory) for multiple arm M class configurations. I think adding more clang recipes might be one way to go.

[MartinO--> ] Sort of.  I am musing about this, but I thought that it might be possible to have a convention which would allow a particular target to provide a configuration CMake recipe for building and installing the desired C libraries and headers using the "just built" clang, and ahead of building the other libraries.  If this recipe is not present then no C library customisation is assumed.

> Typically I would like to build CLang and libraries to support one or 
> more cross-targets plus the local host target, and then choose which 
> target I want at runtime using the triple.  For example, let’s say I 
> want to support two targets ‘foo’ and ‘bar’, plus the local target; 
> then I would like configure my build (one possible configuration choice) so that:
>
> ·         target ‘foo’ prepares and builds the C library based on Newlib
> ·         target ‘bar’ prepares and builds the C library based on uClibc
> ·         local target uses the existing installed C library support on the host
>
> Are there any plans within the LLVM community to standardise how to do 
> this kind of build?  The CLang Driver would need to adopt conventions 
> that would allow this, and I think that perhaps a new CMake module 
> could be added that would optionally prep & stage a selected and 
> supported C library for a cross-compiler configuration, and that this 
> could be made an optional dependency of the libraries which are to be 
> cross-compiled (‘libc++’ and ‘compiler-rt’).

I think that this would probably be classed as a toolchain build outside of the scope of the LLVM project. I guess the main problem is where do you stop, there are a huge number of possible combinations of libraries and configurations, which ones would be supported, who would test them? I think that there is scope for collaboration and improvement in this area, but it might be best to start outside of the existing build system.

[MartinO--> ] Yes, I expect this is the case :-(

> Related to this is how to build and manage the equivalent of GCC’s 
> MULTILIBs for cross-compiler targets in a regularised way.

I certainly think that improvements to how clang could work with MULTILIB would be welcome. My understanding is that there is some driver specific multilib support but nothing in the existing BareMetal driver. I think that this would be a great place to start in improving clang support for embedded toolchains.

> Does anybody have any experience of doing this kind of thing with 
> CLang, and advice on how I should approach this?  So far I have done 
> this in an ad-hoc way for each of my intended targets, and use 
> intermediate non-integrated build processes to ensure that the right 
> headers and C libraries are prepared in advance of being used by the 
> subsequent dependent libraries from the LLVM project.

I think that the general problem is much harder and messier than the ad-hoc so as far as I know most people have made an ad-hoc solution for the use case that they want to support, but there isn't an easy way to scale it to take into account everyone's use case. I think it would be great to start with improving the clang bare metal driver so that we can drop a clang cross compiler into an existing gcc embedded toolchain (with existing multilibs), or at least something built with the same structure. This is the "Given such a toolchain how do we do as much of the library/include selection based on the target."  which is, I think, more of a tractable problem than the building a toolchain part. I sadly don't have enough CMake or toolchain build experience to say much about the toolchain build process; I feel like the problem seems a bit too wide in scope to be practical, is there any way of narrowing it down.

Peter

[MartinO--> ] Agreed.  Thanks for your comments and feedback Peter.

> Thanks,
>
>             MartinO
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





More information about the cfe-dev mailing list