Open nickdesaulniers opened 4 years ago
While I think that we could add this to this repo, it is probably worth adding to the kernel source directly. Although all distros build clang with all of the backends enabled, more specialized versions like the one that tc-build creates won't. Something like Android's target check maybe?
It's possible to just grep for specific architecture from llvm-objdump --version
for example. Here is the output for the version from LLVM apt repo:
LLVM (http://llvm.org/):
LLVM version 10.0.0
Optimized build.
Default target: x86_64-pc-linux-gnu
Host CPU: ivybridge
Registered Targets:
aarch64 - AArch64 (little endian)
aarch64_32 - AArch64 (little endian ILP32)
aarch64_be - AArch64 (big endian)
amdgcn - AMD GCN GPUs
arm - ARM
arm64 - ARM64 (little endian)
arm64_32 - ARM64 (little endian ILP32)
armeb - ARM (big endian)
avr - Atmel AVR Microcontroller
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
hexagon - Hexagon
lanai - Lanai
mips - MIPS (32-bit big endian)
mips64 - MIPS (64-bit big endian)
mips64el - MIPS (64-bit little endian)
mipsel - MIPS (32-bit little endian)
msp430 - MSP430 [experimental]
nvptx - NVIDIA PTX 32-bit
nvptx64 - NVIDIA PTX 64-bit
ppc32 - PowerPC 32
ppc64 - PowerPC 64
ppc64le - PowerPC 64 LE
r600 - AMD GPUs HD2XXX-HD6XXX
riscv32 - 32-bit RISC-V
riscv64 - 64-bit RISC-V
sparc - Sparc
sparcel - Sparc LE
sparcv9 - Sparc V9
systemz - SystemZ
thumb - Thumb
thumbeb - Thumb (big endian)
wasm32 - WebAssembly 32-bit
wasm64 - WebAssembly 64-bit
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
xcore - XCore
I don’t think that is any cleaner than just trying to run:
echo | “$@“ -x c -c -o /dev/null - 2>&1 && echo “y”
with a shell script like Android does.
In fact, we could probably use this justification to upstream that Android patch. It would be easy to combine these two checks into one script. I’ll try to prototype something tonight.
In fact, we could probably use this justification to upstream that Android patch. It would be easy to combine these two checks into one script. I’ll try to prototype something tonight.
Hmmm, maybe not because I am sure upstream would want a different error message based on what is failing (target not being valid or target being an Android target) and I can't really think of a clean way to do that right now.
I'll still draft up a patch for the original issue soon.
Doubling back to low hanging fruit. This works:
diff --git a/Makefile b/Makefile
index 16d8271192d1..84e75d856cd9 100644
--- a/Makefile
+++ b/Makefile
@@ -528,6 +528,9 @@ endif
ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
ifneq ($(CROSS_COMPILE),)
CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%))
+ifneq ($(shell $(srctree)/scripts/clang-target.sh $(CC) $(CLANG_FLAGS)),)
+$(error "$(CC) does not support $(CLANG_FLAGS), please make sure $(CC) has backend support for selected target")
+endif
GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)
GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..)
diff --git a/scripts/clang-target.sh b/scripts/clang-target.sh
new file mode 100755
index 000000000000..1a2590581339
--- /dev/null
+++ b/scripts/clang-target.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+echo | $@ -c -x c - -o /dev/null >/dev/null 2>&1 || echo n
$ make -j$(nproc) -s ARCH=hexagon CROSS_COMPILE=hexagon-linux-gnu- AR=llvm-ar AS=clang CC=clang HOSTCC=clang HOSTLD=ld.lld HOSTAR=llvm-ar LD=ld.lld NM=llvm-nm OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump OBJSIZE=llvm-size READELF=llvm-readelf STRIP=llvm-strip distclean defconfig
Makefile:532: *** "clang does not support --target=hexagon-linux-gnu, please make sure clang has backend support for selected target". Stop.
make: *** [Makefile:327: __build_one_by_one] Error 2
$ make -j$(nproc) -s ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- AR=llvm-ar AS=clang CC=clang HOSTCC=clang HOSTLD=ld.lld HOSTAR=llvm-ar LD=ld.lld NM=llvm-nm OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump OBJSIZE=llvm-size READELF=llvm-readelf STRIP=llvm-strip distclean defconfig
Not sure if it is worth adding that to the build system or just making it a part of driver.sh
?
I usually build llvm with:
which makes testing mipsel locally with driver.sh error in non-sensical ways. It might be a slight improvement for an edge case to test that clang has been configured to target these. Probably don't need to check all of these tools (theoretically you could have some crazy combo of different clang and lld with differing target support).
Not a priority though.