• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3#
4# This scripts adds local version information from the version
5# control systems git, mercurial (hg) and subversion (svn).
6#
7# If something goes wrong, send a mail the kernel build mailinglist
8# (see MAINTAINERS) and CC Nico Schottelius
9# <nico-linuxsetlocalversion -at- schottelius.org>.
10#
11#
12
13usage() {
14	echo "Usage: $0 [--save-scmversion] [--save-tag] [srctree] [branch] [kmi-generation]" >&2
15	exit 1
16}
17
18scm_only=false
19save_tag=false
20srctree=.
21android_release=
22kmi_generation=
23if test "$1" = "--save-scmversion"; then
24	scm_only=true
25	shift
26fi
27if test "$1" = "--save-tag"; then
28	save_tag=true
29	shift
30fi
31if test $# -gt 0; then
32	srctree=$1
33	shift
34fi
35if test $# -gt 0; then
36	# Extract the Android release version. If there is no match, then return 255
37	# and clear the var $android_release
38	android_release=`echo "$1" | sed -e '/android[0-9]\{2,\}/!{q255}; \
39		s/^\(android[0-9]\{2,\}\)-.*/\1/'`
40	if test $? -ne 0; then
41		android_release=
42	fi
43	shift
44
45	if test $# -gt 0; then
46		kmi_generation=$1
47		[ $(expr $kmi_generation : '^[0-9]\+$') -eq 0 ] && usage
48		shift
49	fi
50fi
51if test $# -gt 0 -o ! -d "$srctree"; then
52	usage
53fi
54
55scm_version()
56{
57	local short
58	short=false
59
60	cd "$srctree"
61	if test -e .scmversion; then
62		cat .scmversion
63		return
64	fi
65	if test "$1" = "--short"; then
66		short=true
67	fi
68
69	# Check for git and a git repo.
70	if head=$(git rev-parse --verify HEAD 2>/dev/null); then
71
72		if [ -n "$android_release" ] && [ -n "$kmi_generation" ]; then
73			printf '%s' "-$android_release-$kmi_generation"
74		elif [ -n "$android_release" ]; then
75			printf '%s' "-$android_release"
76		fi
77		# If we are at a tagged commit (like "v2.6.30-rc6"), by default
78		# we ignore it and manually define VERSION in the top level
79		# Makefile. Alternatively, set --save-tag to keep the tag.
80		tag="$(git describe --exact-match 2>/dev/null)"
81		if [ -z "$tag" ]; then
82			# If only the short version is requested, don't bother
83			# running further git commands
84			if $short; then
85				echo "+"
86				return
87			fi
88			# If we are past a tagged commit (like
89			# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
90			if atag="$(git describe 2>/dev/null)"; then
91				echo "$atag" | awk -F- '{printf("-%05d", $(NF-1))}'
92			fi
93
94			# Add -g and exactly 12 hex chars.
95			printf '%s%s' -g "$(echo $head | cut -c1-12)"
96		elif $save_tag; then
97			printf '%s' - "$(echo $tag)"
98		fi
99
100		# Check for uncommitted changes.
101		# This script must avoid any write attempt to the source tree,
102		# which might be read-only.
103		# You cannot use 'git describe --dirty' because it tries to
104		# create .git/index.lock .
105		# First, with git-status, but --no-optional-locks is only
106		# supported in git >= 2.14, so fall back to git-diff-index if
107		# it fails. Note that git-diff-index does not refresh the
108		# index, so it may give misleading results. See
109		# git-update-index(1), git-diff-index(1), and git-status(1).
110		if {
111			git --no-optional-locks status -uno --porcelain 2>/dev/null ||
112			git diff-index --name-only HEAD
113		} | read dummy; then
114			printf '%s' -dirty
115		fi
116	fi
117}
118
119collect_files()
120{
121	local file res=
122
123	for file; do
124		case "$file" in
125		*\~*)
126			continue
127			;;
128		esac
129		if test -e "$file"; then
130			res="$res$(cat "$file")"
131		fi
132	done
133	echo "$res"
134}
135
136if $scm_only; then
137	if test ! -e .scmversion; then
138		res=$(scm_version)
139		echo "$res" >.scmversion
140	fi
141	exit
142fi
143
144if test -e include/config/auto.conf; then
145	. include/config/auto.conf
146else
147	echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
148	exit 1
149fi
150
151# localversion* files in the build and source directory
152res="$(collect_files localversion*)"
153if test ! "$srctree" -ef .; then
154	res="$res$(collect_files "$srctree"/localversion*)"
155fi
156
157# CONFIG_LOCALVERSION and LOCALVERSION (if set)
158res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
159
160# scm version string if not at a tagged commit
161if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
162	# full scm version string
163	res="$res$(scm_version)"
164elif [ "${LOCALVERSION+set}" != "set" ]; then
165	# If the variable LOCALVERSION is not set, append a plus
166	# sign if the repository is not in a clean annotated or
167	# signed tagged state (as git describe only looks at signed
168	# or annotated tags - git tag -a/-s).
169	#
170	# If the variable LOCALVERSION is set (including being set
171	# to an empty string), we don't want to append a plus sign.
172	scm=$(scm_version --short)
173	res="$res${scm:++}"
174fi
175
176# finally, add the abXXX number if BUILD_NUMBER is set
177if test -n "${BUILD_NUMBER}"; then
178	res="$res-ab${BUILD_NUMBER}"
179fi
180
181echo "$res"
182