xref: /OK3568_Linux_fs/device/rockchip/common/linux-kbuild/aarch64/linux-kbuild-4.19/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 test -z "$(git rev-parse --show-cdup 2>/dev/null)" &&
66*4882a593Smuzhiyun	   head=$(git rev-parse --verify HEAD 2>/dev/null); then
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun		if [ -n "$android_release" ] && [ -n "$kmi_generation" ]; then
69*4882a593Smuzhiyun			printf '%s' "-$android_release-$kmi_generation"
70*4882a593Smuzhiyun		elif [ -n "$android_release" ]; then
71*4882a593Smuzhiyun			printf '%s' "-$android_release"
72*4882a593Smuzhiyun		fi
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun		# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
75*4882a593Smuzhiyun		# it, because this version is defined in the top level Makefile.
76*4882a593Smuzhiyun		if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun			# If only the short version is requested, don't bother
79*4882a593Smuzhiyun			# running further git commands
80*4882a593Smuzhiyun			if $short; then
81*4882a593Smuzhiyun				echo "+"
82*4882a593Smuzhiyun				return
83*4882a593Smuzhiyun			fi
84*4882a593Smuzhiyun			# If we are past a tagged commit (like
85*4882a593Smuzhiyun			# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
86*4882a593Smuzhiyun			#
87*4882a593Smuzhiyun			# Ensure the abbreviated sha1 has exactly 12
88*4882a593Smuzhiyun			# hex characters, to make the output
89*4882a593Smuzhiyun			# independent of git version, local
90*4882a593Smuzhiyun			# core.abbrev settings and/or total number of
91*4882a593Smuzhiyun			# objects in the current repository - passing
92*4882a593Smuzhiyun			# --abbrev=12 ensures a minimum of 12, and the
93*4882a593Smuzhiyun			# awk substr() then picks the 'g' and first 12
94*4882a593Smuzhiyun			# hex chars.
95*4882a593Smuzhiyun			if atag="$(git describe --abbrev=12 2>/dev/null)"; then
96*4882a593Smuzhiyun				echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),substr($(NF),0,13))}'
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun			# If we don't have a tag at all we print -g{commitish},
99*4882a593Smuzhiyun			# again using exactly 12 hex chars.
100*4882a593Smuzhiyun			else
101*4882a593Smuzhiyun				head="$(echo $head | cut -c1-12)"
102*4882a593Smuzhiyun				printf '%s%s' -g $head
103*4882a593Smuzhiyun			fi
104*4882a593Smuzhiyun		fi
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun		# Is this git on svn?
107*4882a593Smuzhiyun		if git config --get svn-remote.svn.url >/dev/null; then
108*4882a593Smuzhiyun			printf -- '-svn%s' "`git svn find-rev $head`"
109*4882a593Smuzhiyun		fi
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun		# Check for uncommitted changes.
112*4882a593Smuzhiyun		# First, with git-status, but --no-optional-locks is only
113*4882a593Smuzhiyun		# supported in git >= 2.14, so fall back to git-diff-index if
114*4882a593Smuzhiyun		# it fails. Note that git-diff-index does not refresh the
115*4882a593Smuzhiyun		# index, so it may give misleading results. See
116*4882a593Smuzhiyun		# git-update-index(1), git-diff-index(1), and git-status(1).
117*4882a593Smuzhiyun		if {
118*4882a593Smuzhiyun			git --no-optional-locks status -uno --porcelain 2>/dev/null ||
119*4882a593Smuzhiyun			git diff-index --name-only HEAD
120*4882a593Smuzhiyun		} | grep -qvE '^(.. )?scripts/package'; then
121*4882a593Smuzhiyun			printf '%s' -dirty
122*4882a593Smuzhiyun		fi
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun		# All done with git
125*4882a593Smuzhiyun		return
126*4882a593Smuzhiyun	fi
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun	# Check for mercurial and a mercurial repo.
129*4882a593Smuzhiyun	if test -d .hg && hgid=`hg id 2>/dev/null`; then
130*4882a593Smuzhiyun		# Do we have an tagged version?  If so, latesttagdistance == 1
131*4882a593Smuzhiyun		if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then
132*4882a593Smuzhiyun			id=`hg log -r . --template '{latesttag}'`
133*4882a593Smuzhiyun			printf '%s%s' -hg "$id"
134*4882a593Smuzhiyun		else
135*4882a593Smuzhiyun			tag=`printf '%s' "$hgid" | cut -d' ' -f2`
136*4882a593Smuzhiyun			if [ -z "$tag" -o "$tag" = tip ]; then
137*4882a593Smuzhiyun				id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
138*4882a593Smuzhiyun				printf '%s%s' -hg "$id"
139*4882a593Smuzhiyun			fi
140*4882a593Smuzhiyun		fi
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun		# Are there uncommitted changes?
143*4882a593Smuzhiyun		# These are represented by + after the changeset id.
144*4882a593Smuzhiyun		case "$hgid" in
145*4882a593Smuzhiyun			*+|*+\ *) printf '%s' -dirty ;;
146*4882a593Smuzhiyun		esac
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun		# All done with mercurial
149*4882a593Smuzhiyun		return
150*4882a593Smuzhiyun	fi
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun	# Check for svn and a svn repo.
153*4882a593Smuzhiyun	if rev=`LANG= LC_ALL= LC_MESSAGES=C svn info 2>/dev/null | grep '^Last Changed Rev'`; then
154*4882a593Smuzhiyun		rev=`echo $rev | awk '{print $NF}'`
155*4882a593Smuzhiyun		printf -- '-svn%s' "$rev"
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun		# All done with svn
158*4882a593Smuzhiyun		return
159*4882a593Smuzhiyun	fi
160*4882a593Smuzhiyun}
161*4882a593Smuzhiyun
162*4882a593Smuzhiyuncollect_files()
163*4882a593Smuzhiyun{
164*4882a593Smuzhiyun	local file res
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun	for file; do
167*4882a593Smuzhiyun		case "$file" in
168*4882a593Smuzhiyun		*\~*)
169*4882a593Smuzhiyun			continue
170*4882a593Smuzhiyun			;;
171*4882a593Smuzhiyun		esac
172*4882a593Smuzhiyun		if test -e "$file"; then
173*4882a593Smuzhiyun			res="$res$(cat "$file")"
174*4882a593Smuzhiyun		fi
175*4882a593Smuzhiyun	done
176*4882a593Smuzhiyun	echo "$res"
177*4882a593Smuzhiyun}
178*4882a593Smuzhiyun
179*4882a593Smuzhiyunif $scm_only; then
180*4882a593Smuzhiyun	if test ! -e .scmversion; then
181*4882a593Smuzhiyun		res=$(scm_version)
182*4882a593Smuzhiyun		echo "$res" >.scmversion
183*4882a593Smuzhiyun	fi
184*4882a593Smuzhiyun	exit
185*4882a593Smuzhiyunfi
186*4882a593Smuzhiyun
187*4882a593Smuzhiyunif test -e include/config/auto.conf; then
188*4882a593Smuzhiyun	. include/config/auto.conf
189*4882a593Smuzhiyunelse
190*4882a593Smuzhiyun	echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
191*4882a593Smuzhiyun	exit 1
192*4882a593Smuzhiyunfi
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun# localversion* files in the build and source directory
195*4882a593Smuzhiyunres="$(collect_files localversion*)"
196*4882a593Smuzhiyunif test ! "$srctree" -ef .; then
197*4882a593Smuzhiyun	res="$res$(collect_files "$srctree"/localversion*)"
198*4882a593Smuzhiyunfi
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun# CONFIG_LOCALVERSION and LOCALVERSION (if set)
201*4882a593Smuzhiyunres="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun# scm version string if not at a tagged commit
204*4882a593Smuzhiyunif test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
205*4882a593Smuzhiyun	# full scm version string
206*4882a593Smuzhiyun	res="$res$(scm_version)"
207*4882a593Smuzhiyunelse
208*4882a593Smuzhiyun	# append a plus sign if the repository is not in a clean
209*4882a593Smuzhiyun	# annotated or signed tagged state (as git describe only
210*4882a593Smuzhiyun	# looks at signed or annotated tags - git tag -a/-s) and
211*4882a593Smuzhiyun	# LOCALVERSION= is not specified
212*4882a593Smuzhiyun	if test "${LOCALVERSION+set}" != "set"; then
213*4882a593Smuzhiyun		scm=$(scm_version --short)
214*4882a593Smuzhiyun		res="$res${scm:++}"
215*4882a593Smuzhiyun	fi
216*4882a593Smuzhiyunfi
217*4882a593Smuzhiyun
218*4882a593Smuzhiyunecho "$res"
219