1. 程式人生 > 其它 >Linux核心對GCC版本的檢測

Linux核心對GCC版本的檢測

在編譯linux核心時,linux會檢查當前使用的gcc的版本,如果太老的話,就無法編譯linux。

執行命令make ARCH=x86_64 defconfig時,提示如下錯誤:

*** Default configuration is based on 'x86_64_defconfig'
***
*** Compiler is too old.
***   Your GCC version:    4.8.5
***   Minimum GCC version: 5.1.0
***
scripts/Kconfig.include:44: Sorry, this compiler is not supported.
make[2]: *** [defconfig] Error 1
make[1]: *** [defconfig] Error 2
make: *** [__sub-make] Error 2

下面是檢查邏輯:(以Linux-5.16.12為例)

Kconfig
--> scripts/Kconfig.include
--> 獲取編譯器的name和版本:

# Get the compiler name, version, and error out if it is not supported.
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)

上面呼叫cc-version.sh獲取編譯的name和版本,其中會檢查版本是否符合要求。

#!/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

# 獲取編譯器的name和版本
# Print the compiler name and some version components.
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命令可以修改$1 $2 $3 $4的值
set -- $(get_compiler_info "$@")

name=$1

min_tool_version=$(dirname $0)/min-tool-version.sh

case "$name" in
GCC)
        version=$2.$3.$4
		# 獲取GCC的版本
        min_version=$($min_tool_version gcc)
        ;;
Clang)
        version=$2.$3.$4
        min_version=$($min_tool_version llvm)
        ;;
ICC)
        version=$(($2 / 100)).$(($2 % 100)).$3
        min_version=$($min_tool_version icc)
        ;;
*)
        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
fi

echo $name $cversion

如果成功的話,會返回編譯器的名字和版本,否則會退出編譯。

上面使用min-tool-version.sh來獲取最低要求的編譯器版本,內容如下:

cat scripts/min-tool-version.sh
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
#
# Print the minimum supported version of the given tool.
# When you raise the minimum version, please update
# Documentation/process/changes.rst as well.

set -e

if [ $# != 1 ]; then
        echo "Usage: $0 toolname" >&2
        exit 1
fi

case "$1" in
binutils)
        echo 2.23.0
        ;;
gcc)
        echo 5.1.0
        ;;
icc)
        # temporary
        echo 16.0.3
        ;;
llvm)
        # https://lore.kernel.org/r/YMtib5hKVyNknZt3@osiris/
        if [ "$SRCARCH" = s390 ]; then
                echo 13.0.0
        else
                echo 10.0.1
        fi
        ;;
*)
        echo "$1: unknown tool" >&2
        exit 1
        ;;
esac

上面對GCC版本要求最低為5.1.0

下面是一些linux對GCC版本的要求:

Linux版本 最低GCC版本
5.16.12 5.1.0