2006-01-04 20:42:03 +01:00
#!/bin/sh
2009-05-16 14:00:56 +02:00
#
# This scripts adds local version information from the version
# control systems git, mercurial (hg) and subversion (svn).
#
# If something goes wrong, send a mail the kernel build mailinglist
# (see MAINTAINERS) and CC Nico Schottelius
# <nico-linuxsetlocalversion -at- schottelius.org>.
#
#
2005-07-31 04:57:49 -04:00
2006-01-04 20:42:03 +01:00
usage() {
2010-07-15 10:36:37 +02:00
echo "Usage: $0 [--save-scmversion] [srctree]" >&2
2006-01-04 20:42:03 +01:00
exit 1
2005-07-31 04:57:49 -04:00
}
2010-06-17 15:14:58 +02:00
scm_only=false
srctree=.
2010-07-15 10:36:37 +02:00
if test "$1" = "--save-scmversion"; then
2010-06-17 15:14:58 +02:00
scm_only=true
shift
fi
if test $# -gt 0; then
srctree=$1
shift
fi
if test $# -gt 0 -o ! -d "$srctree"; then
usage
fi
2005-07-31 04:57:49 -04:00
2010-06-17 15:14:58 +02:00
scm_version()
{
2010-07-18 10:26:40 +02:00
local short
short=false
2009-05-16 14:00:56 +02:00
2010-06-17 15:14:58 +02:00
cd "$srctree"
if test -e .scmversion; then
2010-07-18 10:26:40 +02:00
cat .scmversion
2010-06-17 15:14:58 +02:00
return
fi
if test "$1" = "--short"; then
short=true
fi
2009-05-16 14:00:56 +02:00
2010-06-17 15:14:58 +02:00
# Check for git and a git repo.
2013-12-02 16:34:29 +01:00
if test -z "$(git rev-parse --show-cdup 2>/dev/null)" &&
scripts/setlocalversion: make git describe output more reliable
commit 548b8b5168c90c42e88f70fcf041b4ce0b8e7aa8 upstream.
When building for an embedded target using Yocto, we're sometimes
observing that the version string that gets built into vmlinux (and
thus what uname -a reports) differs from the path under /lib/modules/
where modules get installed in the rootfs, but only in the length of
the -gabc123def suffix. Hence modprobe always fails.
The problem is that Yocto has the concept of "sstate" (shared state),
which allows different developers/buildbots/etc. to share build
artifacts, based on a hash of all the metadata that went into building
that artifact - and that metadata includes all dependencies (e.g. the
compiler used etc.). That normally works quite well; usually a clean
build (without using any sstate cache) done by one developer ends up
being binary identical to a build done on another host. However, one
thing that can cause two developers to end up with different builds
[and thus make one's vmlinux package incompatible with the other's
kernel-dev package], which is not captured by the metadata hashing, is
this `git describe`: The output of that can be affected by
(1) git version: before 2.11 git defaulted to a minimum of 7, since
2.11 (git.git commit e6c587) the default is dynamic based on the
number of objects in the repo
(2) hence even if both run the same git version, the output can differ
based on how many remotes are being tracked (or just lots of local
development branches or plain old garbage)
(3) and of course somebody could have a core.abbrev config setting in
~/.gitconfig
So in order to avoid `uname -a` output relying on such random details
of the build environment which are rather hard to ensure are
consistent between developers and buildbots, make sure the abbreviated
sha1 always consists of exactly 12 hex characters. That is consistent
with the current rule for -stable patches, and is almost always enough
to identify the head commit unambigously - in the few cases where it
does not, the v5.4.3-00021- prefix would certainly nail it down.
[Adapt to `` vs $() differences between 5.4 and upstream.]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-09-17 08:56:11 +02:00
head=$(git rev-parse --verify HEAD 2>/dev/null); then
2010-06-17 15:14:58 +02:00
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
# it, because this version is defined in the top level Makefile.
if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
# If only the short version is requested, don't bother
# running further git commands
if $short; then
echo "+"
return
fi
# If we are past a tagged commit (like
# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
scripts/setlocalversion: make git describe output more reliable
commit 548b8b5168c90c42e88f70fcf041b4ce0b8e7aa8 upstream.
When building for an embedded target using Yocto, we're sometimes
observing that the version string that gets built into vmlinux (and
thus what uname -a reports) differs from the path under /lib/modules/
where modules get installed in the rootfs, but only in the length of
the -gabc123def suffix. Hence modprobe always fails.
The problem is that Yocto has the concept of "sstate" (shared state),
which allows different developers/buildbots/etc. to share build
artifacts, based on a hash of all the metadata that went into building
that artifact - and that metadata includes all dependencies (e.g. the
compiler used etc.). That normally works quite well; usually a clean
build (without using any sstate cache) done by one developer ends up
being binary identical to a build done on another host. However, one
thing that can cause two developers to end up with different builds
[and thus make one's vmlinux package incompatible with the other's
kernel-dev package], which is not captured by the metadata hashing, is
this `git describe`: The output of that can be affected by
(1) git version: before 2.11 git defaulted to a minimum of 7, since
2.11 (git.git commit e6c587) the default is dynamic based on the
number of objects in the repo
(2) hence even if both run the same git version, the output can differ
based on how many remotes are being tracked (or just lots of local
development branches or plain old garbage)
(3) and of course somebody could have a core.abbrev config setting in
~/.gitconfig
So in order to avoid `uname -a` output relying on such random details
of the build environment which are rather hard to ensure are
consistent between developers and buildbots, make sure the abbreviated
sha1 always consists of exactly 12 hex characters. That is consistent
with the current rule for -stable patches, and is almost always enough
to identify the head commit unambigously - in the few cases where it
does not, the v5.4.3-00021- prefix would certainly nail it down.
[Adapt to `` vs $() differences between 5.4 and upstream.]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-09-17 08:56:11 +02:00
#
# Ensure the abbreviated sha1 has exactly 12
# hex characters, to make the output
# independent of git version, local
# core.abbrev settings and/or total number of
# objects in the current repository - passing
# --abbrev=12 ensures a minimum of 12, and the
# awk substr() then picks the 'g' and first 12
# hex chars.
if atag="$(git describe --abbrev=12 2>/dev/null)"; then
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),substr($(NF),0,13))}'
2010-06-17 15:14:58 +02:00
scripts/setlocalversion: make git describe output more reliable
commit 548b8b5168c90c42e88f70fcf041b4ce0b8e7aa8 upstream.
When building for an embedded target using Yocto, we're sometimes
observing that the version string that gets built into vmlinux (and
thus what uname -a reports) differs from the path under /lib/modules/
where modules get installed in the rootfs, but only in the length of
the -gabc123def suffix. Hence modprobe always fails.
The problem is that Yocto has the concept of "sstate" (shared state),
which allows different developers/buildbots/etc. to share build
artifacts, based on a hash of all the metadata that went into building
that artifact - and that metadata includes all dependencies (e.g. the
compiler used etc.). That normally works quite well; usually a clean
build (without using any sstate cache) done by one developer ends up
being binary identical to a build done on another host. However, one
thing that can cause two developers to end up with different builds
[and thus make one's vmlinux package incompatible with the other's
kernel-dev package], which is not captured by the metadata hashing, is
this `git describe`: The output of that can be affected by
(1) git version: before 2.11 git defaulted to a minimum of 7, since
2.11 (git.git commit e6c587) the default is dynamic based on the
number of objects in the repo
(2) hence even if both run the same git version, the output can differ
based on how many remotes are being tracked (or just lots of local
development branches or plain old garbage)
(3) and of course somebody could have a core.abbrev config setting in
~/.gitconfig
So in order to avoid `uname -a` output relying on such random details
of the build environment which are rather hard to ensure are
consistent between developers and buildbots, make sure the abbreviated
sha1 always consists of exactly 12 hex characters. That is consistent
with the current rule for -stable patches, and is almost always enough
to identify the head commit unambigously - in the few cases where it
does not, the v5.4.3-00021- prefix would certainly nail it down.
[Adapt to `` vs $() differences between 5.4 and upstream.]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-09-17 08:56:11 +02:00
# If we don't have a tag at all we print -g{commitish},
# again using exactly 12 hex chars.
2010-06-17 15:14:58 +02:00
else
scripts/setlocalversion: make git describe output more reliable
commit 548b8b5168c90c42e88f70fcf041b4ce0b8e7aa8 upstream.
When building for an embedded target using Yocto, we're sometimes
observing that the version string that gets built into vmlinux (and
thus what uname -a reports) differs from the path under /lib/modules/
where modules get installed in the rootfs, but only in the length of
the -gabc123def suffix. Hence modprobe always fails.
The problem is that Yocto has the concept of "sstate" (shared state),
which allows different developers/buildbots/etc. to share build
artifacts, based on a hash of all the metadata that went into building
that artifact - and that metadata includes all dependencies (e.g. the
compiler used etc.). That normally works quite well; usually a clean
build (without using any sstate cache) done by one developer ends up
being binary identical to a build done on another host. However, one
thing that can cause two developers to end up with different builds
[and thus make one's vmlinux package incompatible with the other's
kernel-dev package], which is not captured by the metadata hashing, is
this `git describe`: The output of that can be affected by
(1) git version: before 2.11 git defaulted to a minimum of 7, since
2.11 (git.git commit e6c587) the default is dynamic based on the
number of objects in the repo
(2) hence even if both run the same git version, the output can differ
based on how many remotes are being tracked (or just lots of local
development branches or plain old garbage)
(3) and of course somebody could have a core.abbrev config setting in
~/.gitconfig
So in order to avoid `uname -a` output relying on such random details
of the build environment which are rather hard to ensure are
consistent between developers and buildbots, make sure the abbreviated
sha1 always consists of exactly 12 hex characters. That is consistent
with the current rule for -stable patches, and is almost always enough
to identify the head commit unambigously - in the few cases where it
does not, the v5.4.3-00021- prefix would certainly nail it down.
[Adapt to `` vs $() differences between 5.4 and upstream.]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-09-17 08:56:11 +02:00
head="$(echo $head | cut -c1-12)"
2010-06-17 15:14:58 +02:00
printf '%s%s' -g $head
fi
fi
2009-05-16 14:00:56 +02:00
2010-06-17 15:14:58 +02:00
# Is this git on svn?
if git config --get svn-remote.svn.url >/dev/null; then
printf -- '-svn%s' "`git svn find-rev $head`"
2009-05-16 14:00:56 +02:00
fi
2005-07-31 04:57:49 -04:00
scripts/setlocalversion: Improve -dirty check with git-status --no-optional-locks
[ Upstream commit ff64dd4857303dd5550faed9fd598ac90f0f2238 ]
git-diff-index does not refresh the index for you, so using it for a
"-dirty" check can give misleading results. Commit 6147b1cf19651
("scripts/setlocalversion: git: Make -dirty check more robust") tried to
fix this by switching to git-status, but it overlooked the fact that
git-status also writes to the .git directory of the source tree, which
is definitely not kosher for an out-of-tree (O=) build. That is getting
reverted.
Fortunately, git-status now supports avoiding writing to the index via
the --no-optional-locks flag, as of git 2.14. It still calculates an
up-to-date index, but it avoids writing it out to the .git directory.
So, let's retry the solution from commit 6147b1cf19651 using this new
flag first, and if it fails, we assume this is an older version of git
and just use the old git-diff-index method.
It's hairy to get the 'grep -vq' (inverted matching) correct by stashing
the output of git-status (you have to be careful about the difference
betwen "empty stdin" and "blank line on stdin"), so just pipe the output
directly to grep and use a regex that's good enough for both the
git-status and git-diff-index version.
Cc: Christian Kujau <lists@nerdbynature.de>
Cc: Guenter Roeck <linux@roeck-us.net>
Suggested-by: Alexander Kapshuk <alexander.kapshuk@gmail.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
Tested-by: Genki Sky <sky@genki.is>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2018-11-14 18:11:18 -08:00
# Check for uncommitted changes.
# First, with git-status, but --no-optional-locks is only
# supported in git >= 2.14, so fall back to git-diff-index if
# it fails. Note that git-diff-index does not refresh the
# index, so it may give misleading results. See
# git-update-index(1), git-diff-index(1), and git-status(1).
if {
git --no-optional-locks status -uno --porcelain 2>/dev/null ||
git diff-index --name-only HEAD
} | grep -qvE '^(.. )?scripts/package'; then
2010-06-17 15:14:58 +02:00
printf '%s' -dirty
fi
2009-06-12 09:59:52 +02:00
2010-06-17 15:14:58 +02:00
# All done with git
return
2006-01-04 20:42:03 +01:00
fi
2007-11-28 16:55:44 -05:00
2010-06-17 15:14:58 +02:00
# Check for mercurial and a mercurial repo.
2010-08-16 17:09:52 +02:00
if test -d .hg && hgid=`hg id 2>/dev/null`; then
2011-01-12 00:53:52 -05:00
# Do we have an tagged version? If so, latesttagdistance == 1
if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then
id=`hg log -r . --template '{latesttag}'`
2010-06-17 15:14:58 +02:00
printf '%s%s' -hg "$id"
2011-01-12 00:53:52 -05:00
else
tag=`printf '%s' "$hgid" | cut -d' ' -f2`
if [ -z "$tag" -o "$tag" = tip ]; then
id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
printf '%s%s' -hg "$id"
fi
2010-06-17 15:14:58 +02:00
fi
2007-11-28 16:55:44 -05:00
2010-06-17 15:14:58 +02:00
# Are there uncommitted changes?
# These are represented by + after the changeset id.
case "$hgid" in
*+|*+\ *) printf '%s' -dirty ;;
esac
2007-11-28 16:55:44 -05:00
2010-06-17 15:14:58 +02:00
# All done with mercurial
return
2007-11-28 16:55:44 -05:00
fi
2010-06-17 15:14:58 +02:00
# Check for svn and a svn repo.
2013-02-22 09:59:18 +01:00
if rev=`LANG= LC_ALL= LC_MESSAGES=C svn info 2>/dev/null | grep '^Last Changed Rev'`; then
2010-06-17 15:14:58 +02:00
rev=`echo $rev | awk '{print $NF}'`
printf -- '-svn%s' "$rev"
2007-11-28 16:55:44 -05:00
2010-06-17 15:14:58 +02:00
# All done with svn
return
fi
}
collect_files()
{
local file res
for file; do
case "$file" in
*\~*)
continue
;;
esac
if test -e "$file"; then
res="$res$(cat "$file")"
fi
done
echo "$res"
}
if $scm_only; then
2010-07-15 10:36:37 +02:00
if test ! -e .scmversion; then
res=$(scm_version)
echo "$res" >.scmversion
fi
2007-11-28 16:55:44 -05:00
exit
2006-01-04 20:42:03 +01:00
fi
2008-02-03 14:13:26 +08:00
2010-06-17 15:14:58 +02:00
if test -e include/config/auto.conf; then
2010-07-18 10:26:40 +02:00
. include/config/auto.conf
2010-06-17 15:14:58 +02:00
else
2016-06-06 21:00:38 +02:00
echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
2010-06-17 15:14:58 +02:00
exit 1
fi
2008-02-03 14:13:26 +08:00
2010-06-17 15:14:58 +02:00
# localversion* files in the build and source directory
res="$(collect_files localversion*)"
if test ! "$srctree" -ef .; then
res="$res$(collect_files "$srctree"/localversion*)"
fi
# CONFIG_LOCALVERSION and LOCALVERSION (if set)
res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
# scm version string if not at a tagged commit
if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
# full scm version string
res="$res$(scm_version)"
else
2010-09-06 11:57:19 +02:00
# append a plus sign if the repository is not in a clean
# annotated or signed tagged state (as git describe only
# looks at signed or annotated tags - git tag -a/-s) and
# LOCALVERSION= is not specified
2010-06-17 15:14:58 +02:00
if test "${LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
res="$res${scm:++}"
fi
2008-02-03 14:13:26 +08:00
fi
2010-06-17 15:14:58 +02:00
echo "$res"