[PATCH] kbuild: check the minimum compiler version in Kconfig

801 views
Skip to first unread message

Masahiro Yamada

unread,
Jan 13, 2021, 11:17:39 PM1/13/21
to linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Masahiro Yamada, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org
Paul Gortmaker reported a regression in the GCC version check [1].
If you use GCC 4.8, the build breaks before showing the error message
"error Sorry, your version of GCC is too old - please use 4.9 or newer."

I do not want to apply his fix-up since it implies we would not be able
to remove any cc-option test. Anyway, I admit checking the GCC version
in <linux/compiler-gcc.h> is too late.

Almost at the same time, Linus also suggested to move the compiler
version error to Kconfig time. [2]

I unified the similar two scripts, gcc-version.sh and clang-version.sh
into the new cc-version.sh. The old scripts invoked the compiler multiple
times (3 times for gcc-version.sh, 4 times for clang-version.sh). I
refactored the code so the new one invokes the compiler just once, and
also tried my best to use shell-builtin commands where possible.

The new script runs faster.

$ time ./scripts/clang-version.sh clang
120000

real 0m0.029s
user 0m0.012s
sys 0m0.021s

$ time ./scripts/cc-version.sh clang
Clang 120000

real 0m0.009s
user 0m0.006s
sys 0m0.004s

The cc-version.sh also shows the error if the compiler is old:

$ make defconfig CC=clang-9
*** Default configuration is based on 'x86_64_defconfig'
***
*** Compiler is too old.
*** Your Clang version: 9.0.1
*** Minimum Clang version: 10.0.1
***
scripts/Kconfig.include:46: Sorry, this compiler is unsupported.
make[1]: *** [scripts/kconfig/Makefile:81: defconfig] Error 1
make: *** [Makefile:602: defconfig] Error 2

I removed the clang version check from <linux/compiler-clang.h>

For now, I did not touch <linux/compiler-gcc.h> in order to avoid
merge conflict with [3], which has been queued up in the arm64 tree.
We will be able to clean it up later.

I put the stub for ICC because I see <linux/compiler-intel.h> although
I am not sure if building the kernel with ICC is well-supported.

[1] https://lkml.org/lkml/2021/1/10/250
[2] https://lkml.org/lkml/2021/1/12/1708
[3] https://lkml.org/lkml/2021/1/12/1533

Fixes: 87de84c9140e ("kbuild: remove cc-option test of -Werror=date-time")
Reported-by: Paul Gortmaker <paul.go...@windriver.com>
Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
Signed-off-by: Masahiro Yamada <masa...@kernel.org>
---

include/linux/compiler-clang.h | 10 -----
init/Kconfig | 9 +++--
scripts/Kconfig.include | 6 +++
scripts/cc-version.sh | 69 ++++++++++++++++++++++++++++++++++
scripts/clang-version.sh | 19 ----------
scripts/gcc-version.sh | 20 ----------
6 files changed, 80 insertions(+), 53 deletions(-)
create mode 100755 scripts/cc-version.sh
delete mode 100755 scripts/clang-version.sh
delete mode 100755 scripts/gcc-version.sh

diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index 98cff1b4b088..04c0a5a717f7 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -3,16 +3,6 @@
#error "Please don't include <linux/compiler-clang.h> directly, include <linux/compiler.h> instead."
#endif

-#define CLANG_VERSION (__clang_major__ * 10000 \
- + __clang_minor__ * 100 \
- + __clang_patchlevel__)
-
-#if CLANG_VERSION < 100001
-#ifndef __BPF_TRACING__
-# error Sorry, your version of Clang is too old - please use 10.0.1 or newer.
-#endif
-#endif
-
/* Compiler specific definitions for Clang compiler */

/* same as gcc, this was present in clang-2.6 so we can assume it works
diff --git a/init/Kconfig b/init/Kconfig
index b77c60f8b963..01108dd1318b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -26,11 +26,11 @@ config CC_VERSION_TEXT
and then every file will be rebuilt.

config CC_IS_GCC
- def_bool $(success,echo "$(CC_VERSION_TEXT)" | grep -q gcc)
+ def_bool $(success,test $(cc-name) = GCC)

config GCC_VERSION
int
- default $(shell,$(srctree)/scripts/gcc-version.sh $(CC)) if CC_IS_GCC
+ default $(cc-version) if CC_IS_GCC
default 0

config LD_VERSION
@@ -38,14 +38,15 @@ config LD_VERSION
default $(shell,$(LD) --version | $(srctree)/scripts/ld-version.sh)

config CC_IS_CLANG
- def_bool $(success,echo "$(CC_VERSION_TEXT)" | grep -q clang)
+ def_bool $(success,test $(cc-name) = Clang)

config LD_IS_LLD
def_bool $(success,$(LD) -v | head -n 1 | grep -q LLD)

config CLANG_VERSION
int
- default $(shell,$(srctree)/scripts/clang-version.sh $(CC))
+ default $(cc-version) if CC_IS_CLANG
+ default 0

config LLD_VERSION
int
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
index a5fe72c504ff..cdc8726d2904 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -39,6 +39,12 @@ as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler
$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)

+# Get the compiler name, version, and error out if it is unsupported.
+cc-info := $(shell,scripts/cc-version.sh $(CC))
+$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is unsupported.)
+cc-name := $(shell,set -- $(cc-info); echo $1)
+cc-version := $(shell,set -- $(cc-info); echo $2)
+
# Fail if the linker is gold as it's not capable of linking the kernel proper
$(error-if,$(success, $(LD) -v | grep -q gold), gold linker '$(LD)' not supported)

diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh
new file mode 100755
index 000000000000..32df0e2940f5
--- /dev/null
+++ b/scripts/cc-version.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Print the compiler name and its version in a 5 or 6-digit form.
+# Also, perform the minimum version check.
+
+set -e
+
+# When you raise the compiler version, please update
+# Documentation/process/changes.rst as well.
+gcc_min_version=4.9.0
+clang_min_version=10.0.1
+
+# print the compiler name, major version, minor version, patchlevel version
+get_compiler_info()
+{
+ cat <<- EOF | "$@" -E -P -x c - 2>/dev/null
+ #if defined(__clang__)
+ Clang __clang_major__ __clang_minor__ __clang_patchlevel__
+ #elif defined(__INTEL_COMPILER)
+ /* How to get the version of intel compiler? */
+ ICC 0 0 0
+ #elif defined(__GNUC__)
+ GCC __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
+ #else
+ unsupported 0 0 0
+ #endif
+ EOF
+}
+
+# convert the version to a canonical 5 or 6-digit form for numerical comparison
+get_canonical_version()
+{
+ IFS=.
+ set -- $1
+ echo $((10000 * $1 + 100 * $2 + $3))
+}
+
+# $@ instead of $1 because multiple words might be given e.g. CC="ccache gcc"
+orig_args="$@"
+set -- $(run_preprocessor "$@")
+
+name=$1
+version=$2.$3.$4
+
+case "$name" in
+GCC) min_version=$gcc_min_version;;
+Clang) min_version=$clang_min_version;;
+ICC) ;; # ICC min version undefined?
+*) echo "$orig_args: unknown compiler" >&2; exit 1;;
+esac
+
+cversion=$(get_canonical_version $version)
+
+if [ -n "$min_version" ]; then
+
+ min_cversion=$(get_canonical_version $min_version)
+
+ if [ "$cversion" -lt "$min_cversion" ]; then
+ echo >&2 "***"
+ echo >&2 "*** Compiler is too old."
+ echo >&2 "*** Your $name version: $version"
+ echo >&2 "*** Minimum $name version: $min_version"
+ echo >&2 "***"
+ exit 1
+ fi
+fi
+
+echo $name $cversion
diff --git a/scripts/clang-version.sh b/scripts/clang-version.sh
deleted file mode 100755
index 6fabf0695761..000000000000
--- a/scripts/clang-version.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# clang-version clang-command
-#
-# Print the compiler version of `clang-command' in a 5 or 6-digit form
-# such as `50001' for clang-5.0.1 etc.
-
-compiler="$*"
-
-if ! ( $compiler --version | grep -q clang) ; then
- echo 0
- exit 1
-fi
-
-MAJOR=$(echo __clang_major__ | $compiler -E -x c - | tail -n 1)
-MINOR=$(echo __clang_minor__ | $compiler -E -x c - | tail -n 1)
-PATCHLEVEL=$(echo __clang_patchlevel__ | $compiler -E -x c - | tail -n 1)
-printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
deleted file mode 100755
index ae353432539b..000000000000
--- a/scripts/gcc-version.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# gcc-version gcc-command
-#
-# Print the gcc version of `gcc-command' in a 5 or 6-digit form
-# such as `29503' for gcc-2.95.3, `30301' for gcc-3.3.1, etc.
-
-compiler="$*"
-
-if [ ${#compiler} -eq 0 ]; then
- echo "Error: No compiler specified." >&2
- printf "Usage:\n\t$0 <gcc-command>\n" >&2
- exit 1
-fi
-
-MAJOR=$(echo __GNUC__ | $compiler -E -x c - | tail -n 1)
-MINOR=$(echo __GNUC_MINOR__ | $compiler -E -x c - | tail -n 1)
-PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -x c - | tail -n 1)
-printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
--
2.27.0

Masahiro Yamada

unread,
Jan 13, 2021, 11:25:14 PM1/13/21
to linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Masahiro Yamada, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org
Changes in v2:
- fix the function name
index 000000000000..9c17c1de401c
+set -- $(get_compiler_info "$@")

Sedat Dilek

unread,
Jan 14, 2021, 2:07:15 AM1/14/21
to Masahiro Yamada, linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, Clang-Built-Linux ML, linux-...@vger.kernel.org
On Thu, Jan 14, 2021 at 5:17 AM Masahiro Yamada <masa...@kernel.org> wrote:
>
> Paul Gortmaker reported a regression in the GCC version check [1].
> If you use GCC 4.8, the build breaks before showing the error message
> "error Sorry, your version of GCC is too old - please use 4.9 or newer."
>

Hi Masahiro,

This patch is really helpful and user-friendly.

I ran into an issue with pahole requirement seen when
scripts/link-vmlinux.sh is run (see [1])
That happened after 3 hours of build-time.
Such things make me really unhappy.

Nathan proposed a fix for the pahole issue (see [2]).

I definitely will enjoy testing your v2.

Regards,
- Sedat -

[1] https://marc.info/?t=161036949500004&r=1&w=2
[2] https://marc.info/?t=161038851500003&r=1&w=2
> --
> You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-li...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20210114041623.226419-1-masahiroy%40kernel.org.

Ilie Halip

unread,
Jan 14, 2021, 2:55:03 AM1/14/21
to Masahiro Yamada, linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-built-linux, Linux Kernel Mailing List
Hi Masahiro,

> + #elif defined(__INTEL_COMPILER)
> + /* How to get the version of intel compiler? */
> + ICC 0 0 0

According to Intel documentation[1], this should do the trick:

ICC __INTEL_COMPILER __INTEL_COMPILER_UPDATE
__INTEL_COMPILER_BUILD_DATE

I don't have the compiler installed, but I tested this on godbolt[2] and
looks fine to me. What do you think?

[1] https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/macros/additional-predefined-macros.html
[2] https://godbolt.org/z/E5PE6f

I.H.

Sedat Dilek

unread,
Jan 14, 2021, 3:09:41 AM1/14/21
to Ilie Halip, Masahiro Yamada, linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-built-linux, Linux Kernel Mailing List
On Thu, Jan 14, 2021 at 8:55 AM Ilie Halip <ilie....@gmail.com> wrote:
>
> Hi Masahiro,
>
> > + #elif defined(__INTEL_COMPILER)
> > + /* How to get the version of intel compiler? */
> > + ICC 0 0 0
>
> According to Intel documentation[1], this should do the trick:
>
> ICC __INTEL_COMPILER __INTEL_COMPILER_UPDATE
> __INTEL_COMPILER_BUILD_DATE
>
> I don't have the compiler installed, but I tested this on godbolt[2] and
> looks fine to me. What do you think?
>

I remember at university I used ICC successfully with building a Linux-kernel.
Anyone has used ICC recently?

I cannot remember to have seen any bug-reports regarding ICC to
linux-kernel or linux-kbuild mailing-lists.

- Sedat -
> --
> You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-li...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/CAHFW8PRr6kjEE%3D7BSzWo7itSZgAhy_dhmnSe1yq5wMfDwEyJ9g%40mail.gmail.com.

Masahiro Yamada

unread,
Jan 14, 2021, 4:21:12 AM1/14/21
to Ilie Halip, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-built-linux, Linux Kernel Mailing List
Thanks.

The following is the result from godbolt
(except the beta releases of 21.1.*)


version __INTEL_COMPILER __INTEL_COMPILER_UPDATE
13.0.1 1300 (unsupported)
16.0.3 1600 3
17.0.0 1700 0
18.0.0 1800 0
19.0.0 1900 0
19.0.1 1900 0



Presumably, the version string xx.yy.zz corresponds to
__INTEL_COMPILER=xxyy
__INTEL_COMPILER_UPDATE=zz

The output from 19.0.1 does not make sense, though.



BTW, when I tried ICC a few years ago,
I could not build the kernel with it.


--
Best Regards
Masahiro Yamada

Nathan Chancellor

unread,
Jan 14, 2021, 11:49:22 AM1/14/21
to Masahiro Yamada, Ilie Halip, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nick Desaulniers, Will Deacon, clang-built-linux, Linux Kernel Mailing List
On Thu, Jan 14, 2021 at 06:20:15PM +0900, Masahiro Yamada wrote:
> BTW, when I tried ICC a few years ago,
> I could not build the kernel with it.

Looking at the history behind include/linux/compiler-intel.h, the last
time I see a change that actually references building a kernel with icc
was 503cf95c061a ("x86, build, icc: Remove uninitialized_var() from
compiler-intel.h"), all the way back in 2013. Since then, there do not
appear to be any meaningful changes; every change is basically doing
something for clang or gcc and not wanting to leave icc behind. It might
be worth considering tearing it out.

Cheers,
Nathan

Nathan Chancellor

unread,
Jan 14, 2021, 12:07:14 PM1/14/21
to Masahiro Yamada, linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Nick Desaulniers, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org
I would recommend the lore version of these links:

[1]: https://lore.kernel.org/r/20210110190807.1349...@windriver.com
[2]: https://lore.kernel.org/r/CAHk-=wh-+TMHPTFo1qs-MYyK7tZh-OQovA=pP3=e06aC...@mail.gmail.com
[3]: https://lore.kernel.org/r/2021011222483...@kernel.org

> Fixes: 87de84c9140e ("kbuild: remove cc-option test of -Werror=date-time")
> Reported-by: Paul Gortmaker <paul.go...@windriver.com>
> Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
> Signed-off-by: Masahiro Yamada <masa...@kernel.org>

I like this a lot, I think that erroring as early as possible when
something is misconfigured is a good user experience.

Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nathan Chancellor <natecha...@gmail.com>

Nick Desaulniers

unread,
Jan 14, 2021, 12:44:30 PM1/14/21
to Masahiro Yamada, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Will Deacon, clang-built-linux, LKML
SGTM

>
> I put the stub for ICC because I see <linux/compiler-intel.h> although
> I am not sure if building the kernel with ICC is well-supported.

I would like to see Ilie's suggestion added.
Removal of the check for __BPF_TRACING__ was my only concern, but I
think it's ok.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bc2dc4406c463
for context. Moving this version check from headers being parsed to
Kconfig is an improvement.
FWIW, I sometime run `make CC="/usr/bin/time -v clang"` then post
process the output:
https://github.com/ClangBuiltLinux/linux/issues/1086#issuecomment-670685565
Looks like this should be ok.

> +orig_args="$@"
> +set -- $(run_preprocessor "$@")

^ sorry, what is this statement doing? Ah, fixed in V2...probably
should have commented on that one. Sorry!

> +
> +name=$1
> +version=$2.$3.$4
> +
> +case "$name" in
> +GCC) min_version=$gcc_min_version;;
> +Clang) min_version=$clang_min_version;;
> +ICC) ;; # ICC min version undefined?

Maybe set to 0.0.0 or 1.0.0 for now? We can raise later, if we get
reports...ever.
--
Thanks,
~Nick Desaulniers

Nick Desaulniers

unread,
Jan 14, 2021, 12:46:46 PM1/14/21
to Sedat Dilek, Ilie Halip, Masahiro Yamada, Nathan Chancellor, clang-built-linux
On Thu, Jan 14, 2021 at 12:09 AM Sedat Dilek <sedat...@gmail.com> wrote:
>
> I remember at university I used ICC successfully with building a Linux-kernel.

Not asking you to disclose anything or date yourself, but to readers
who don't know when you attended university, that could have been this
year or 100 years ago.

> Anyone has used ICC recently?
>
> I cannot remember to have seen any bug-reports regarding ICC to
> linux-kernel or linux-kbuild mailing-lists.
--
Thanks,
~Nick Desaulniers

Masahiro Yamada

unread,
Jan 14, 2021, 1:08:16 PM1/14/21
to linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Masahiro Yamada, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org
scripts/Kconfig.include:46: Sorry, this compiler is not supported.
make[1]: *** [scripts/kconfig/Makefile:81: defconfig] Error 1
make: *** [Makefile:602: defconfig] Error 2

I removed the clang version check from <linux/compiler-clang.h>

For now, I did not touch <linux/compiler-gcc.h> in order to avoid
merge conflict with [3], which has been queued up in the arm64 tree.
We will be able to clean it up later.

The new script takes care of ICC because we have <linux/compiler-intel.h>
although I am not sure if building the kernel with ICC is well-supported.

[1] https://lkml.org/lkml/2021/1/10/250
[2] https://lkml.org/lkml/2021/1/12/1708
[3] https://lkml.org/lkml/2021/1/12/1533

Fixes: 87de84c9140e ("kbuild: remove cc-option test of -Werror=date-time")
Reported-by: Paul Gortmaker <paul.go...@windriver.com>
Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
Signed-off-by: Masahiro Yamada <masa...@kernel.org>
---

Changes in v3:
- add $(srctree)/ to fix out-of-tree build
- support ICC version

Changes in v2:
- fix the function name

include/linux/compiler-clang.h | 10 -----
init/Kconfig | 9 ++--
scripts/Kconfig.include | 6 +++
scripts/cc-version.sh | 76 ++++++++++++++++++++++++++++++++++
scripts/clang-version.sh | 19 ---------
scripts/gcc-version.sh | 20 ---------
6 files changed, 87 insertions(+), 53 deletions(-)
create mode 100755 scripts/cc-version.sh
delete mode 100755 scripts/clang-version.sh
delete mode 100755 scripts/gcc-version.sh

diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index 98cff1b4b088..04c0a5a717f7 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -3,16 +3,6 @@
#error "Please don't include <linux/compiler-clang.h> directly, include <linux/compiler.h> instead."
#endif

-#define CLANG_VERSION (__clang_major__ * 10000 \
- + __clang_minor__ * 100 \
- + __clang_patchlevel__)
-
-#if CLANG_VERSION < 100001
-#ifndef __BPF_TRACING__
index a5fe72c504ff..26c355a84c19 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -39,6 +39,12 @@ as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler
$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)

+# Get the compiler name, version, and error out if it is unsupported.
+cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC))
+$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.)
+cc-name := $(shell,set -- $(cc-info) && echo $1)
+cc-version := $(shell,set -- $(cc-info) && echo $2)
+
# Fail if the linker is gold as it's not capable of linking the kernel proper
$(error-if,$(success, $(LD) -v | grep -q gold), gold linker '$(LD)' not supported)

diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh
new file mode 100755
index 000000000000..818d233bb0ad
--- /dev/null
+++ b/scripts/cc-version.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Print the compiler name and its version in a 5 or 6-digit form.
+# Also, perform the minimum version check.
+
+set -e
+
+# When you raise the compiler version, please update
+# Documentation/process/changes.rst as well.
+gcc_min_version=4.9.0
+clang_min_version=10.0.1
+icc_min_version=16.0.3 # temporary
+
+# print the compiler name and versions
+get_compiler_info()
+{
+ cat <<- EOF | "$@" -E -P -x c - 2>/dev/null
+ #if defined(__clang__)
+ Clang __clang_major__ __clang_minor__ __clang_patchlevel__
+ #elif defined(__INTEL_COMPILER)
+ ICC __INTEL_COMPILER __INTEL_COMPILER_UPDATE
+ #elif defined(__GNUC__)
+ GCC __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
+ #else
+ unknown
+ #endif
+ EOF
+}
+
+# convert the version string x.y.z to a canonical 5 or 6-digit form
+get_canonical_version()
+{
+ IFS=.
+ set -- $1
+ echo $((10000 * $1 + 100 * $2 + $3))
+}
+
+# $@ instead of $1 because multiple words might be given e.g. CC="ccache gcc"
+orig_args="$@"
+set -- $(get_compiler_info "$@")
+
+name=$1
+
+case "$name" in
+GCC)
+ version=$2.$3.$4
+ min_version=$gcc_min_version
+ ;;
+Clang)
+ version=$2.$3.$4
+ min_version=$clang_min_version
+ ;;
+ICC)
+ version=$(($2 / 100)).$(($2 % 100)).$3
+ min_version=$icc_min_version
+ ;;
+*)
+ echo "$orig_args: unknown compiler" >&2
+ exit 1
+ ;;
+esac
+
+cversion=$(get_canonical_version $version)
+min_cversion=$(get_canonical_version $min_version)
+
+if [ "$cversion" -lt "$min_cversion" ]; then
+ echo >&2 "***"
+ echo >&2 "*** Compiler is too old."
+ echo >&2 "*** Your $name version: $version"
+ echo >&2 "*** Minimum $name version: $min_version"
+ echo >&2 "***"
+ exit 1

Miguel Ojeda

unread,
Jan 14, 2021, 1:15:09 PM1/14/21
to Masahiro Yamada, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-built-linux, linux-kernel
On Thu, Jan 14, 2021 at 5:25 AM Masahiro Yamada <masa...@kernel.org> wrote:
>
> The cc-version.sh also shows the error if the compiler is old:
>
> $ make defconfig CC=clang-9
> *** Default configuration is based on 'x86_64_defconfig'
> ***
> *** Compiler is too old.
> *** Your Clang version: 9.0.1
> *** Minimum Clang version: 10.0.1
> ***
> scripts/Kconfig.include:46: Sorry, this compiler is unsupported.

That looks nice. Hopefully we can do the same approach for other tools too!

> I put the stub for ICC because I see <linux/compiler-intel.h> although
> I am not sure if building the kernel with ICC is well-supported.

I doubt it, and there seems to be no maintainer listed either. I think
it could be considered for removal in an RFC.

Cheers,
Miguel

Nick Desaulniers

unread,
Jan 14, 2021, 1:22:10 PM1/14/21
to Masahiro Yamada, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Will Deacon, clang-built-linux, LKML
Consider Nathan's request to use lore links rather than lkml.org links.
https://lore.kernel.org/lkml/20210114170710.GA259754@ubuntu-m3-large-x86/
But I don't think that requires a v4 just for that.

Thanks for the patch.

Reviewed-by: Nick Desaulniers <ndesau...@google.com>
Tested-by: Nick Desaulniers <ndesau...@google.com>
--
Thanks,
~Nick Desaulniers

Nathan Chancellor

unread,
Jan 14, 2021, 1:23:22 PM1/14/21
to Masahiro Yamada, linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Nick Desaulniers, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org

Miguel Ojeda

unread,
Jan 14, 2021, 1:32:15 PM1/14/21
to Masahiro Yamada, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-built-linux, linux-kernel
On Thu, Jan 14, 2021 at 7:08 PM Masahiro Yamada <masa...@kernel.org> wrote:
>
> I unified the similar two scripts, gcc-version.sh and clang-version.sh
> into the new cc-version.sh. The old scripts invoked the compiler multiple
> times (3 times for gcc-version.sh, 4 times for clang-version.sh). I
> refactored the code so the new one invokes the compiler just once, and
> also tried my best to use shell-builtin commands where possible.

Tested v3 with GCC, Clang and an old GCC too:

$ scripts/cc-version.sh gcc-4.6.4
***
*** Compiler is too old.
*** Your GCC version: 4.6.4
*** Minimum GCC version: 4.9.0
***

Reviewed-by: Miguel Ojeda <oj...@kernel.org>
Tested-by: Miguel Ojeda <oj...@kernel.org>

Cheers,
Miguel

Masahiro Yamada

unread,
Jan 14, 2021, 1:54:53 PM1/14/21
to linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Masahiro Yamada, Nick Desaulniers, Nathan Chancellor, Miguel Ojeda, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org
Paul Gortmaker reported a regression in the GCC version check [1].
If you use GCC 4.8, the build breaks before showing the error message
"error Sorry, your version of GCC is too old - please use 4.9 or newer."

I do not want to apply his fix-up since it implies we would not be able
to remove any cc-option test. Anyway, I admit checking the GCC version
in <linux/compiler-gcc.h> is too late.

Almost at the same time, Linus also suggested to move the compiler
version error to Kconfig time. [2]

I unified the similar two scripts, gcc-version.sh and clang-version.sh
into the new cc-version.sh. The old scripts invoked the compiler multiple
times (3 times for gcc-version.sh, 4 times for clang-version.sh). I
refactored the code so the new one invokes the compiler just once, and
also tried my best to use shell-builtin commands where possible.

The new script runs faster.

$ time ./scripts/clang-version.sh clang
120000

real 0m0.029s
user 0m0.012s
sys 0m0.021s

$ time ./scripts/cc-version.sh clang
Clang 120000

real 0m0.009s
user 0m0.006s
sys 0m0.004s

The cc-version.sh also shows the error if the compiler is old:

$ make defconfig CC=clang-9
*** Default configuration is based on 'x86_64_defconfig'
***
*** Compiler is too old.
*** Your Clang version: 9.0.1
*** Minimum Clang version: 10.0.1
***
scripts/Kconfig.include:46: Sorry, this compiler is not supported.
make[1]: *** [scripts/kconfig/Makefile:81: defconfig] Error 1
make: *** [Makefile:602: defconfig] Error 2

I removed the clang version check from <linux/compiler-clang.h>

For now, I did not touch <linux/compiler-gcc.h> in order to avoid
merge conflict with [3], which has been queued up in the arm64 tree.
We can clean it up later.

The new script takes care of ICC because we have <linux/compiler-intel.h>
although I am not sure if building the kernel with ICC is well-supported.

Fixes: 87de84c9140e ("kbuild: remove cc-option test of -Werror=date-time")
Reported-by: Paul Gortmaker <paul.go...@windriver.com>
Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
Reviewed-by: Nick Desaulniers <ndesau...@google.com>
Tested-by: Nick Desaulniers <ndesau...@google.com>
Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nathan Chancellor <natecha...@gmail.com>
Reviewed-by: Miguel Ojeda <oj...@kernel.org>
Tested-by: Miguel Ojeda <oj...@kernel.org>
Signed-off-by: Masahiro Yamada <masa...@kernel.org>
---

Changes in v4:
- use lore version of the links
index a5fe72c504ff..0228cb9c74aa 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -39,6 +39,12 @@ as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler
$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)

+# Get the compiler name, version, and error out if it is not supported.

Sedat Dilek

unread,
Jan 14, 2021, 3:42:12 PM1/14/21
to Masahiro Yamada, linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Nick Desaulniers, Nathan Chancellor, Miguel Ojeda, Will Deacon, Clang-Built-Linux ML, linux-...@vger.kernel.org
Applied v4 to my custom clang-cfi patchset.

Here I tested with all Clang compilers I have installed:

[ Debian ]

dileks@iniza:~/src/linux-kernel/git$ scripts/cc-version.sh clang-11
Clang 110100
dileks@iniza:~/src/linux-kernel/git$ scripts/cc-version.sh clang-10
Clang 100001
dileks@iniza:~/src/linux-kernel/git$ scripts/cc-version.sh clang-9***
*** Compiler is too old.
*** Your Clang version: 9.0.1
*** Minimum Clang version: 10.0.1
***

[ Selfmade LLVM toolchain v11.1.0-rc1 ]

dileks@iniza:~/src/linux-kernel/git$ which clang
/opt/llvm-toolchain/bin/clang
dileks@iniza:~/src/linux-kernel/git$ scripts/cc-version.sh clang
Clang 110100

[ LLVM-12 from <apt.llvm.org> ]

dileks@iniza:~/src/linux-kernel/git$ scripts/cc-version.sh clang-12
Clang 120000

Feel free to add my:

Tested-by: Sedat Dilek <sedat...@gmail.com>

- Sedat -
> --
> You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-li...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20210114185354.308083-1-masahiroy%40kernel.org.

Sedat Dilek

unread,
Jan 14, 2021, 3:45:09 PM1/14/21
to Masahiro Yamada, linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Nick Desaulniers, Nathan Chancellor, Miguel Ojeda, Will Deacon, Clang-Built-Linux ML, linux-...@vger.kernel.org
^^^ That's from my selfmade toolchain.

dileks@iniza:~/src/linux-kernel/git$ scripts/cc-version.sh /usr/bin/clang-11
Clang 110001

- Sedat -

Masahiro Yamada

unread,
Jan 15, 2021, 5:55:38 PM1/15/21
to Miguel Ojeda, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-built-linux, linux-kernel
On Fri, Jan 15, 2021 at 3:15 AM Miguel Ojeda
<miguel.oje...@gmail.com> wrote:
>
> On Thu, Jan 14, 2021 at 5:25 AM Masahiro Yamada <masa...@kernel.org> wrote:
> >
> > The cc-version.sh also shows the error if the compiler is old:
> >
> > $ make defconfig CC=clang-9
> > *** Default configuration is based on 'x86_64_defconfig'
> > ***
> > *** Compiler is too old.
> > *** Your Clang version: 9.0.1
> > *** Minimum Clang version: 10.0.1
> > ***
> > scripts/Kconfig.include:46: Sorry, this compiler is unsupported.
>
> That looks nice. Hopefully we can do the same approach for other tools too!


Yes, I plan to merge scripts/ld-version.sh and scripts/lld-version.sh
in a similar way, and move the version check as well
once the following cleanups land in the upstream:

https://patchwork.kernel.org/project/linux-kbuild/patch/20201212165431.1...@kernel.org/
https://patchwork.kernel.org/project/linux-kbuild/patch/20201212165431.1...@kernel.org/


> > I put the stub for ICC because I see <linux/compiler-intel.h> although
> > I am not sure if building the kernel with ICC is well-supported.
>
> I doubt it, and there seems to be no maintainer listed either. I think
> it could be considered for removal in an RFC.


Yes, but that would require higher level acks,
and consult x86 and intel folks.

Please let this patch land first,
then we will discuss whether ICC is still used or not.




> Cheers,
> Miguel

Masahiro Yamada

unread,
Jan 15, 2021, 6:14:45 PM1/15/21
to linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Masahiro Yamada, Nick Desaulniers, Nathan Chancellor, Miguel Ojeda, Sedat Dilek, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org
Paul Gortmaker reported a regression in the GCC version check. [1]
If you use GCC 4.8, the build breaks before showing the error message
"error Sorry, your version of GCC is too old - please use 4.9 or newer."

I do not want to apply his fix-up since it implies we would not be able
to remove any cc-option test. Anyway, I admit checking the GCC version
in <linux/compiler-gcc.h> is too late.

Almost at the same time, Linus also suggested to move the compiler
version error to Kconfig time. [2]

I unified the two similar scripts, gcc-version.sh and clang-version.sh
into cc-version.sh. The old scripts invoked the compiler multiple times
(3 times for gcc-version.sh, 4 times for clang-version.sh). I refactored
the code so the new one invokes the compiler just once, and also tried
my best to use shell-builtin commands where possible.

The new script runs faster.

$ time ./scripts/clang-version.sh clang
120000

real 0m0.029s
user 0m0.012s
sys 0m0.021s

$ time ./scripts/cc-version.sh clang
Clang 120000

real 0m0.009s
user 0m0.006s
sys 0m0.004s

cc-version.sh also shows the error if the compiler is too old:

$ make defconfig CC=clang-9
*** Default configuration is based on 'x86_64_defconfig'
***
*** Compiler is too old.
*** Your Clang version: 9.0.1
*** Minimum Clang version: 10.0.1
***
scripts/Kconfig.include:46: Sorry, this compiler is not supported.
make[1]: *** [scripts/kconfig/Makefile:81: defconfig] Error 1
make: *** [Makefile:602: defconfig] Error 2

I removed the clang version check from <linux/compiler-clang.h>

For now, I did not touch <linux/compiler-gcc.h> in order to avoid
merge conflict with [3], which has been queued up in the arm64 tree.
We can clean it up later.

The new script takes care of ICC because we have <linux/compiler-intel.h>
although I am not sure if building the kernel with ICC is well-supported.

[1]: https://lore.kernel.org/r/20210110190807.1349...@windriver.com
[2]: https://lore.kernel.org/r/CAHk-=wh-+TMHPTFo1qs-MYyK7tZh-OQovA=pP3=e06aC...@mail.gmail.com
[3]: https://lore.kernel.org/r/2021011222483...@kernel.org

Fixes: 87de84c9140e ("kbuild: remove cc-option test of -Werror=date-time")
Reported-by: Paul Gortmaker <paul.go...@windriver.com>
Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
Reviewed-by: Nick Desaulniers <ndesau...@google.com>
Tested-by: Nick Desaulniers <ndesau...@google.com>
Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nathan Chancellor <natecha...@gmail.com>
Reviewed-by: Miguel Ojeda <oj...@kernel.org>
Tested-by: Miguel Ojeda <oj...@kernel.org>
Tested-by: Sedat Dilek <sedat...@gmail.com>
Signed-off-by: Masahiro Yamada <masa...@kernel.org>
---

Changes in v5:
- double-quote $(cc-name) in the CC_IS_GCC and CC_IS_CLANG
index b77c60f8b963..8f04e5db2001 100644

Masahiro Yamada

unread,
Jan 15, 2021, 6:36:37 PM1/15/21
to linux-...@vger.kernel.org, Paul Gortmaker, Linus Torvalds, Masahiro Yamada, Nick Desaulniers, Nathan Chancellor, Miguel Ojeda, Sedat Dilek, Will Deacon, clang-bu...@googlegroups.com, linux-...@vger.kernel.org
The new script takes care of ICC because we have <linux/compiler-intel.h>
although I am not sure if building the kernel with ICC is well-supported.

[1]: https://lore.kernel.org/r/20210110190807.1349...@windriver.com
[2]: https://lore.kernel.org/r/CAHk-=wh-+TMHPTFo1qs-MYyK7tZh-OQovA=pP3=e06aC...@mail.gmail.com

Fixes: 87de84c9140e ("kbuild: remove cc-option test of -Werror=date-time")
Reported-by: Paul Gortmaker <paul.go...@windriver.com>
Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
Reviewed-by: Nick Desaulniers <ndesau...@google.com>
Tested-by: Nick Desaulniers <ndesau...@google.com>
Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nathan Chancellor <natecha...@gmail.com>
Reviewed-by: Miguel Ojeda <oj...@kernel.org>
Tested-by: Miguel Ojeda <oj...@kernel.org>
Tested-by: Sedat Dilek <sedat...@gmail.com>
Signed-off-by: Masahiro Yamada <masa...@kernel.org>
---

Changes in v6:
- Now that https://lore.kernel.org/r/2021011222483...@kernel.org
landed in Linus' tree, I cleaned up <linux/compiler-gcc.h> as well.

Changes in v5:
- double-quote $(cc-name) in the CC_IS_GCC and CC_IS_CLANG

Changes in v4:
- use lore version of the links

Changes in v3:
- add $(srctree)/ to fix out-of-tree build
- support ICC version

Changes in v2:
- fix the function name

include/linux/compiler-clang.h | 10 -----
include/linux/compiler-gcc.h | 11 -----
init/Kconfig | 9 ++--
scripts/Kconfig.include | 6 +++
scripts/cc-version.sh | 82 ++++++++++++++++++++++++++++++++++
scripts/clang-version.sh | 19 --------
scripts/gcc-version.sh | 20 ---------
7 files changed, 93 insertions(+), 64 deletions(-)
create mode 100755 scripts/cc-version.sh
delete mode 100755 scripts/clang-version.sh
delete mode 100755 scripts/gcc-version.sh

diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index 98cff1b4b088..04c0a5a717f7 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -3,16 +3,6 @@
#error "Please don't include <linux/compiler-clang.h> directly, include <linux/compiler.h> instead."
#endif

-#define CLANG_VERSION (__clang_major__ * 10000 \
- + __clang_minor__ * 100 \
- + __clang_patchlevel__)
-
-#if CLANG_VERSION < 100001
-#ifndef __BPF_TRACING__
-# error Sorry, your version of Clang is too old - please use 10.0.1 or newer.
-#endif
-#endif
-
/* Compiler specific definitions for Clang compiler */

/* same as gcc, this was present in clang-2.6 so we can assume it works
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 555ab0fddbef..48750243db4c 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -10,17 +10,6 @@
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)

-/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 */
-#if GCC_VERSION < 40900
-# error Sorry, your version of GCC is too old - please use 4.9 or newer.
-#elif defined(CONFIG_ARM64) && GCC_VERSION < 50100
-/*
- * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63293
- * https://lore.kernel.org/r/2021010711...@shell.armlinux.org.uk
- */
-# error Sorry, your version of GCC is too old - please use 5.1 or newer.
-#endif
-
/*
* This macro obfuscates arithmetic on a variable address so that gcc
* shouldn't recognize the original var, and make assumptions about it.
index 000000000000..d1edbe4d140c
--- /dev/null
+++ b/scripts/cc-version.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Print the compiler name and its version in a 5 or 6-digit form.
+# Also, perform the minimum version check.
+
+set -e
+
+# When you raise the compiler version, please update
+# Documentation/process/changes.rst as well.
+gcc_min_version=4.9.0
+clang_min_version=10.0.1
+icc_min_version=16.0.3 # temporary
+
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63293
+# https://lore.kernel.org/r/2021010711...@shell.armlinux.org.uk
+if [ "$SRCARCH" = arm64 ]; then
+ gcc_min_version=5.1.0
+fi

Miguel Ojeda

unread,
Jan 15, 2021, 8:33:16 PM1/15/21
to Masahiro Yamada, Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nathan Chancellor, Nick Desaulniers, Will Deacon, clang-built-linux, linux-kernel
On Fri, Jan 15, 2021 at 11:55 PM Masahiro Yamada <masa...@kernel.org> wrote:
>
> Yes, I plan to merge scripts/ld-version.sh and scripts/lld-version.sh
> in a similar way, and move the version check as well
> once the following cleanups land in the upstream:
>
> https://patchwork.kernel.org/project/linux-kbuild/patch/20201212165431.1...@kernel.org/
> https://patchwork.kernel.org/project/linux-kbuild/patch/20201212165431.1...@kernel.org/

Nice!

> Yes, but that would require higher level acks,
> and consult x86 and intel folks.
>
> Please let this patch land first,
> then we will discuss whether ICC is still used or not.

I was not implying to delay this patch -- rather to start an
independent RFC to discuss it. This patch should go in regardless of
that, of course :-)

Cheers,
Miguel

Masahiro Yamada

unread,
Jan 18, 2021, 9:15:12 PM1/18/21
to Linux Kbuild mailing list, Paul Gortmaker, Linus Torvalds, Nick Desaulniers, Nathan Chancellor, Miguel Ojeda, Sedat Dilek, Will Deacon, clang-built-linux, Linux Kernel Mailing List
Applied to linux-kbuild.
> --
> You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-li...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20210115233542.70789-1-masahiroy%40kernel.org.
Reply all
Reply to author
Forward
0 new messages