Commit 09155120cf0ffe6f0c8aba3aa625831405b65996

Authored by Michal Marek
1 parent fb994ecc2b

kbuild: Clean up and speed up the localversion logic

Now that we run scripts/setlocalversion during every build, it makes
sense to move all the localversion logic there. This cleans up the
toplevel Makefile and also makes sure that the script is called only
once in 'make prepare' (previously, it would be called every time due to
a variable expansion in an ifneq statement). No user-visible change is
intended, unless one runs the setlocalversion script directly.

Reported-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Greg Thelen <gthelen@google.com>
Cc: Nico Schottelius <nico-linuxsetlocalversion@schottelius.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>

Showing 3 changed files with 136 additions and 119 deletions Side-by-side Diff

... ... @@ -883,80 +883,12 @@
883 883 $(vmlinux-dirs): prepare scripts
884 884 $(Q)$(MAKE) $(build)=$@
885 885  
886   -# Build the kernel release string
887   -#
888   -# The KERNELRELEASE value built here is stored in the file
889   -# include/config/kernel.release, and is used when executing several
890   -# make targets, such as "make install" or "make modules_install."
891   -#
892   -# The eventual kernel release string consists of the following fields,
893   -# shown in a hierarchical format to show how smaller parts are concatenated
894   -# to form the larger and final value, with values coming from places like
895   -# the Makefile, kernel config options, make command line options and/or
896   -# SCM tag information.
897   -#
898   -# $(KERNELVERSION)
899   -# $(VERSION) eg, 2
900   -# $(PATCHLEVEL) eg, 6
901   -# $(SUBLEVEL) eg, 18
902   -# $(EXTRAVERSION) eg, -rc6
903   -# $(localver-full)
904   -# $(localver)
905   -# localversion* (files without backups, containing '~')
906   -# $(CONFIG_LOCALVERSION) (from kernel config setting)
907   -# $(LOCALVERSION) (from make command line, if provided)
908   -# $(localver-extra)
909   -# $(scm-identifier) (unique SCM tag, if one exists)
910   -# ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO)
911   -# .scmversion (only with CONFIG_LOCALVERSION_AUTO)
912   -# + (only without CONFIG_LOCALVERSION_AUTO
913   -# and without LOCALVERSION= and
914   -# repository is at non-tagged commit)
915   -#
916   -# For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has
917   -# been revised beyond a tagged commit, `+' is appended to the version string
918   -# when not overridden by using "make LOCALVERSION=". This indicates that the
919   -# kernel is not a vanilla release version and has been modified.
920   -
921   -pattern = ".*/localversion[^~]*"
922   -string = $(shell cat /dev/null \
923   - `find $(objtree) $(srctree) -maxdepth 1 -regex $(pattern) | sort -u`)
924   -
925   -localver = $(subst $(space),, $(string) \
926   - $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
927   -
928   -# scripts/setlocalversion is called to create a unique identifier if the source
929   -# is managed by a known SCM and the repository has been revised since the last
930   -# tagged (release) commit. The format of the identifier is determined by the
931   -# SCM's implementation.
932   -#
933   -# .scmversion is used when generating rpm packages so we do not loose
934   -# the version information from the SCM when we do the build of the kernel
935   -# from the copied source
936   -ifeq ($(wildcard .scmversion),)
937   - scm-identifier = $(shell $(CONFIG_SHELL) \
938   - $(srctree)/scripts/setlocalversion $(srctree))
939   -else
940   - scm-identifier = $(shell cat .scmversion 2> /dev/null)
941   -endif
942   -
943   -ifdef CONFIG_LOCALVERSION_AUTO
944   - localver-extra = $(scm-identifier)
945   -else
946   - ifneq ($(scm-identifier),)
947   - ifeq ($(LOCALVERSION),)
948   - localver-extra = +
949   - endif
950   - endif
951   -endif
952   -
953   -localver-full = $(localver)$(LOCALVERSION)$(localver-extra)
954   -
955 886 # Store (new) KERNELRELASE string in include/config/kernel.release
956   -kernelrelease = $(KERNELVERSION)$(localver-full)
  887 +localversion = $(shell $(CONFIG_SHELL) \
  888 + $(srctree)/scripts/setlocalversion $(srctree))
957 889 include/config/kernel.release: include/config/auto.conf FORCE
958 890 $(Q)rm -f $@
959   - $(Q)echo $(kernelrelease) > $@
  891 + $(Q)echo $(KERNELVERSION)$(localversion) > $@
960 892  
961 893  
962 894 # Things we need to do before we recursively start building the kernel
scripts/package/Makefile
... ... @@ -44,7 +44,7 @@
44 44 fi
45 45 $(MAKE) clean
46 46 $(PREV) ln -sf $(srctree) $(KERNELPATH)
47   - $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion
  47 + $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --scm-only > $(objtree)/.scmversion
48 48 $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
49 49 $(PREV) rm $(KERNELPATH)
50 50 rm -f $(objtree)/.scmversion
scripts/setlocalversion
... ... @@ -10,74 +10,159 @@
10 10 #
11 11  
12 12 usage() {
13   - echo "Usage: $0 [srctree]" >&2
  13 + echo "Usage: $0 [--scm-only] [srctree]" >&2
14 14 exit 1
15 15 }
16 16  
17   -cd "${1:-.}" || usage
  17 +scm_only=false
  18 +srctree=.
  19 +if test "$1" = "--scm-only"; then
  20 + scm_only=true
  21 + shift
  22 +fi
  23 +if test $# -gt 0; then
  24 + srctree=$1
  25 + shift
  26 +fi
  27 +if test $# -gt 0 -o ! -d "$srctree"; then
  28 + usage
  29 +fi
18 30  
19   -# Check for git and a git repo.
20   -if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
  31 +scm_version()
  32 +{
  33 + local short=false
21 34  
22   - # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it,
23   - # because this version is defined in the top level Makefile.
24   - if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
  35 + cd "$srctree"
  36 + if test -e .scmversion; then
  37 + cat "$_"
  38 + return
  39 + fi
  40 + if test "$1" = "--short"; then
  41 + short=true
  42 + fi
25 43  
26   - # If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"),
27   - # we pretty print it.
28   - if atag="`git describe 2>/dev/null`"; then
29   - echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
  44 + # Check for git and a git repo.
  45 + if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
30 46  
31   - # If we don't have a tag at all we print -g{commitish}.
32   - else
33   - printf '%s%s' -g $head
  47 + # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
  48 + # it, because this version is defined in the top level Makefile.
  49 + if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
  50 +
  51 + # If only the short version is requested, don't bother
  52 + # running further git commands
  53 + if $short; then
  54 + echo "+"
  55 + return
  56 + fi
  57 + # If we are past a tagged commit (like
  58 + # "v2.6.30-rc5-302-g72357d5"), we pretty print it.
  59 + if atag="`git describe 2>/dev/null`"; then
  60 + echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
  61 +
  62 + # If we don't have a tag at all we print -g{commitish}.
  63 + else
  64 + printf '%s%s' -g $head
  65 + fi
34 66 fi
35   - fi
36 67  
37   - # Is this git on svn?
38   - if git config --get svn-remote.svn.url >/dev/null; then
39   - printf -- '-svn%s' "`git svn find-rev $head`"
40   - fi
  68 + # Is this git on svn?
  69 + if git config --get svn-remote.svn.url >/dev/null; then
  70 + printf -- '-svn%s' "`git svn find-rev $head`"
  71 + fi
41 72  
42   - # Update index only on r/w media
43   - [ -w . ] && git update-index --refresh --unmerged > /dev/null
  73 + # Update index only on r/w media
  74 + [ -w . ] && git update-index --refresh --unmerged > /dev/null
44 75  
45   - # Check for uncommitted changes
46   - if git diff-index --name-only HEAD | grep -v "^scripts/package" \
47   - | read dummy; then
48   - printf '%s' -dirty
  76 + # Check for uncommitted changes
  77 + if git diff-index --name-only HEAD | grep -v "^scripts/package" \
  78 + | read dummy; then
  79 + printf '%s' -dirty
  80 + fi
  81 +
  82 + # All done with git
  83 + return
49 84 fi
50 85  
51   - # All done with git
52   - exit
53   -fi
  86 + # Check for mercurial and a mercurial repo.
  87 + if hgid=`hg id 2>/dev/null`; then
  88 + tag=`printf '%s' "$hgid" | cut -d' ' -f2`
54 89  
55   -# Check for mercurial and a mercurial repo.
56   -if hgid=`hg id 2>/dev/null`; then
57   - tag=`printf '%s' "$hgid" | cut -d' ' -f2`
  90 + # Do we have an untagged version?
  91 + if [ -z "$tag" -o "$tag" = tip ]; then
  92 + id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
  93 + printf '%s%s' -hg "$id"
  94 + fi
58 95  
59   - # Do we have an untagged version?
60   - if [ -z "$tag" -o "$tag" = tip ]; then
61   - id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
62   - printf '%s%s' -hg "$id"
  96 + # Are there uncommitted changes?
  97 + # These are represented by + after the changeset id.
  98 + case "$hgid" in
  99 + *+|*+\ *) printf '%s' -dirty ;;
  100 + esac
  101 +
  102 + # All done with mercurial
  103 + return
63 104 fi
64 105  
65   - # Are there uncommitted changes?
66   - # These are represented by + after the changeset id.
67   - case "$hgid" in
68   - *+|*+\ *) printf '%s' -dirty ;;
69   - esac
  106 + # Check for svn and a svn repo.
  107 + if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
  108 + rev=`echo $rev | awk '{print $NF}'`
  109 + printf -- '-svn%s' "$rev"
70 110  
71   - # All done with mercurial
  111 + # All done with svn
  112 + return
  113 + fi
  114 +}
  115 +
  116 +collect_files()
  117 +{
  118 + local file res
  119 +
  120 + for file; do
  121 + case "$file" in
  122 + *\~*)
  123 + continue
  124 + ;;
  125 + esac
  126 + if test -e "$file"; then
  127 + res="$res$(cat "$file")"
  128 + fi
  129 + done
  130 + echo "$res"
  131 +}
  132 +
  133 +if $scm_only; then
  134 + scm_version
72 135 exit
73 136 fi
74 137  
75   -# Check for svn and a svn repo.
76   -if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
77   - rev=`echo $rev | awk '{print $NF}'`
78   - printf -- '-svn%s' "$rev"
  138 +if test -e include/config/auto.conf; then
  139 + source "$_"
  140 +else
  141 + echo "Error: kernelrelease not valid - run 'make prepare' to update it"
  142 + exit 1
  143 +fi
79 144  
80   - # All done with svn
81   - exit
  145 +# localversion* files in the build and source directory
  146 +res="$(collect_files localversion*)"
  147 +if test ! "$srctree" -ef .; then
  148 + res="$res$(collect_files "$srctree"/localversion*)"
82 149 fi
  150 +
  151 +# CONFIG_LOCALVERSION and LOCALVERSION (if set)
  152 +res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
  153 +
  154 +# scm version string if not at a tagged commit
  155 +if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
  156 + # full scm version string
  157 + res="$res$(scm_version)"
  158 +else
  159 + # apped a plus sign if the repository is not in a clean tagged
  160 + # state and LOCALVERSION= is not specified
  161 + if test "${LOCALVERSION+set}" != "set"; then
  162 + scm=$(scm_version --short)
  163 + res="$res${scm:++}"
  164 + fi
  165 +fi
  166 +
  167 +echo "$res"