Skip to content
This repository has been archived by the owner on Apr 13, 2024. It is now read-only.

fail if LLVM not configured to target certain backend #209

Open
nickdesaulniers opened this issue Oct 3, 2019 · 5 comments
Open

fail if LLVM not configured to target certain backend #209

nickdesaulniers opened this issue Oct 3, 2019 · 5 comments

Comments

@nickdesaulniers
Copy link
Member

I usually build llvm with:

$ cmake .. -DCMAKE_BUILD_TYPE=Release -G Ninja -DCMAKE_C_COMPILER=/android1/android-master/prebuilts/clang/host/linux-x86/clang-r353983c/bin/clang -DCMAKE_CXX_COMPILER=/android1/android-master/prebuilts/clang/host/linux-x86/clang-r353983c/bin/clang++ -DLLVM_ENABLE_LLD=ON -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86"

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.

@nathanchance
Copy link
Member

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?

@tpimh
Copy link
Contributor

tpimh commented Dec 4, 2019

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

@nathanchance
Copy link
Member

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.

@nathanchance
Copy link
Member

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.

@nathanchance
Copy link
Member

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?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants