轉自:http://blog.csdn.net/adaptiver/article/details/7225980
之前每次由於git倉庫編譯出來每次都帶有'+', 導致都需要使用git archive單獨拉出一個干凈的源碼出來編譯,這樣一方面要重新編譯,耗費時間,另一方面,改動會更麻煩,可能要本地來回打patch. 於是分享下面來解決這個問題。
有個簡單的辦法:無論kernel還是uboot,都可以在本地倉庫的根目錄下touch .scmversion空文件,然后編譯即可, .config中CONFIG_LOCALVERSION_AUTO為No, CONFIG_LOCALVERSION="", 如果不配置Auto可能導致鏡像用不了
1. 引子
編譯2.6.35.7 kernel版本的時候發現,“2.6.35.7“的內核版本編譯成功后生成的版本號變成了“2.6.35.7+”,為什么后面會多一個加號呢?問題出現在linux的版本控制這一塊:
打開Makefile我們可以在文件的最上面可以發現
VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 35 EXTRAVERSION = .7 NAME = Yokohama
這些就是告訴我們內核版本的版本號,生成出來的版本號理論上不應帶+號,但為什么帶+號呢
include/config/kernel.release文件是生成的帶有版本號的文件,該文件由內核頂層Makefile的如下腳本處理:
# Store (new) KERNELRELASE string in include/config/kernel.release include/config/kernel.release: include/config/auto.conf FORCE $(Q)rm -f $@ $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@
使用scripts/setlocalversion工具來生成include/config/kernel.release。“+”號就是在調用這個腳本時添加的。
閱讀scripts/setlocalversion文件,並查閱資料,做如下筆記:
2. 為何會添加“+”號
在scripts/setlocalversion文件中有這么一段
# 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 # apped a plus sign if the repository is not in a clean tagged # state and LOCALVERSION= is not specified if test "${LOCALVERSION+set}" != "set"; then scm=$(scm_version --short) res="$res${scm:++}" fi fi
2.1. 如果定義了CONFIG_LOCALVERSION_AUTO(CONFIG_LOCALVERSION_AUTO=y)
此時會執行第一個if下的腳本。執行res="$res$(scm_version)"
如果代碼屬於git管理:
打了tag,則會添加tag相關字符;
沒有打tag,則會添加log相加字符,例如最新的commit是
commit cdebe039ded3e7fcd00c6e5603a878b14d7e564e
則編譯之后文件include/config/kernel.release的內容為2.6.35.7-gcdebe03
2.2. 如果沒有定義了CONFIG_LOCALVERSION_AUTO。
此時會執行else下的腳本。
- 如果沒有定義LOCALVERSION,版本號后面會添加“+”號:執行else里的if下的腳本scm=$(scm_version --short),在函數scm_version --short里,如果傳入參數short會添加“+”號,
if $short; then echo "+" return fi
- 定義了LOCALVERSION則不會執行else里if所在的腳本,從而不會在后面添加“+”號。
- LOCALVERSION變量可在命令行定義:
make LOCALVERSION=.88 include/config/kernel.release
或者添加為環境變量。
如果既不想添加字符,又不想有“+”號:不定義CONFIG_LOCALVERSION_AUTO,將LOCALVERSION變量定義為空:LOCALVERSION=
3. 往版本號里添加字符的方式
在scripts/setlocalversion文件中還有有這么一段:
# 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}"
由此可看出,如果想往版本號里添加字符,有幾種方式:
- 使用LOCALVERSION變量(或者在命令行,或者添加為環境變量)
- 在linux-2.6.35目錄下添加文件localversion,文件內容會自動添加到版本號里去。
- 定義CONFIG_LOCALVERSION變量
- 如果linux-2.6.35目錄下有文件localversion(其內容為.33),也使用了LOCALVERSION變量,也定義了CONFIG_LOCALVERSION=".XYZ"。
make LOCALVERSION=.44 include/config/kernel.release
此時對2.6.35.7的內核,include/config/kernel.release的內容為2.6.35.7.33.XYZ.55。
可看到添加的三種字符的順序:文件localversion內容在前,然后是CONFIG_LOCALVERSION的值,最后是LOCALVERSION的值。
4. 另外,關於scripts/setlocalversion文件:
- 在scripts/setlocalversion文件中,可用echo "aaa" >&2來輸出顯示相關信息,例如:
echo "LOCALVERSION=${LOCALVERSION}" >&2
- 這個文件里很多地方是跟根據一些git命令來進行判斷的,例如
if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then if [ -z "`git describe --exact-match 2>/dev/null`" ]; then if git config --get svn-remote.svn.url >/dev/null; then [ -w . ] && git update-index --refresh --unmerged > /dev/null if git diff-index --name-only HEAD | grep -v "^scripts/package" \
需要仔細注意:
使用modinfo可查看編譯出來的ko文件對應的內核版本號
使用uname或者 cat /proc/version 可在目標系統上查看內核版本號。
可查看kernel編譯過程生成的文件: include/generated/utsrelease.h ,確定編譯出來的內核的版本號。