1 Problem finding
Compile the main line kernel
Version found , After successfully compiling the kernel version of, the generated version number becomes "x.y.z+"
, Why is there a plus sign after it ?
At the beginning, I was wondering if CONFIG_LOCALVERSION
The problem of , Configured with CONFIG_LOCALVERSION
, It's still going to be added at the end of the kernel version "+"
after , After installation , Every time uname -a
Will appear +
I really feel depressed after , Obsessive compulsive disorder I really can't stand .
2 Cause analysis
There must be problems linux
Version control in the construction process , Since it was added during the build process , Then we can start from Makefile
Some clues have been found in .
2.1 Makefile
in LOCALVERSION
Information
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION = .7
NAME = Yokohama
These are the version numbers of our kernel version , In theory, the generated version number should not carry +
Number , But why +
No.? .
There are two configuration macros in the kernel CONFIG_LOCALVERSION
and CONFIG_LOCALVERSION_AUTO
Configuration of the system kernel version number and suffix information .
2.2 Makefile
Read and set the version number in the
We retrieve information about these two macros , Check LOCALVERSION
Macro excludes arch/*/configs
and Documentation
Such as catalog .
scripts/setlocalversion:# CONFIG_LOCALVERSION and LOCALVERSION (if set)
scripts/setlocalversion:res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
scripts/setlocalversion:if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
scripts/setlocalversion: # LOCALVERSION= is not specified
scripts/setlocalversion: if test "${LOCALVERSION+set}" != "set"; then
You can see scripts/setlocalversion
The script reads the relevant information .
take it easy , Let's slowly analyze , have a look Makefile
How to read and set this information . Continue from Makefile
Middle analysis LOVALVERSION
Information about .
define filechk_kernel.release
echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"
endef
# Store (new) KERNELRELEASE string in include/config/kernel.release
include/config/kernel.release: include/config/auto.conf FORCE
$(call filechk,kernel.release)
Makefile
Use scripts/setlocalversion
Tools to generate include/config/kernel.release
. “+” The sign is added when the script is called .
Then you can generate the version file by executing the following command
make include/config/kernel.release
OR
make include/generated/utsrelease.h
Look at the information of these two files to see the version number information
in addition Makefile
There are also the following definitions :
kernelrelease:
@echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"
You can also directly use the following command to display the version number information
make kernelrelease
2.3 setlocalversion
Function to set version number information
read scripts/setlocalversion
file , And look up information , Take the following notes :
# If the current kernel uses SVN trusteeship , Only from .scmversion Read version number information in
if $scm_only; then
if test ! -e .scmversion; then
res=$(scm_version)
echo "$res" >.scmversion
fi
exit
fi
# confirm auto.conf Does the file exist
if test -e include/config/auto.conf; then
. include/config/auto.conf
else
echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
exit 1
fi
# call localversion From the source root directory localversion The information is read from the file
# localversion* files in the build and source directory
res="$(collect_files localversion*)"
if test ! "$srctree" -ef .; then
res="$res$(collect_files "$srctree"/localversion*)"
fi
# Set up LOCALVERSION Information
# CONFIG_LOCALVERSION and LOCALVERSION (if set)
res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
# call scm_version Function to read suffix information
# 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
# 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
if test "${LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
res="$res${scm:++}"
fi
fi
2.3.1 LOCALVERSION Set up
stay scripts/setlocalversion
There's also a paragraph in it :
# CONFIG_LOCALVERSION and LOCALVERSION (if set)
res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
You can see that if you configure CONFIG_LOCALVERSION
and LOCALVERSION
This suffix will be added after the version number .
and res
It is the local version number information obtained , such as 4.14-rc8
2.3.2 SCM_VERSION The addition of suffix information
Finally, it depends on whether it is configured CONFIG_LOCALVERSION_AUTO
and CONFIG_LOCALVERSION
macro , Add version suffix information
If you define
CONFIG_LOCALVERSION_AUTO=y
At this point the execution will be executed
res="$res$(scm_version)"
among res
It's our version number information , and scm_version
Function gets the version number suffix .
Otherwise, if it is not set CONFIG_LOCALVERSION_AUTO
, Then execute the following fragment .
# call scm_version Function to read suffix information
# 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
# 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
if test "${LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
res="$res${scm:++}"
fi
fi
about setlocalversion
To explain the grammar of :
So the one above shell
sentence
If
CONFIG_LOCALVERSION_AUTO = y
This program will go throughscm_version
function ( Without parameters ) Configure local version number .If
CONFIG_LOCALVERSION_AUTO
Not set , andLOVALVERSION
It's empty , be"${LOCALVERSION+set}" != "set"
, So calledscm_version --short
Will add a... At the end+
Number .
So that's it , This is how the plus sign is added . How to add the plus sign , then , scm_version
What kind of work has been done , How do these configuration macros affect the version number and suffix information , It's just research scm_version
Function .
2.3.3 Version suffix information acquisition
scm_version()
{
local short
short=false
cd "$srctree"
# If there is .scmversion The file directly obtains the suffix information of the file
if test -e .scmversion; then
cat .scmversion
return
fi
# --short Parameter settings
if test "$1" = "--short"; then
short=true
fi
# Check for git and a git repo.
# Read git Version information of the warehouse
# If --short Set to print directly + Number
# otherwise git Read version number information ,
# If git tag Sign exists git describe | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
# Otherwise print directly commit Number information
if test -z "$(git rev-parse --show-cdup 2>/dev/null)" &&
head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
# 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.
if atag="`git describe 2>/dev/null`"; then
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
# If we don't have a tag at all we print -g{commitish}.
else
printf '%s%s' -g $head
fi
fi
# Is this git on svn?
if git config --get svn-remote.svn.url >/dev/null; then
printf -- '-svn%s' "`git svn find-rev $head`"
fi
# Check for uncommitted changes
# If there are uncommitted documents, add -dirty suffix
if git diff-index --name-only HEAD | grep -qv "^scripts/package"; then
printf '%s' -dirty
fi
# All done with git
return
fi
# Check for mercurial and a mercurial repo.
if test -d .hg && hgid=`hg id 2>/dev/null`; then
# Do we have an tagged version? If so, latesttagdistance == 1
if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then
id=`hg log -r . --template '{latesttag}'`
printf '%s%s' -hg "$id"
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
fi
# Are there uncommitted changes?
# These are represented by + after the changeset id.
case "$hgid" in
*+|*+\ *) printf '%s' -dirty ;;
esac
# All done with mercurial
return
fi
# Check for svn and a svn repo.
# obtain svn Version number suffix information of the warehouse
if rev=`LANG= LC_ALL= LC_MESSAGES=C svn info 2>/dev/null | grep '^Last Changed Rev'`; then
rev=`echo $rev | awk '{print $NF}'`
printf -- '-svn%s' "$rev"
# All done with svn
return
fi
}
use bash
Judge sentence to judge
git rev-parse --verify --short
To determine whether the present is git
Version library management , Then output a short version Library HEAD revision
Short code of .
git rev-parse --verify --short HEAD 2>/dev/null
The key is the execution result of the following statement
git describe --exact-match
This sentence describes the current tag
identification . without tag
It's empty , So the whole if
The sentence is true , It's going to go on , Below echo "+"
, This will output a... In the version number +
Number .
If we're in the repository
git tag -a -m "v0.1" v0.1
then , We're executing git describe --exact-match
This sentence , It turns out that the output is ours tag
identification . that if
There is no sentence , Won't echo "+"
了 .
Keep looking at the code above , If there is uncommitted code , printf -dirty
It was carried out in the place of git diff
The inspection of , That is to say, I have revised , No uploaded files . So basically, all the reasons have been found out , After I upload the file , again make prepare
after , Generated kernel.release
Sure enough .
Conclusion , linux
The management of versions is quite strict , This also makes us in the code management must be strict with themselves , For example, before the release , First check if there are any files that have been modified to upload , Then we should git Type A in the version library tag.
If the code belongs to git
management
I hit
tag
, Then add tag Related characters-
If
tag
It's just a simple marker , such as4.14-rc8
Then skip , Because this information is already from the frontmakefile
We gotIf
tag
There are other suffixes , such asv2.6.30-rc5-302-g72357d5
, Print them out
There was no fight
tag
, Then addlog
character
For example, the latestcommit
yescommit cdebe039ded3e7fcd00c6e5603a878b14d7e564e
Then compile the file include/config/kernel.release
The content is 4.14.0-rc8-gcdebe03
According to the parameters passed before
If there is no definition
CONFIG_LOCALVERSION_AUTO
andLOCALVERSION
, scm_version The function will pass through--short
The parameter version number is followed by"+"
Number .if $short; then echo "+" return fi
2.4 summary
2.4.1 Set the version number
Script script/setlocalversion
Read the version number information in
# 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}"
It can be seen from this that , If you want to add characters to the version number , There are several ways :
Use
LOCALVERSION
Variable ( Or on the command line , Or add it as an environment variable )Add files to the root of the kernel source code
localversion
The content of the file will be automatically added to the version number . Create locally Add... To the fileDefinition
CONFIG_LOCALVERSION
VariableHow to add characters to the version number
LOCALVERSION
Variables can be defined on the command line :
make LOCALVERSION=.44 include/config/kernel.release
Or add it as an environment variable
export LOCALVERSION=.44
make include/config/kernel.release
The current kernel version is 4.14.0-rc8
, If there are files in the root directory of the source code localversion
( Its content is .33
), Also used. LOCALVERSION
Variable (make
When you specify ), It also defines CONFIG_LOCALVERSION=".XYZ"
.
make LOCALVERSION=.44 include/config/kernel.release
Right now 4.14-rc8
The kernel of , include/config/kernel.release
The content is 4.14-rc8.33.XYZ.55
.
You can see the order of the three characters added
file localversion
The content comes first , And then there was CONFIG_LOCALVERSION
Value , And finally LOCALVERSION
Value
namely
2.4.2 The acquisition of suffix information
If
CONFIG_LOCALVERSION_AUTO = y
This program will go throughscm_version
function ( Without parameters ) Configure local version number suffix information . The suffix information is usually the version number of the hosting repository , such asgit tag/commit
etc.If
CONFIG_LOCALVERSION_AUTO
Not set , andLOVALVERSION
It's empty , be"${LOCALVERSION+set}" != "set"
, So calledscm_version --short
Will add a... At the end+
Number .
in addition , About
scripts/setlocalversion
file .stay `scripts/setlocalversion In file , You can use echo “aaa” >&2 To output and display relevant information , for example :
echo “LOCALVERSION=${LOCALVERSION}” >&2It needs careful attention
Use
modinfo
You can view the compiledko
The kernel version number of the file
Useuname
perhapscat /proc/version
The kernel version number can be viewed on the target system .You can see
kernel
Files generated by the compilation processinclude/config/kernel.release
perhapsinclude/generated/utsrelease.h
, Determine the version number of the compiled kernel .
2.4.3 verification
LOCALVERSION
You can add suffix information after the version number , If we redefineCONFIG_LOCALVERSION_AUTO
, It will be added at the endgit
Version number is suffix informationDoes not define
CONFIG_LOCALVERSION_AUTO
Will not showgit
Warehouse information , If at this timeLOCALVERSION
The variable definition is undefined , Will add “+”.
here scm_version –short Added a “+” Number
cat .config | grep -E "CONFIG_LOCALVERSION"
make kernelrelease
As long as it's defined LOCALVERSION Even if it is defined as
NULL
, No additional “+”
make LOCALVERSION= kernelrelease
make LOCALVERSION="" kernelrelease
You will not add “+” Number
3 solve
LOCALVERSION
You can add suffix information after the version number , If we redefineCONFIG_LOCALVERSION_AUTO
, It will be added at the endgit
Version number is suffix information .Does not define
CONFIG_LOCALVERSION_AUTO
Will not showgit
Warehouse information , If at this timeLOCALVERSION
The variable definition is undefined , Will add “+”.If you don't want to add a suffix , I don't want to have
"+"
Number : Does not defineCONFIG_LOCALVERSION_AUTO
, takeLOCALVERSION
The variable definition is empty :LOCALVERSION=
.As long as it's defined
LOCALVERSION
, Then there will be no additional “+” The no.
4 Reference material
towards linux
Add characters to kernel version number / Why is it sometimes added automatically +
Number
towards linux Add characters to kernel version number / Why is it sometimes added automatically ”+” Number or ”xxx-dirty”
towards linux Add characters to kernel version number / Why is it sometimes added automatically “+” Number
Get rid of linux The kernel version number is automatically added “+” Number
LINUX KERNEL A plus sign is added to the version generated by compilation ”+”
Ben Bowen was written by Cheng Jian (gatieme) A literary creation , Link to the original text :
http://blog.csdn.net/gatieme