linuxカーネルバージョン番号が自動的に追加された「+」番号を削除


kernelバージョンをコンパイルしたとき、私は突然、「2.6.35.7」のカーネルバージョンのコンパイルに成功した後に生成されたバージョン番号が「2.6.35.7+」になったことに気づき、なぜ後ろにプラス記号が1つ増えたのか分からなかった.一歩一歩探して、私は問題の所在を発見して、もとは問題はlinuxのバージョンでこのブロックを制御します.
Makefileを開くとファイルの一番上に
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION = .7
NAME = Yokohama
これらはカーネルバージョンのバージョン番号を教えてくれます.生成されたバージョン番号は理論的に+番号をつけるべきではありませんが、なぜ+番号をつけるのでしょうか.下を見続けます.
コンパイルに成功した後、kernelで発見しました.releaseこのファイルはバージョン番号付きで生成されたファイルで、開いた後に発見するか+番号付きか、これはこのファイルを生成するスクリプトに問題があるに違いない.検索を続け、メインMakefileで生成kernelを発見した.releaseファイルのスクリプト
# 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)$(src tree)/scripts/setlocalversion$(src tree)>$@このスクリプトはルートディレクトリからsetlocalversionのスクリプトを呼び出してバージョン番号を生成しkernelに出力する.releaseの.setlocalversionを開くと、このファイルがbashのスクリプトであることがわかります.ファイルヘッダの説明は、このスクリプトによって追加されたローカルバージョン番号である可能性のあるローカルバージョン番号を追加するスクリプトであることを示しています.
#!/bin/sh
#
# 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
# .
#
スクリプトを読むと、スクリプトの最後にプログラムが呼び出されたことがわかります.
[plain] view plain copy
# 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  

  • ここのifはCONFIG_LOCALVERSION_AUTO定義するとsvnバージョン番号が付けられているのでnにしたのでelse部分を実行します.scm=$(scm_version--short)はscm_に--shortを渡しますがversionはshort=trueとするが.gitは存在しないのでscm_versionでは「+」は印刷されていませんが、res=「$res${scm:+}」という言葉はどういう意味ですか?scm:++は、実際にはscmが定義されていない場合、デフォルト値「+」を使用します.つまり、+はデフォルト値を使用することを意味し、2番目の「+」はデフォルト値を表します.2番目の「+」を削除すればいいのです.つまり、res=「$res${scm:+}」に変更すると、「+」の付いていないバージョン番号「2.6.37」が印刷されます.
    このコードを破壊したくない場合は、どのようにプラス記号を削除しますか?それはscmを研究するしかない.version関数です.関数には次のような関数があります.
    scm_version()
    {
    	local short
    	short=false
    
    	cd "$srctree"
    	if test -e .scmversion; then
    		cat .scmversion
    		return
    	fi
    	if test "$1" = "--short"; then
    		short=true
    	fi
    
    	# Check for git and a git repo.
    	if test -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 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
    
    		# Update index only on r/w media
    		[ -w . ] && git update-index --refresh --unmerged > /dev/null
    
    		# Check for uncommitted changes
    		if git diff-index --name-only HEAD | grep -qv "^scripts/package"; then
    			printf '%s' -dirty
    		fi
    
    		# All done with git
    		return
    	fi
            ......
    }

    彼はbash判断文でgit rev-parse--verify--shortを判断して現在gitバージョンライブラリ管理であるかどうかを判断し、短いバージョンライブラリHEAD revisionの短い符号化を出力し、存在する場合は歩き続ける.私のカーネルはgitバージョンライブラリにあるので、必ずこの場所を歩きます.
    次のコード-zは、文字列が0であるか否かを判断し、0であると真を出力する.キーはgit describe--exact-matchの実行結果です.この文はtagを記述する識別子である.tagがなければ空であればif文全体が真であり、実行され、次のecho「+」はバージョン番号に+番号を出力します.
    バージョンライブラリでgit tag-a-m"v 0.1"v 0.1後、git describe--exact-matchという文を実行し、出力されたのは私たちのtag IDであることを発見しました.if文は中に入らないので、echo「+」はできません.
    しかし問題はまた現れて、私は発見して、このようにしてよくなった後に、バージョン番号の中で“2.6.35.7-dirty”が現れて、どうしてですか?上のコードを見続け、printf-dirtyの場所でgit diffのチェックを行いました.つまり、私は修正したことがあり、アップロードされていないファイルがあります.以上の基本的な原因はすべて明らかにして、私はファイルをアップロードした後、再びmake prepareをした後、額kernelを生成します.releaseはやはり正しい.
    結論:linuxはバージョンの管理がかなり厳しいので、コード管理を行う上で自分を厳しく要求しなければなりません.例えば、バージョンを発行する前に、アップロードに変更されたファイルがあるかどうかをチェックしてから、gitバージョンライブラリにtagを打つ必要があります.