Cross Compile Any Llvm Component Using Clang Only (No Gcc Requirement)?

Simply put: Can ANY part of llvm be cross-compiled WITHOUT the need of ANY gcc component?

I had been trying a whole number of attempts from various llvm.org links and got bupkus, only errors.

I first posed the question on the IRC channel(s) and one user said it could be done without needing gcc, but almost everywhere I’ve looked, I’d see references to using some aspect of gcc.

It was even suggested I look into using compiler-rt, but building that resulted in the same issues that arise either during cmake tests or during the build (probably from a child cmake).

My latest test was to go bare-minimum by just doing llvm’s libc alone.
However, every method listed in https://libc.llvm.org/full_cross_build.html failed.
Going by the “standalone”, the error was:

-- Skipping startup for target architecture arm
CMake Error at /<pathTo>llvm-project/libc/cmake/modules/LLVMLibCTestRules.cmake:397 (message):
  The 'crt1' target for the integration test is missing.
Call Stack (most recent call first):
 /<pathTo>/llvm-project/libc/test/src/CMakeLists.txt:135 (add_integration_test)

I even made sure to use the true triplet form shown on that page (rather than including “vendor”, which shouldn’t have made any difference), and it still failed:

$ /usr/bin/cmake \
   -S "<pathToGit>/llvm" \
   -B "<pathToBuild>" \
   -DCMAKE_INSTALL_PREFIX="/usr" \
   -DCMAKE_BUILD_TYPE="Release" \
   -DCMAKE_C_COMPILER="/usr/bin/clang" \
   -DCMAKE_CXX_COMPILER="/usr/bin/clang++" \
   -DLLVM_ENABLE_PROJECTS=libc \
   -DLLVM_LIBC_FULL_BUILD=ON \
   -DLIBC_TARGET_TRIPLE=arm-linux-gnueabi

Seems to me that some SYSROOT ought to have been included in there, except this is libc that’s being built so it should only be looking for where it was built, except it couldn’t even get out of the starting-gate to even begin to get built.

Setting something like -DCMAKE_C_FLAGS="--target=<tuple> --sysroot=<hostTargetDir>" for other llvm component builds ends up also failing because it’s looking for files that are normally provided by gcc. Example: crtbeginS.o or lgcc_s.
But like I said, I’m looking to go completely sans-GCC, and figured llvm could bootstrap in a similar way that GCC can, as shown on LFS. The only things gcc needed was some libc, linux headers, binutils, and itself.
Is this not the case for llvm?

How To Cross-Compile Clang/LLVM using Clang/LLVM — LLVM 19.0.0git documentation “or whatever is the location of your GCC’s sysroot”

Getting Started with the LLVM System — LLVM 19.0.0git documentation “The first step is to get a recent GCC toolchain installed”

CMLFS/1-Stage0/0-Build-Notes at master · dslm4515/CMLFS · GitHub also shows GCC used (if even just for building a libc).

Tagging libc people with more cross-compiling experience: @petrhosek @mikhailrgadelha @jhuber6 @SchrodingerZhu

There’s existing work to compile libc++ using the LLVM libc, there’s still pieces missing (locales, vasprintf, vsscanf, some other stuff). There’s even more missing when it comes to using the LLVM libc as a glibc replacement (no dlfcn.h for example). These things are in progress, but there’s a lot to do.

Here are the flags we currently use to cross-compile libc for rv32: llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py at d55a314e6dd0273e3a15401684478daff546958b · llvm/llvm-zorg · GitHub

I think the most important options are LIBC_TARGET_TRIPLE, CMAKE_SYSTEM_NAME, LLVM_HOST_TRIPLE, and (maybe) LLVM_TARGETS_TO_BUILD. You probably don’t need them all to enable cross-compilation but I added them all just to be safe.

CMAKE_CROSSCOMPILING_EMULATOR is useful when running the tests, as it prepends the tests with whatever is set in this variable. In rv32’s case, it’s a script that runs the test in qemu running a rv32 Linux image.

So I should take it that when that user on IRC made the claim that llvm/clang could be built without needing gcc, it wasn’t true?
That in llvm’s current state, there is still aspects of gcc that is still required (eg libc++)?
But what of my failed attempt to even get a successful cmake for llvm’s libc?
I get not having all of the features needed to use llvm’s libc for other projects, but to even just build itself, it’s requiring an existing cross-built libc?
Is that how I should be seeing all of this?

You can definitely use compiler-rt, libc++, and libc++abi. Replacing glibc is the hard part.

1 Like

Yeah, I’ve seen that --gcc-toolchain mentioned elsewhere before, which also made me think that gcc is still required.

Like I said before, I couldn’t even get compiler-rt to get through a successful cmake because it was looking for gcc-related files in the sysroot.

It’s the toolchain from here: GitHub - riscv-collab/riscv-gnu-toolchain: GNU toolchain for RISC-V, including GCC

I know, I’m saying this topic is about if llvm can be built without the need of ANY gcc component, and from everything I’m seeing, it’s needed even though gcc doesn’t need anything other than binutils and a libc to be bootstrapped, like in LFS.

No GCC components are required, but you do need a libc and C startup bits as others have stated. On Linux that’s going to default to glibc plus gcc provided crt* files. FreeBSD provides a BSD+LLVM toolchain without any GCC bits (there are a few libgcc* files, but they are built from compiler-rt). People have also build musl based sysroots.

IMO the documentation mentioning GCC is mostly just sloppy in that it’s the default unless you’re using a musl based distro.

No GCC components are required…
…plus gcc provided crt* files

To get the libgcc* files, one needs… GCC? Maybe I’m missing something you’re saying.

there are a few libgcc* files, but they are built from compiler-rt

Is that saying compiler-rt provides the libgcc files, or just that it builds it… from gcc source, something that is part of gcc?

Maybe I’m somehow not being clear or something, but gcc has no need for anything from llvm, but the opposite does not appear to be true.
And to cross-compile compiler-rt, the libgcc files are needed, which I’m guessing needs to be done via a --target parameter for gcc. Again, gcc seems needed in some form or fashion.

LLVM needs some things from the host environment. On Linux, those are typically provided by GNU projects such as glibc. On Windows, those things are provided by Microsoft. I’m unfamiliar with the exact details of FreeBSD but my understanding is their goal is to be non-GNU, even if the names of a few files have “gcc” in them.

And is that expected to be the way it will always be? That it’ll never be able to bootstrap like GCC can LFS-style?

On Linux, those are typically provided by GNU projects such as glibc.

And gcc libs (and binutils) apparently (which is what the title of this post has asking).

For some environments, I expect so. Not seeing any real demand for a Windows-hosted LLVM libc, for example.

LLVM has a pretty usable set of binutils these days. My employer no longer ships the GNU binutils for our current platform.

People keep mentioning FreeBSD; if you really want a gcc-free environment, I’m not sure why you’d want to ignore that.

I don’t know what “LFS-style” means.

https://www.linuxfromscratch.org/lfs/view/systemd/
Once I do a variant of III.5, I’m golden for the rest of my buildout.

For me it’s not about being GCC/GNU-free, but about not having extra steps that (what seems to be) ought not be necessary.

What I’m desire akin to III.5:

<on target-host sysroot>
  linux headers
  glibc (until llibc is ready)
  llvm

since it sounds like llvm consolidates what’s needed, instead of:

<on target-host sysroot>
  linux headers
<on build>
  binutils
  gcc stage 1
<on target-host sysroot>
  glibc
  gcc libstdc++
  binutils
  gcc stage 2

If I want llvm LFS-style bootstrap, it sounds like I’d need to:

<on target-host sysroot>
  linux headers
  glibc
  gcc libstdc++
  llvm

If I could drop gcc libstdc++, so I don’t need the repo any more, that’d be great.
I mean, gcc can build it’s own libstdc++ (from the gcc repo), but clang cannot build its libstdc++ without the libstdc++ files already existing on target-host sysroot.

EDIT0: And when the time comes llibc reaches *libc parity, then it’d be doubly great to have a single bootstrap command to build all of it in one-go.

Have you looked into the ClangBuiltLinux project?

I have not, but right off the bat I’m not seeing any references to “cross”-anything: Building Clang from source · ClangBuiltLinux/linux Wiki · GitHub which is what this topic is about.

A quick glance makes it look like it’s for building linux on existing systems (not cross-arch).

From ClangBuiltLinux github: ClangBuiltLinux · GitHub

Please see our site for links to more info such as our issue tracker, or the official Linux kernel docs for how to get started building Linux kernels with LLVM.

Follow the link to the official Linux kernel docs, included in the first 4 lines of Building with LLVM is

 For cross compiling:

make LLVM=1 ARCH=arm64

I have no clue why you’re even showing that, as it has nothing to do with this topic.

I’ve already cross-compiled the kernel (with gcc as well as with llvm), so I know how that works.

This topic is/was/will-always-be about cross-arch bootstrapping llvm.