關於CONFIG_LOCALVERSION_AUTO設置去掉內核版本號SVN後綴

出處 http://blog.csdn.net/gqb_driver/article/details/8444528

關於CONFIG_LOCALVERSION_AUTO設置去掉內核版本號SVN後綴

分類: 嵌入式Linux驅動開發Linux Kernel 807人閱讀 評論(0) 收藏 舉報

原創做品,轉載時請務必以超連接形式標明文章原始出處:http://blog.csdn.net/gqb666/article/details/8444528,做者:gqb666
linux

最近在TI 的DVSDK下寫驅動模塊時老受linux內核svn版本號問題的困擾,如"2.6.37-svn41"、"2.6.37-svn51"等等,svn版本變一次,從上面取下的代碼內核版本就要變一次,這樣形成原來驅動模塊ko文件必須從新拷貝到新的lib/modules/2.6.37-svn51下,很是麻煩且不利於發版本。git

所以找到一篇博文《去掉SVN管理kernel編譯後版本自動變化》,見個人轉載。shell

按其說法將arch/arm/configs/omap3_evm_defconfig裏面bash

CONFIG_LOCALVERSION_AUTO=y
app

修改成#CONFIG_LOCALVERSION_AUTO=yide

或#CONFIG_LOCALVERSION_AUTO is not set svn

清理內核源碼根目錄下的.config文件後,從新make omap3_evm_defconfig或者make linux_config,CONFIG_LOCALVERSION_AUTO相關項雖然未設置但依舊被內建。post

後來發現將其設置爲:ui

CONFIG_LOCALVERSION_AUTO=n
this

才使其默認不選上,其原理研究後再補上。

可是這樣作了以後,編譯linux內核並引導發內核版本變成了"2.6.37+",多了個「+」號

這個就須要修改scripts/setlocalversion的腳本了,先來看一段代碼


[plain] view plain copy
  1. scm_version()  

  2. {  

  3.    local short  

  4.    short=false  

  5.    cd "$srctree"  

  6.    if test -e .scmversion; then  

  7.    cat .scmversion  

  8.    return  

  9.    fi  

  10.    if test "$1" = "--short"; then  

  11.        short=true  

  12.    fi  

  13.    # Check for git and a git repo.  

  14.    if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`;then  

  15.        # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore  

  16.        # it, because this version is defined in the top level Makefile.  

  17.        if [ -z "`git describe --exact-match 2>/dev/null`" ]; then  

  18.            # If only the short version is requested, don't bother  

  19.            # running further git commands  

  20.                if $short; then  

  21.                    echo "+"  

  22.                    return  

  23.                fi  

  24.        ……  

  25.        fi  

  26.        ……  

  27.    fi  

  28. }  


這裏有個 echo "+",那「2.6.37+」裏面的「+」究竟是這條語句產生的嗎?開始看到有些博客說修改這裏, 註釋掉 "echo "+"",但並未起做用。須要認真分析一下,看第3個f語句,意思是至少有.git目錄存在的話纔會執行這後面的,但咱們用的svn,沒有.git的,因此這裏的echo "+"並未執行。再看一段代碼:



[plain] view plain copy
  1. # scm version string if not at a tagged commit  

  2. if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then  

  3.    # full scm version string  

  4.    res="$res$(scm_version)"  

  5. else  

  6.    # append a plus sign if the repository is not in a clean  

  7.    # annotated or signed tagged state (as git describe only  

  8.    # looks at signed or annotated tags - git tag -a/-s) and  

  9.    # LOCALVERSION= is not specified  

  10.    if test "${LOCALVERSION+set}" != "set"; then  

  11.        scm=$(scm_version --short)  

  12.        res="$res${scm:++}"  

  13.    fi  

  14. fi  

這裏的if就是說若是CONFIG_LOCALVERSION_AUTO定義的話,會加上svn版本號,咱們已經設爲n了,因此會執行else部分, scm=$(scm_version --short)雖然將--short傳給scm_version使得short=true,但.git不存在,因此scm_version並未打印出「+」,再來看 res="$res${scm:++}"這句話什麼意思呢?scm:++其實是說若是scm未定義的話,將使用默認值"+"也就是說:+表示使用默認值的意思,而第二個「+」表示默認值。因此將第二個「+」去掉便可。也就是改爲 res="$res${scm:+}",便可打印不帶「+」的版本號「2.6.37」。


但願給遇到一樣問題的同行以幫助!


http://smilejay.com/2012/07/kernel-version-plus-sign/


Linux kernel編譯生成的版本多一個加號「+」

七 28th, 2012
2,390 views | 發表評論 | Trackback

其實,一直以來,咱們編譯KVM(Linux kernel)生成的RPM包中的kernel版本老是帶有一個「莫名其妙」的加號(+),其實我知道大概是由於咱們修改了Linux.git(或kvm.git)中的一些文件。可是咱們只是修改了一下Makefile,讓咱們作RPM包是方便而已,通常我也沒有在編譯時修改其餘的源代碼文件,因此我想把這個加號去掉,對其進行了簡單的研究,問題已經搞定了,記錄以下吧。

kernel版本出現一個加號(plug sign)的緣由多是以下兩點,固然前提是使用Linux的GIT repository,且CONFIG_LOCALVERSION_AUTO和LOCALVERSION都沒有設置。
(1)若是當前repository的commit ID不是某一個tag,則默認有一個加號。由於在最上層的Makefile中只有該repository中最近一次tag的版本信息,須要用加號(+)來標識它並不是一個tag(如:3.5.0)。
(2)若是當前repository的commit ID恰好是一個tag,且其中有GIT管理下的文件被改動,這默認有一個加號(+)。
若是想避免這個煩人的加號,能夠將scripts/setlocalversion腳本中帶有’ echo 「+」 ‘和’ res=」$res${scm:++}」 ‘的這兩行刪掉便可。
To avoid the additional plus sign in kernel release version, just remove ‘ echo 「+」 ‘ line and ‘ res=」$res${scm:++}」 ‘ line in scripts/setlocalversion file.

首先,Linux的頂層的Makefile關於版本的信息,以及對」make kernelrelease」的定義以下:

View Code BASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
VERSION = 3
PATCHLEVEL = 5
SUBLEVEL = 0
EXTRAVERSION =
NAME = Saber-toothed Squirrel
#..............@echo'  kernelrelease   - Output the release version string'@echo'  kernelversion   - Output the version stored in Makefile'#..............
kernelrelease:
        @echo"$(KERNELVERSION)$$($(CONFIG_SHELL)$(srctree)/scripts/setlocalversion $(srctree))"
 
kernelversion:
        @echo $(KERNELVERSION)

而後,咱們執行「make kernelrelease」則會生成kernel發佈的版本信息,以下:

View Code BASH
1
2
3
4
5
[root@jay-linux linux.git]# make kernelrelease
3.5.0
[root@jay-linux linux.git]# vi mm/oom_kill.c[root@jay-linux linux.git]# make kernelrelease
3.5.0+

注意,這個加號實際上是做爲本地的版本號加進去的,詳見scripts/setlocalversion這個腳本,有以下的部分重要內容。

View Code BASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
scm_version(){local short
        short=falsecd"$srctree"iftest-e .scmversion; thencat .scmversion
                returnfiiftest"$1" = "--short"; thenshort=truefi# Check for git and a git repo.iftest-d .git &&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 commandsif$short; thenecho"+"returnfi# If we are past a tagged commit (like# "v2.6.30-rc5-302-g72357d5"), we pretty print it.ifatag="`git describe 2>/dev/null`"; thenecho"$atag"|awk-F-'{printf("-%05d-%s", $(NF-1),$(NF))}'# If we don't have a tag at all we print -g{commitish}.elseprintf'%s%s'-g$headfifiifgit diff-index --name-only HEAD |grep-qv"^scripts/package"; thenprintf'%s'-dirtyfi# All done with gitreturnfi#................}#................# CONFIG_LOCALVERSION and LOCALVERSION (if set)res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"# scm version string if not at a tagged commitiftest"$CONFIG_LOCALVERSION_AUTO" = "y"; then# full scm version stringres="$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 specifiediftest"${LOCALVERSION+set}"!= "set"; thenscm=$(scm_version --short)res="$res${scm:++}"fifiecho"$res"

以下的一些信息能夠方便你理解上面的這段腳本。

View Code BASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@jay-linux linux.git]# git rev-parse --verify --short HEAD
28a33cb
[root@jay-linux linux.git]# git describe --exact-match 2>/dev/null
v3.5
[root@jay-linux linux.git]# git diff-index --name-only HEAD
mm/oom_kill.c
[root@jay-linux linux.git]# man git #...........git-rev-parse(1)
           Pick out and massage parameters.
 git-describe(1)
           Show the most recent tag that is reachable from a commit.
 git-diff-index(1)
           Compares content and mode of blobs between the index and repository.
    #............

另外,對於setlocalversion中的一個語法解釋一下:
${var:-value1} 在變量var不爲空時,保持var原有的值不變;若是var變量未設置或者爲空,這表達式結果爲value1,可是變量var的值並不改變(未設置或爲空)。
${var:+value1} 在變量var不爲空時,表達式結果爲value1;若是var變量未設置或者爲空,這表達式結果爲空。${var+value1}的效果同樣。
${var:=value1} 在變量var不爲空時,保持var原有的值不變;若是var變量未設置或者爲空,這表達式結果爲value1,變量var也被賦值爲value1。
${var:?value1} 在變量var未設置或爲空時,腳本會退出並拋出一個錯誤信息(包含value1)。

另外,以下一篇博客也研究了這個問題,供你們參考。

http://blog.csdn.net/adaptiver/article/details/7225980

標籤: Kernel, Linux, Shell
相關文章
相關標籤/搜索