Re: [PATCH] kbuild: Support clang-$ver builds

From: Peter Zijlstra
Date: Fri Oct 29 2021 - 04:54:54 EST


On Thu, Oct 28, 2021 at 04:27:55PM -0700, Nick Desaulniers wrote:
> On Thu, Oct 28, 2021 at 1:49 PM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:

> > > 2. Update the documentation to describe using the
> > >
> > > $ PATH=/usr/lib/llvm-#/bin:$PATH make LLVM=1 ...
> > >
> > > trick. This has been the preferred method for using different
> > > versions of LLVM but it has never been documented anywhere. This
> > > would allow us to keep the current build infrastructure while giving
> > > people clear instructions for how to handle different versions of
> > > clang. As Peter has noted, this would require people who are not
> > > familiar with building with LLVM to be constantly looking at the
> > > documentation to remember the command to invoke, whereas with
> > > LLVM=-#, it is easy to remember.
> >
> > Right, this is no more than a crude hack and is super unfriendly. It
> > should never have been accepted.
>
> Lots of tools modify PATH in your `.bashrc` or `.zshrc` etc. I don't
> see how that's any different, other than one off commands in which you
> actually intend to use a specific version.

Typically /etc/profile.d/ stuff adds to PATH for easy access to
installed programs but it is very poor at handling conflicting versions
of the same program (IIRC you get the first one).

Why should I want to remember where clang-12 vs gcc-9 lives? I don't
want to remember or even type those paths, Debian has already kindly
given me these unambiguous names to use.

> > So how about we do the below instead? Then the normal way of things will
> > be:
> >
> > $ make CC=clang-12
> >
> > and it will all *just*work*. The incomplete LLVM archs can revert back
> > to the old hybrid (clang+binutils) way of things by doing:
> >
> > $ make CC=clang LLVM=0
> >
> > Which explicitly states, use clang but don't use the full llvm suite. Or
> > they can do that CONFIG_LLVM_BROKEN (or whatever) to have them default
> > to LLVM=0
> >
> > ifdef CONFIG_LLVM_BROKEN
> > LLVM ?= 0
> > endif
> >
> > in front of the CC magic in the below patch should take care of that.
>
> I don't think setting CC should affect LD and friends (if you were
> suggesting that CC=clang-12 replace LLVM=1).

Why not? Why should clang not default to ld.lld? If you want weird mixes
you can always override them.

Again, why should CC=clang not default to the whole LLVM suite? Why
should using LLVM as a whole, be made more difficult? It's almost as if
you don't want people to use it.

You're explicitly making clang-lto/cfi difficult to use; is that on
purpose?

> Like Nathan, I'm
> sympathetic and think that your first patch is probably closer to what
> I'd accept, but it needs to handle non-suffixed versions (looks like
> it should) and add this info to Documentations/kbuild/llvm.rst.

That first patch has some issues there, but should be fixable. The
latest CC= using one works there. As does the below.


--- a/Makefile
+++ b/Makefile
@@ -423,9 +423,27 @@ HOST_LFS_CFLAGS := $(shell getconf LFS_C
HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null)
HOST_LFS_LIBS := $(shell getconf LFS_LIBS 2>/dev/null)

-ifneq ($(LLVM),)
-HOSTCC = clang
-HOSTCXX = clang++
+# powerpc and s390 don't yet work with LLVM as a whole
+ifeq ($(ARCH),powerpc)
+LLVM = 0
+endif
+ifeq ($(ARCH),s390)
+LLVM = 0
+endif
+
+# otherwise, if CC=clang, default to using LLVM to enable LTO
+CC_BASE := $(shell echo $(CC) | cut -b "1-5")
+ifeq ($(shell test "$(CC_BASE)" = "clang"; echo $$?),0)
+LLVM ?= 1
+LLVM_SFX := $(shell echo $(CC) | cut -b "6-")
+endif
+
+# if not set by now, do not use LLVM
+LLVM ?= 0
+
+ifneq ($(LLVM),0)
+HOSTCC = clang$(LLVM_SFX)
+HOSTCXX = clang++$(LLVM_SFX)
else
HOSTCC = gcc
HOSTCXX = g++
@@ -442,15 +460,15 @@ KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS)

# Make variables (CC, etc...)
CPP = $(CC) -E
-ifneq ($(LLVM),)
-CC = clang
-LD = ld.lld
-AR = llvm-ar
-NM = llvm-nm
-OBJCOPY = llvm-objcopy
-OBJDUMP = llvm-objdump
-READELF = llvm-readelf
-STRIP = llvm-strip
+ifneq ($(LLVM),0)
+CC = clang$(LLVM_SFX)
+LD = ld.lld$(LLVM_SFX)
+AR = llvm-ar$(LLVM_SFX)
+NM = llvm-nm$(LLVM_SFX)
+OBJCOPY = llvm-objcopy$(LLVM_SFX)
+OBJDUMP = llvm-objdump$(LLVM_SFX)
+READELF = llvm-readelf$(LLVM_SFX)
+STRIP = llvm-strip$(LLVM_SFX)
else
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld