diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60d6e4a096121d..3b38f8473c5f4f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,11 @@ jobs: os: windows runs_on: windows-2019 shell: msys2 {0} + - displayTargetName: clang-build + os: unix + runs_on: ubuntu-22.04 + shell: bash + build_options: "LLVM=1 CROSS_COMPILE=x86_64-linux-gnu" timeout-minutes: 100 env: CCACHE_DIR: ${{ github.workspace }}/.ccache @@ -93,6 +98,11 @@ jobs: run: | sudo apt update -y sudo apt install -y ccache libjsmn-dev + - name: Install clang toolchain + if: runner.os == 'Linux' + run: | + sudo apt update -y + sudo apt install -y clang lld llvm - name: Install patched binutils for Windows if: runner.os == 'Windows' run: | diff --git a/arch/lkl/kernel/misc.c b/arch/lkl/kernel/misc.c index 9cdb4508314dc4..5071b2990c8adb 100644 --- a/arch/lkl/kernel/misc.c +++ b/arch/lkl/kernel/misc.c @@ -1,5 +1,23 @@ #include +// TODO: Functions __generic_xchg_called_with_bad_pointer and wrong_size_cmpxchg +// are called in __generic_xchg and __generic_cmpxchg_local respectively. +// They should be optimized out by the compiler due to the function +// inlining. However, when building with clang there are some instances +// where the functions aren't inlined and, thus, the compile-time optimization +// doesn't eliminate them entirely. As a result, the linker throws +// unresololved symbols error. As a workaround, the fix below define these +// functions to bypass the link-time error. +void __generic_xchg_called_with_bad_pointer(void) +{ + panic("%s shouldn't be executed\n", __func__); +} +unsigned long wrong_size_cmpxchg(volatile void *ptr) +{ + panic("%s shouldn't be executed\n", __func__); + return 0; +} + #ifdef CONFIG_PROC_FS static void *cpuinfo_start(struct seq_file *m, loff_t *pos) { diff --git a/tools/lkl/Makefile b/tools/lkl/Makefile index 0fd436be57c7d0..849912b63a4af8 100644 --- a/tools/lkl/Makefile +++ b/tools/lkl/Makefile @@ -105,6 +105,7 @@ $(OUTPUT)cpfromfs$(EXESUF): cptofs$(EXESUF) $(Q)if ! [ -e $@ ]; then ln -s $< $@; fi clean: + $(call QUIET_CLEAN, vmlinux)$(MAKE) -C ../.. ARCH=lkl $(KOPT) clean $(call QUIET_CLEAN, objects)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd'\ -delete -o -name '\.*.d' -delete $(call QUIET_CLEAN, headers)$(RM) -r $(OUTPUT)/include/lkl/ @@ -113,6 +114,8 @@ clean: clean-conf: clean $(call QUIET_CLEAN, Makefile.conf)$(RM) $(OUTPUT)/Makefile.conf + $(call QUIET_CLEAN, kernel_config.h)$(RM) $(OUTPUT)/include/kernel_config.h + $(call QUIET_CLEAN, kernel.config)$(RM) $(OUTPUT)/kernel.config headers_install: $(TARGETS) $(call QUIET_INSTALL, headers) \ diff --git a/tools/lkl/Makefile.autoconf b/tools/lkl/Makefile.autoconf index a4bba1c01c935e..56edf8dda0540e 100644 --- a/tools/lkl/Makefile.autoconf +++ b/tools/lkl/Makefile.autoconf @@ -142,7 +142,7 @@ define kasan_enable $(if $(filter yes,$(kasan_test)), $(call kasan_test_enable)) endef -define do_autoconf +define do_autoconf_gnu export CROSS_COMPILE := $(CROSS_COMPILE) export CC := $(CROSS_COMPILE)gcc export LD := $(CROSS_COMPILE)ld @@ -150,6 +150,27 @@ define do_autoconf $(eval LD := $(CROSS_COMPILE)ld) $(eval CC := $(CROSS_COMPILE)gcc) $(eval LD_FMT := $(shell $(LD) -r -print-output-format)) +endef + +define llvm_target_to_ld_fmt + $(if $(filter $(CROSS_COMPILE),x86_64-linux-gnu),elf64-x86-64,\ + $(error Unsupported LLVM target $(CROSS_COMPILE))) +endef + +define do_autoconf_llvm + $(eval LLVM_PREFIX := $(if $(filter %/,$(LLVM)),$(LLVM))) + $(eval LLVM_SUFFIX := $(if $(filter -%,$(LLVM)),$(LLVM))) + export CROSS_COMPILE := $(CROSS_COMPILE) + export CC := $(LLVM_PREFIX)clang$(LLVM_SUFFIX) + export LD := $(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX) + export AR := $(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX) + $(eval LD := $(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX)) + $(eval CC := $(LLVM_PREFIX)clang$(LLVM_SUFFIX)) + $(eval LD_FMT := $(call llvm_target_to_ld_fmt)) +endef + +define do_autoconf + $(if $(LLVM),$(call do_autoconf_llvm),$(call do_autoconf_gnu)) $(eval EXEC_FMT := $(shell echo $(LD_FMT) | cut -d "-" -f1)) $(call set_kernel_config,OUTPUT_FORMAT,\"$(LD_FMT)\") $(if $(or $(filter $(EXEC_FMT),elf64),$(filter $(LD_FMT),pe-x86-64)),$(call 64bit_host))