I recently sent a message that may or may not have made it to the list,
on problems building an LLVM cross-compiler. Now the issue seems clear
to me and is irrelevant at this point, I would like to discuss the general
issue.
Suppose you have a host system, a Linux distribution on an x86_64 machine,
and want to build a cross-compiler for aarch64 (or any platform supported
by LLVM, other than an AMD-/Intel-based machine) to cross compile a Linux
distribution.
The process, in my opinion, should go like this:
1. Get the sources (llvm, lld, compiler-rt, libunwind, libcxx...).
2. Build an LLVM cross-compiler toolchain using native distribution's
compiler (i.e. build an x86_64 clang executable that targets aarch64).
3. Cross-compile libc and other libraries/dependencies to run the
userland.
4. Cross-compile the userland.
With LLVM it doesn't work:
1. You got the sources.
2. Built clang targetting, among others or only, aarch64/mips/etc.
3. Clang requires compiler-rt but you need to cross-compile compiler-rt
for the target platform. *You don't have a cross-compiler*.
It stops after that. To build compiler-rt you need C headers, libc
runtimes, *and libclang_rt.a*. You can't cross-compile libc because you
don't have compiler-rt because you don't have libc. Chicken or egg.
I.e. you need a cross-compiler to build a cross-compiler.
So, how do you build an LLVM-based cross-compiler?
I hope I am wrong in my assumptions and if it's so, please forgive me.
I also hope I made it clear.
Thanks for taking time and have a nice weekend!
--
caóc
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
This can be done either by using the `LLVM_ENABLE_RUNTIMES` CMake option (see DistributionExample-stage2.cmake in clang/cmake/caches), or by treating compiler-rt/lib/builtins as the top-level CMake file.
I would strongly suggest that you start with one of the CMake cache files under clang/cmake/caches as an example because setting up the CMake options to build a toolchain that can cross-compile is sadly quite complicated.
-Chris
> On Nov 6, 2020, at 4:13 PM, Cág via llvm-dev <llvm...@lists.llvm.org> wrote:
>
> Hi everyone,
Chris Bieneman wrote:
> You’ve hit on one of the odd historical messes in LLVM. Compiler-RT
> can’t really be treated as a monolithic set of libraries when you are
> bootstrapping. In order to even configure the LLVM sanitizer runtimes
> you need libc and many other OS interfaces, so when bootstrapping you
> need to build the compiler-rt builtins library separately from the
> sanitizers.
> This can be done either by using the `LLVM_ENABLE_RUNTIMES` CMake option
> (see DistributionExample-stage2.cmake in clang/cmake/caches), or by
> treating compiler-rt/lib/builtins as the top-level CMake file.
>
> I would strongly suggest that you start with one of the CMake cache
> files under clang/cmake/caches as an example because setting up the
> CMake options to build a toolchain that can cross-compile is sadly
> quite complicated.
Thanks for the input. I will now be trying this cache file to see. At
the moment I am simply experimenting with different CMake options to see
if I can get it right. LLVM_ENABLE_RUNTIMES causes the freshly-built
Clang to be used as the compiler for the runtimes set, here it runs into
including host system headers (no libc exists yet).
Only BUILTINS are set to ON, no sanitizers or xrays.
It looks like a quite common request/question. Has a fix been proposed or
a reviews.llvm.org page exists? I'd follow it. Hacking CMake is fun
until you want to get the job done.
Cheers
Martin Storsjö wrote:
>> 1. Get the sources (llvm, lld, compiler-rt, libunwind, libcxx...).
>> 2. Build an LLVM cross-compiler toolchain using native distribution's
>> compiler (i.e. build an x86_64 clang executable that targets aarch64).
>> 3. Cross-compile libc and other libraries/dependencies to run the
>> userland.
>> 4. Cross-compile the userland.
> Yes, for such a full from-scratch setup, the procedure is a bit fiddly
> to get right, and exactly how to do it is very dependent on how
> configurable the lower level components of your target platform are
> for such bootstrap setups.
>
> I regularly build my toolchain that targets mingw, in exactly this way.
> First I build the compiler, then I install the target "libc"'s headers,
> then build the mingw equivalent of the libc.
> After this stage, higher level runtimes like libc++ can be built on top,
> followed by other compiler-rt libraries.
> See https://github.com/mstorsjo/llvm-mingw for the full set of scripts I
> use to build my setup; built-all.sh is the toplevel script you can star
> following if you want to dig in.
I like this. I hope you don't mind if I borrow some of these ideas to
play with. C_COMPILER_WORKS is something I've never heard of.
Thank you!
Just a quick update. Here's what worked for me here*:
1. Get the sources.
2. Build clang, llvm, lld.
3. Install libc headers to a sysroot.
4. Build compiler-rt builtins and crt with the freshly-built clang.
One need to set C_COMPILER_WORKS to skip the checks.
5. Build libc.a/libc.so
Now the freshly-built clang can compile a "Hello, World" program.
@Martin Storsjö
@Chris Bieneman
Thanks for the hints!
* - instead of previously supposed
1. Get the sources (llvm, lld, compiler-rt, libunwind, libcxx...).
2. Build an LLVM cross-compiler toolchain using native distribution's
compiler (i.e. build an x86_64 clang executable that targets aarch64).
3. Cross-compile libc and other libraries/dependencies to run the
userland.
4. Cross-compile the userland.
--
>I like this. I hope you don't mind if I borrow some of these ideas to
>play with. C_COMPILER_WORKS is something I've never heard of.
I'm also working on building a clang-based toolchain from scratch.
To avoid CMake bailing out when a binary can't be linked, I use:
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
Along with:
-DCMAKE_SYSTEM_NAME="Generic"
-DCMAKE_SYSTEM_PROCESSOR="powerpc"
Best Regards,
Vlad
On 11/10/20 2:49 PM, Cág via llvm-dev wrote:
> Just a quick update. Here's what worked for me here*:
> 1. Get the sources.
> 2. Build clang, llvm, lld.
> 3. Install libc headers to a sysroot.
Alternatively, use a Debian-based system which allows co-installation of system
libraries for multiple architectures (Multi-Arch).
Never understood why other distributions aren't picking this mechanism up :-(.
Adrian
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer - glau...@debian.org
`. `' Freie Universitaet Berlin - glau...@physik.fu-berlin.de
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
> Just a note about this:
>
>> I like this. I hope you don't mind if I borrow some of these ideas to
>> play with. C_COMPILER_WORKS is something I've never heard of.
>
> I'm also working on building a clang-based toolchain from scratch.
> To avoid CMake bailing out when a binary can't be linked, I use:
>
> -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
Oh, right, that's the one - I remembered that there was a more proper
cmake option to use, but I didn't find it when I sent the previous mail.
Yeah, that option probably is more correct than CMAKE_C_COMPILER_WORKS. We
set it already in libunwind/CMakeLists.txt, I guess we should set it in a
few more places, at least compiler-rt/lib/builtins/CMakeLists.txt.
// Martin