diff mbox series

[RFC,04/12] toolchain/toolchain-external: add support for clang

Message ID 20241025140714.2395033-5-bcain@quicinc.com
State New
Headers show
Series add hexagon architecture | expand

Commit Message

Brian Cain Oct. 25, 2024, 2:07 p.m. UTC
Signed-off-by: Brian Cain <bcain@quicinc.com>
---
 package/Makefile.in                           | 24 ++++--
 toolchain/Config.in                           | 54 +++++++++++++
 toolchain/helpers.mk                          | 16 ++++
 .../pkg-toolchain-external.mk                 | 29 ++++++-
 .../Config.in.options                         | 76 +++++++++++++++++++
 5 files changed, 190 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/package/Makefile.in b/package/Makefile.in
index 829636900b..b54fe123ba 100644
--- a/package/Makefile.in
+++ b/package/Makefile.in
@@ -231,14 +231,28 @@  ifeq ($(BR2_TOOLCHAIN_GCC_AT_LEAST_4_7),y)
 TARGET_GCC_WRAPPERS_PREFIX = gcc-
 endif
 
+ifeq ($(BR2_TOOLCHAIN_EXTERNAL_CLANG),y)
+TARGET_CC_SUFFIX=clang
+TARGET_CXX_SUFFIX=clang++
+TARGET_AS_SUFFIX=llvm-mc
+TARGET_LD_SUFFIX=clang
+TARGET_PREPROCESSOR=clang -E
+else
+TARGET_CC_SUFFIX=gcc
+TARGET_CXX_SUFFIX=g++
+TARGET_AS_SUFFIX=as
+TARGET_LD_SUFFIX=ld
+TARGET_PREPROCESSOR=cpp
+endif
+
 # Define TARGET_xx variables for all common binutils/gcc
 TARGET_AR       = $(TARGET_CROSS)$(TARGET_GCC_WRAPPERS_PREFIX)ar
-TARGET_AS       = $(TARGET_CROSS)as
-TARGET_CC       = $(TARGET_CROSS)gcc
-TARGET_CPP      = $(TARGET_CROSS)cpp
-TARGET_CXX      = $(TARGET_CROSS)g++
+TARGET_AS       = $(TARGET_CROSS)$(TARGET_AS_SUFFIX)
+TARGET_CC       = $(TARGET_CROSS)$(TARGET_CC_SUFFIX)
+TARGET_CPP      = $(TARGET_CROSS)$(TARGET_PREPROCESSOR)
+TARGET_CXX      = $(TARGET_CROSS)$(TARGET_CXX_SUFFIX)
 TARGET_FC       = $(TARGET_CROSS)gfortran
-TARGET_LD       = $(TARGET_CROSS)ld
+TARGET_LD       = $(TARGET_CROSS)$(TARGET_LD_SUFFIX)
 TARGET_NM       = $(TARGET_CROSS)$(TARGET_GCC_WRAPPERS_PREFIX)nm
 TARGET_RANLIB   = $(TARGET_CROSS)$(TARGET_GCC_WRAPPERS_PREFIX)ranlib
 TARGET_READELF  = $(TARGET_CROSS)readelf
diff --git a/toolchain/Config.in b/toolchain/Config.in
index c2522aca7f..1466425ce2 100644
--- a/toolchain/Config.in
+++ b/toolchain/Config.in
@@ -837,6 +837,60 @@  config BR2_TOOLCHAIN_GCC_AT_LEAST
 	default "4.4"	if BR2_TOOLCHAIN_GCC_AT_LEAST_4_4
 	default "4.3"	if BR2_TOOLCHAIN_GCC_AT_LEAST_4_3
 
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_4_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_5_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_6_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_7_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_9_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_10_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_11_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_12_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_13_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_14_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_15_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_16_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_17_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_18_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_19_0
+	bool
+config BR2_TOOLCHAIN_CLANG_AT_LEAST_20_0
+	bool
+
+# This order guarantees that the highest version is set, as kconfig
+# stops affecting a value on the first matching default.
+config BR2_TOOLCHAIN_CLANG_AT_LEAST
+	string
+	default "4.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_4_0
+	default "5.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_5_0
+	default "6.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_6_0
+	default "7.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_7_0
+	default "9.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_9_0
+	default "10.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_10_0
+	default "11.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_11_0
+	default "12.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_12_0
+	default "13.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_13_0
+	default "14.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_14_0
+	default "15.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_15_0
+	default "16.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_16_0
+	default "17.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_17_0
+	default "18.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_18_0
+	default "19.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_19_0
+	default "20.0"	if BR2_TOOLCHAIN_CLANG_AT_LEAST_20_0
+
 config BR2_TOOLCHAIN_HAS_MNAN_OPTION
 	bool
 	default y if BR2_TOOLCHAIN_GCC_AT_LEAST_4_9
diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
index f3fdaaec07..f4462db483 100644
--- a/toolchain/helpers.mk
+++ b/toolchain/helpers.mk
@@ -224,6 +224,22 @@  check_glibc_rpc_feature = \
 		exit 1 ; \
 	fi
 
+check_clang_version = \
+	expected_version="$(strip $2)" ; \
+	exit 0; \
+	real_version=`$(TOOLCHAIN_EXTERNAL_BIN)/llvm-config --version;`; \
+	if [ -z "$${expected_version}" ]; then \
+		printf "Internal error, __$${2}__ vs __$${expected_version}__ clang version unknown (no CLANG_AT_LEAST_X_Y selected)\n"; \
+		printf "real ver: __$${real_version}__\n"; \
+		exit 1 ; \
+	fi; \
+	real_version=`$(TOOLCHAIN_EXTERNAL_BIN)/$(TOOLCHAIN_EXTERNAL_PREFIX)-llvm-config --version;`; \
+	if [[ ! "$${real_version}" =~ ^$${expected_version}\. ]] ; then \
+	printf "Incorrect selection of clang version: expected %s.x, got %s\n" \
+			"$${expected_version}" "$${real_version}" ; \
+		exit 1 ; \
+	fi
+
 #
 # Check the correctness of a glibc external toolchain configuration.
 #  1. Check that the C library selected in Buildroot matches the one
diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
index d45f2c54de..3948ad1107 100644
--- a/toolchain/toolchain-external/pkg-toolchain-external.mk
+++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
@@ -90,12 +90,28 @@  endif
 TOOLCHAIN_EXTERNAL_SUFFIX = \
 	$(if $(wildcard $(TOOLCHAIN_EXTERNAL_BIN)/*.br_real),.br_real)
 
+ifeq ($(BR2_TOOLCHAIN_EXTERNAL_CLANG),y)
+TARGET_CC_SUFFIX=clang
+TARGET_CXX_SUFFIX=clang++
+TARGET_BINUTILS_PREFIX=llvm-
+TARGET_LD_SUFFIX=clang
+else
+TARGET_CC_SUFFIX=gcc
+TARGET_CXX_SUFFIX=g++
+TARGET_BINUTILS_PREFIX=
+TARGET_LD_SUFFIX=ld
+endif
+
 TOOLCHAIN_EXTERNAL_CROSS = $(TOOLCHAIN_EXTERNAL_BIN)/$(TOOLCHAIN_EXTERNAL_PREFIX)-
-TOOLCHAIN_EXTERNAL_CC = $(TOOLCHAIN_EXTERNAL_CROSS)gcc$(TOOLCHAIN_EXTERNAL_SUFFIX)
-TOOLCHAIN_EXTERNAL_CXX = $(TOOLCHAIN_EXTERNAL_CROSS)g++$(TOOLCHAIN_EXTERNAL_SUFFIX)
+TOOLCHAIN_EXTERNAL_CC = $(TOOLCHAIN_EXTERNAL_CROSS)$(TARGET_CC_SUFFIX)$(TOOLCHAIN_EXTERNAL_SUFFIX)
+TOOLCHAIN_EXTERNAL_CXX = $(TOOLCHAIN_EXTERNAL_CROSS)$(TARGET_CXX_SUFFIX)$(TOOLCHAIN_EXTERNAL_SUFFIX)
 TOOLCHAIN_EXTERNAL_GDC = $(TOOLCHAIN_EXTERNAL_CROSS)gdc$(TOOLCHAIN_EXTERNAL_SUFFIX)
 TOOLCHAIN_EXTERNAL_FC = $(TOOLCHAIN_EXTERNAL_CROSS)gfortran$(TOOLCHAIN_EXTERNAL_SUFFIX)
 TOOLCHAIN_EXTERNAL_READELF = $(TOOLCHAIN_EXTERNAL_CROSS)readelf
+TOOLCHAIN_EXTERNAL_LLVM_CONFIG = $(TOOLCHAIN_EXTERNAL_CROSS)llvm-config$(TOOLCHAIN_EXTERNAL_SUFFIX)
+TOOLCHAIN_CLANG_VERSION = \
+    `$(TOOLCHAIN_EXTERNAL_LLVM_CONFIG) --version | \
+     sed -e 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\).*$$/\1/'`
 
 # Normal handling of downloaded toolchain tarball extraction.
 ifeq ($(BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD),y)
@@ -595,8 +611,13 @@  define $(2)_CONFIGURE_CMDS
 		$$(call toolchain_find_sysroot,$$(TOOLCHAIN_EXTERNAL_CC)),\
 		$$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)),\
 		$$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict)); \
-	$$(call check_gcc_version,$$(TOOLCHAIN_EXTERNAL_CC),\
-		$$(call qstrip,$$(BR2_TOOLCHAIN_GCC_AT_LEAST))); \
+	if test "$(BR2_TOOLCHAIN_EXTERNAL_GCC)" = "y" ; then \
+		$(call check_gcc_version,$(TOOLCHAIN_EXTERNAL_CC),\
+			$(call qstrip,$(BR2_TOOLCHAIN_GCC_AT_LEAST))); \
+	else \
+		$(call check_clang_version,$(TOOLCHAIN_EXTERNAL_CC),\
+			$(call qstrip,$(BR2_TOOLCHAIN_CLANG_AT_LEAST))); \
+	fi ; \
 	if test "$$(BR2_arm)" = "y" ; then \
 		$$(call check_arm_abi,\
 			"$$(TOOLCHAIN_EXTERNAL_CC) $$(TOOLCHAIN_EXTERNAL_CFLAGS)") ; \
diff --git a/toolchain/toolchain-external/toolchain-external-custom/Config.in.options b/toolchain/toolchain-external/toolchain-external-custom/Config.in.options
index fcffeb6b77..0dbf317b92 100644
--- a/toolchain/toolchain-external/toolchain-external-custom/Config.in.options
+++ b/toolchain/toolchain-external/toolchain-external-custom/Config.in.options
@@ -40,8 +40,25 @@  config BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX
 	  so you can leave this option at default value if you use them
 	  as external toolchain.
 
+choice
+	bool "External toolchain Compiler"
+	default BR2_TOOLCHAIN_EXTERNAL_GCC
+	help
+	  Select between gcc and clang
+
+config BR2_TOOLCHAIN_EXTERNAL_GCC
+	bool "gcc"
+	select BR2_TOOLCHAIN_USES_GCC
+
+config BR2_TOOLCHAIN_EXTERNAL_CLANG
+	bool "clang"
+	select BR2_TOOLCHAIN_USES_CLANG
+
+endchoice
+
 choice
 	bool "External toolchain gcc version"
+	depends on BR2_TOOLCHAIN_EXTERNAL_GCC
 	help
 	  Set to the gcc version that is used by your external
 	  toolchain.
@@ -146,6 +163,65 @@  endchoice
 comment "GCC older than 4.8 is not tested by Buildroot. Use at your own risk."
 	depends on !BR2_TOOLCHAIN_GCC_AT_LEAST_4_8
 
+choice
+	bool "External toolchain clang version"
+	default BR2_TOOLCHAIN_EXTERNAL_CLANG_4_0
+	depends on BR2_TOOLCHAIN_EXTERNAL_CLANG
+	help
+	  Set to the clang version that is used by your external
+	  toolchain.
+
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_4_0
+	bool "4.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_4_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_5_0
+	bool "5.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_5_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_6_0
+	bool "6.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_6_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_7_0
+	bool "7.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_7_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_9_0
+	bool "9.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_9_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_10_0
+	bool "10.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_10_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_11_0
+	bool "11.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_11_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_12_0
+	bool "12.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_12_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_13_0
+	bool "13.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_13_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_14_0
+	bool "14.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_14_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_15_0
+	bool "15.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_15_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_16_0
+	bool "16.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_16_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_17_0
+	bool "17.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_17_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_18_0
+	bool "18.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_18_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_19_0
+	bool "19.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_19_0
+config BR2_TOOLCHAIN_EXTERNAL_CLANG_20_0
+	bool "20.0"
+	select BR2_TOOLCHAIN_CLANG_AT_LEAST_20_0
+
+endchoice
+
 choice
 	bool "External toolchain kernel headers series"
 	default BR2_TOOLCHAIN_EXTERNAL_HEADERS_REALLY_OLD