From 2df8220cc511326508ec4da2f43ef69311bdd7b9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 28 Aug 2022 11:39:53 +0900 Subject: kbuild: build init/built-in.a just once Kbuild builds init/built-in.a twice; first during the ordinary directory descending, second from scripts/link-vmlinux.sh. We do this because UTS_VERSION contains the build version and the timestamp. We cannot update it during the normal directory traversal since we do not yet know if we need to update vmlinux. UTS_VERSION is temporarily calculated, but omitted from the update check. Otherwise, vmlinux would be rebuilt every time. When Kbuild results in running link-vmlinux.sh, it increments the version number in the .version file and takes the timestamp at that time to really fix UTS_VERSION. However, updating the same file twice is a footgun. To avoid nasty timestamp issues, all build artifacts that depend on init/built-in.a are atomically generated in link-vmlinux.sh, where some of them do not need rebuilding. To fix this issue, this commit changes as follows: [1] Split UTS_VERSION out to include/generated/utsversion.h from include/generated/compile.h include/generated/utsversion.h is generated just before the vmlinux link. It is generated under include/generated/ because some decompressors (s390, x86) use UTS_VERSION. [2] Split init_uts_ns and linux_banner out to init/version-timestamp.c from init/version.c init_uts_ns and linux_banner contain UTS_VERSION. During the ordinary directory descending, they are compiled with __weak and used to determine if vmlinux needs relinking. Just before the vmlinux link, they are compiled without __weak to embed the real version and timestamp. Signed-off-by: Masahiro Yamada --- scripts/link-vmlinux.sh | 17 +++------- scripts/mkcompile_h | 89 ++++++------------------------------------------- 2 files changed, 15 insertions(+), 91 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index eecc1863e556..8d982574145a 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -75,6 +75,8 @@ vmlinux_link() objs="${objs} .vmlinux.export.o" fi + objs="${objs} init/version-timestamp.o" + if [ "${SRCARCH}" = "um" ]; then wl=-Wl, ld="${CC}" @@ -213,19 +215,6 @@ if [ "$1" = "clean" ]; then exit 0 fi -# Update version -info GEN .version -if [ -r .version ]; then - VERSION=$(expr 0$(cat .version) + 1) - echo $VERSION > .version -else - rm -f .version - echo 1 > .version -fi; - -# final build of init/ -${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 - #link vmlinux.o ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o" @@ -260,6 +249,8 @@ if is_enabled CONFIG_MODULES; then ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o fi +${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o + btf_vmlinux_bin_o="" if is_enabled CONFIG_DEBUG_INFO_BTF; then btf_vmlinux_bin_o=.btf.vmlinux.bin.o diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index ca40a5258c87..f1a820d49e53 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -1,14 +1,9 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -TARGET=$1 -ARCH=$2 -SMP=$3 -PREEMPT=$4 -PREEMPT_DYNAMIC=$5 -PREEMPT_RT=$6 -CC_VERSION="$7" -LD=$8 +UTS_MACHINE=$1 +CC_VERSION="$2" +LD=$3 # Do not expand names set -f @@ -17,17 +12,6 @@ set -f LC_ALL=C export LC_ALL -if [ -z "$KBUILD_BUILD_VERSION" ]; then - VERSION=$(cat .version 2>/dev/null || echo 1) -else - VERSION=$KBUILD_BUILD_VERSION -fi - -if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then - TIMESTAMP=`date` -else - TIMESTAMP=$KBUILD_BUILD_TIMESTAMP -fi if test -z "$KBUILD_BUILD_USER"; then LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/') else @@ -39,63 +23,12 @@ else LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST fi -UTS_VERSION="#$VERSION" -CONFIG_FLAGS="" -if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi - -if [ -n "$PREEMPT_RT" ] ; then - CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_RT" -elif [ -n "$PREEMPT_DYNAMIC" ] ; then - CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_DYNAMIC" -elif [ -n "$PREEMPT" ] ; then - CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT" -fi - -# Truncate to maximum length -UTS_LEN=64 -UTS_VERSION="$(echo $UTS_VERSION $CONFIG_FLAGS $TIMESTAMP | cut -b -$UTS_LEN)" - -# Generate a temporary compile.h - -{ echo /\* This file is auto generated, version $VERSION \*/ - if [ -n "$CONFIG_FLAGS" ] ; then echo "/* $CONFIG_FLAGS */"; fi +LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \ + | sed 's/[[:space:]]*$//') - echo \#define UTS_MACHINE \"$ARCH\" - - echo \#define UTS_VERSION \"$UTS_VERSION\" - - printf '#define LINUX_COMPILE_BY "%s"\n' "$LINUX_COMPILE_BY" - echo \#define LINUX_COMPILE_HOST \"$LINUX_COMPILE_HOST\" - - LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \ - | sed 's/[[:space:]]*$//') - printf '#define LINUX_COMPILER "%s"\n' "$CC_VERSION, $LD_VERSION" -} > .tmpcompile - -# Only replace the real compile.h if the new one is different, -# in order to preserve the timestamp and avoid unnecessary -# recompilations. -# We don't consider the file changed if only the date/time changed, -# unless KBUILD_BUILD_TIMESTAMP was explicitly set (e.g. for -# reproducible builds with that value referring to a commit timestamp). -# A kernel config change will increase the generation number, thus -# causing compile.h to be updated (including date/time) due to the -# changed comment in the -# first line. - -if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then - IGNORE_PATTERN="UTS_VERSION" -else - IGNORE_PATTERN="NOT_A_PATTERN_TO_BE_MATCHED" -fi - -if [ -r $TARGET ] && \ - grep -v $IGNORE_PATTERN $TARGET > .tmpver.1 && \ - grep -v $IGNORE_PATTERN .tmpcompile > .tmpver.2 && \ - cmp -s .tmpver.1 .tmpver.2; then - rm -f .tmpcompile -else - echo " UPD $TARGET" - mv -f .tmpcompile $TARGET -fi -rm -f .tmpver.1 .tmpver.2 +cat <