xref: /OK3568_Linux_fs/device/rockchip/common/linux-kbuild/armhf/linux-kbuild-5.10/scripts/setlocalversion (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/sh
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# This scripts adds local version information from the version
5*4882a593Smuzhiyun# control systems git, mercurial (hg) and subversion (svn).
6*4882a593Smuzhiyun#
7*4882a593Smuzhiyun# If something goes wrong, send a mail the kernel build mailinglist
8*4882a593Smuzhiyun# (see MAINTAINERS) and CC Nico Schottelius
9*4882a593Smuzhiyun# <nico-linuxsetlocalversion -at- schottelius.org>.
10*4882a593Smuzhiyun#
11*4882a593Smuzhiyun#
12*4882a593Smuzhiyun
13*4882a593Smuzhiyunusage() {
14*4882a593Smuzhiyun	echo "Usage: $0 [--save-scmversion] [srctree] [branch] [kmi-generation]" >&2
15*4882a593Smuzhiyun	exit 1
16*4882a593Smuzhiyun}
17*4882a593Smuzhiyun
18*4882a593Smuzhiyunscm_only=false
19*4882a593Smuzhiyunsrctree=.
20*4882a593Smuzhiyunandroid_release=
21*4882a593Smuzhiyunkmi_generation=
22*4882a593Smuzhiyunif test "$1" = "--save-scmversion"; then
23*4882a593Smuzhiyun	scm_only=true
24*4882a593Smuzhiyun	shift
25*4882a593Smuzhiyunfi
26*4882a593Smuzhiyunif test $# -gt 0; then
27*4882a593Smuzhiyun	srctree=$1
28*4882a593Smuzhiyun	shift
29*4882a593Smuzhiyunfi
30*4882a593Smuzhiyunif test $# -gt 0; then
31*4882a593Smuzhiyun	# Extract the Android release version. If there is no match, then return 255
32*4882a593Smuzhiyun	# and clear the var $android_release
33*4882a593Smuzhiyun	android_release=`echo "$1" | sed -e '/android[0-9]\{2,\}/!{q255}; \
34*4882a593Smuzhiyun		s/^\(android[0-9]\{2,\}\)-.*/\1/'`
35*4882a593Smuzhiyun	if test $? -ne 0; then
36*4882a593Smuzhiyun		android_release=
37*4882a593Smuzhiyun	fi
38*4882a593Smuzhiyun	shift
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun	if test $# -gt 0; then
41*4882a593Smuzhiyun		kmi_generation=$1
42*4882a593Smuzhiyun		[ $(expr $kmi_generation : '^[0-9]\+$') -eq 0 ] && usage
43*4882a593Smuzhiyun		shift
44*4882a593Smuzhiyun	fi
45*4882a593Smuzhiyunfi
46*4882a593Smuzhiyunif test $# -gt 0 -o ! -d "$srctree"; then
47*4882a593Smuzhiyun	usage
48*4882a593Smuzhiyunfi
49*4882a593Smuzhiyun
50*4882a593Smuzhiyunscm_version()
51*4882a593Smuzhiyun{
52*4882a593Smuzhiyun	local short
53*4882a593Smuzhiyun	short=false
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun	cd "$srctree"
56*4882a593Smuzhiyun	if test -e .scmversion; then
57*4882a593Smuzhiyun		cat .scmversion
58*4882a593Smuzhiyun		return
59*4882a593Smuzhiyun	fi
60*4882a593Smuzhiyun	if test "$1" = "--short"; then
61*4882a593Smuzhiyun		short=true
62*4882a593Smuzhiyun	fi
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun	# Check for git and a git repo.
65*4882a593Smuzhiyun	if head=$(git rev-parse --verify HEAD 2>/dev/null); then
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun		if [ -n "$android_release" ] && [ -n "$kmi_generation" ]; then
68*4882a593Smuzhiyun			printf '%s' "-$android_release-$kmi_generation"
69*4882a593Smuzhiyun		elif [ -n "$android_release" ]; then
70*4882a593Smuzhiyun			printf '%s' "-$android_release"
71*4882a593Smuzhiyun		fi
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun		# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
74*4882a593Smuzhiyun		# it, because this version is defined in the top level Makefile.
75*4882a593Smuzhiyun		if [ -z "$(git describe --exact-match 2>/dev/null)" ]; then
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun			# If only the short version is requested, don't bother
78*4882a593Smuzhiyun			# running further git commands
79*4882a593Smuzhiyun			if $short; then
80*4882a593Smuzhiyun				echo "+"
81*4882a593Smuzhiyun				return
82*4882a593Smuzhiyun			fi
83*4882a593Smuzhiyun			# If we are past a tagged commit (like
84*4882a593Smuzhiyun			# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
85*4882a593Smuzhiyun			#
86*4882a593Smuzhiyun			# Ensure the abbreviated sha1 has exactly 12
87*4882a593Smuzhiyun			# hex characters, to make the output
88*4882a593Smuzhiyun			# independent of git version, local
89*4882a593Smuzhiyun			# core.abbrev settings and/or total number of
90*4882a593Smuzhiyun			# objects in the current repository - passing
91*4882a593Smuzhiyun			# --abbrev=12 ensures a minimum of 12, and the
92*4882a593Smuzhiyun			# awk substr() then picks the 'g' and first 12
93*4882a593Smuzhiyun			# hex chars.
94*4882a593Smuzhiyun			if atag="$(git describe --abbrev=12 2>/dev/null)"; then
95*4882a593Smuzhiyun				echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),substr($(NF),0,13))}'
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun			# If we don't have a tag at all we print -g{commitish},
98*4882a593Smuzhiyun			# again using exactly 12 hex chars.
99*4882a593Smuzhiyun			else
100*4882a593Smuzhiyun				head="$(echo $head | cut -c1-12)"
101*4882a593Smuzhiyun				printf '%s%s' -g $head
102*4882a593Smuzhiyun			fi
103*4882a593Smuzhiyun		fi
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun		# Is this git on svn?
106*4882a593Smuzhiyun		if git config --get svn-remote.svn.url >/dev/null; then
107*4882a593Smuzhiyun			printf -- '-svn%s' "$(git svn find-rev $head)"
108*4882a593Smuzhiyun		fi
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun		# Check for uncommitted changes.
111*4882a593Smuzhiyun		# First, with git-status, but --no-optional-locks is only
112*4882a593Smuzhiyun		# supported in git >= 2.14, so fall back to git-diff-index if
113*4882a593Smuzhiyun		# it fails. Note that git-diff-index does not refresh the
114*4882a593Smuzhiyun		# index, so it may give misleading results. See
115*4882a593Smuzhiyun		# git-update-index(1), git-diff-index(1), and git-status(1).
116*4882a593Smuzhiyun		if {
117*4882a593Smuzhiyun			git --no-optional-locks status -uno --porcelain 2>/dev/null ||
118*4882a593Smuzhiyun			git diff-index --name-only HEAD
119*4882a593Smuzhiyun		} | grep -qvE '^(.. )?scripts/package'; then
120*4882a593Smuzhiyun			printf '%s' -dirty
121*4882a593Smuzhiyun		fi
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun		# All done with git
124*4882a593Smuzhiyun		return
125*4882a593Smuzhiyun	fi
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun	# Check for mercurial and a mercurial repo.
128*4882a593Smuzhiyun	if hgid=$(hg id 2>/dev/null); then
129*4882a593Smuzhiyun		# Do we have an tagged version?  If so, latesttagdistance == 1
130*4882a593Smuzhiyun		if [ "$(hg log -r . --template '{latesttagdistance}')" = "1" ]; then
131*4882a593Smuzhiyun			id=$(hg log -r . --template '{latesttag}')
132*4882a593Smuzhiyun			printf '%s%s' -hg "$id"
133*4882a593Smuzhiyun		else
134*4882a593Smuzhiyun			tag=$(printf '%s' "$hgid" | cut -d' ' -f2)
135*4882a593Smuzhiyun			if [ -z "$tag" -o "$tag" = tip ]; then
136*4882a593Smuzhiyun				id=$(printf '%s' "$hgid" | sed 's/[+ ].*//')
137*4882a593Smuzhiyun				printf '%s%s' -hg "$id"
138*4882a593Smuzhiyun			fi
139*4882a593Smuzhiyun		fi
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun		# Are there uncommitted changes?
142*4882a593Smuzhiyun		# These are represented by + after the changeset id.
143*4882a593Smuzhiyun		case "$hgid" in
144*4882a593Smuzhiyun			*+|*+\ *) printf '%s' -dirty ;;
145*4882a593Smuzhiyun		esac
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun		# All done with mercurial
148*4882a593Smuzhiyun		return
149*4882a593Smuzhiyun	fi
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun	# Check for svn and a svn repo.
152*4882a593Smuzhiyun	if rev=$(LANG= LC_ALL= LC_MESSAGES=C svn info 2>/dev/null | grep '^Last Changed Rev'); then
153*4882a593Smuzhiyun		rev=$(echo $rev | awk '{print $NF}')
154*4882a593Smuzhiyun		printf -- '-svn%s' "$rev"
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun		# All done with svn
157*4882a593Smuzhiyun		return
158*4882a593Smuzhiyun	fi
159*4882a593Smuzhiyun}
160*4882a593Smuzhiyun
161*4882a593Smuzhiyuncollect_files()
162*4882a593Smuzhiyun{
163*4882a593Smuzhiyun	local file res=
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun	for file; do
166*4882a593Smuzhiyun		case "$file" in
167*4882a593Smuzhiyun		*\~*)
168*4882a593Smuzhiyun			continue
169*4882a593Smuzhiyun			;;
170*4882a593Smuzhiyun		esac
171*4882a593Smuzhiyun		if test -e "$file"; then
172*4882a593Smuzhiyun			res="$res$(cat "$file")"
173*4882a593Smuzhiyun		fi
174*4882a593Smuzhiyun	done
175*4882a593Smuzhiyun	echo "$res"
176*4882a593Smuzhiyun}
177*4882a593Smuzhiyun
178*4882a593Smuzhiyunif $scm_only; then
179*4882a593Smuzhiyun	if test ! -e .scmversion; then
180*4882a593Smuzhiyun		res=$(scm_version)
181*4882a593Smuzhiyun		echo "$res" >.scmversion
182*4882a593Smuzhiyun	fi
183*4882a593Smuzhiyun	exit
184*4882a593Smuzhiyunfi
185*4882a593Smuzhiyun
186*4882a593Smuzhiyunif test -e include/config/auto.conf; then
187*4882a593Smuzhiyun	. include/config/auto.conf
188*4882a593Smuzhiyunelse
189*4882a593Smuzhiyun	echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
190*4882a593Smuzhiyun	exit 1
191*4882a593Smuzhiyunfi
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun# localversion* files in the build and source directory
194*4882a593Smuzhiyunres="$(collect_files localversion*)"
195*4882a593Smuzhiyunif test ! "$srctree" -ef .; then
196*4882a593Smuzhiyun	res="$res$(collect_files "$srctree"/localversion*)"
197*4882a593Smuzhiyunfi
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun# CONFIG_LOCALVERSION and LOCALVERSION (if set)
200*4882a593Smuzhiyunres="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun# scm version string if not at a tagged commit
203*4882a593Smuzhiyunif test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
204*4882a593Smuzhiyun	# full scm version string
205*4882a593Smuzhiyun	res="$res$(scm_version)"
206*4882a593Smuzhiyunelse
207*4882a593Smuzhiyun	# append a plus sign if the repository is not in a clean
208*4882a593Smuzhiyun	# annotated or signed tagged state (as git describe only
209*4882a593Smuzhiyun	# looks at signed or annotated tags - git tag -a/-s) and
210*4882a593Smuzhiyun	# LOCALVERSION= is not specified
211*4882a593Smuzhiyun	if test "${LOCALVERSION+set}" != "set"; then
212*4882a593Smuzhiyun		scm=$(scm_version --short)
213*4882a593Smuzhiyun		res="$res${scm:++}"
214*4882a593Smuzhiyun	fi
215*4882a593Smuzhiyunfi
216*4882a593Smuzhiyun
217*4882a593Smuzhiyunecho "$res"
218