版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
PAGE1《計(jì)算機(jī)軟件基礎(chǔ)》多媒體教程第九講第二章 UNIX的軟件工具2.6make2.6.1make的工作原理 make是UNIX/LINUX的軟件開發(fā)維護(hù)程序。軟件編程過程 軟件編程是一個(gè)不斷循環(huán)的過程: 思考...修改...生成...調(diào)試運(yùn)行修改:編輯源文件,例如 $vimain.c生成:編譯生成目標(biāo)文件和可執(zhí)行文件,例如 $catleft_topleft_btm>left.c $cc-cmain.c $cc-otrymain.oleft.oright.o調(diào)試運(yùn)行:例如 $./try這里給出一個(gè)示例??紤]設(shè)計(jì)5個(gè)源文件:main.c,left_top,left_btm,right_top和right_btm,并由此生成一個(gè)可執(zhí)行文件try,源文件內(nèi)容分別為:源文件main.c:#include<stdio.h>main(){ right(); left();}源文件left_top:#include<stdio.h>left(){源文件right_top:#include<stdio.h>right(){源文件left_btm: printf(“l(fā)eft\n”);}源文件right_btm: printf(“right\n”);}要生成可執(zhí)行程序try,必須運(yùn)行如下的全部命令:$catleft_topleft_btm>left.c 合并left_top和left_btm,生成left.c$catright_topright_btm>right.c 合并right_top和right_btm,生成right.c$cc-cleft.c 編譯left.c,生成left.o$cc-cright.c 編譯right.c,生成right.o$cc-cmain.c 編譯main.c,生成main.o$cc-otryleft.oright.omain.o 鏈接.o文件生成可執(zhí)行文件try下面給出的生成try的流程圖描述了自上而下的生成關(guān)系和自下而上的依賴關(guān)系。生成過程和依賴關(guān)系 例如,left_top和left_btm與left.c具有生成和依賴的相互關(guān)系,由left_top和left_btm的合并將生成left.c,稱left.c依賴于left_top和left_btm。也就是說,有了left_top和left_btm,才能生成left.c,而如果left_top和left_btm發(fā)生變動(dòng),必須重新生成left.c。 同理,left.c與left.o具有生成和依賴的相互關(guān)系,簡(jiǎn)稱依賴關(guān)系。right.c和right.o也同樣具有依賴關(guān)系,等等。依賴關(guān)系的描述 以描述left.c與left.o的依賴關(guān)系為例,可表達(dá)為: if(left.c<NT>left.o) <NT>表示newer-than cc-cleft.c 生成left.c所執(zhí)行的命令 其中,left.c<NT>left.o的含義包括: left.c的生成時(shí)間比left.o的生成時(shí)間新,或者 left.c存在而left.o不存在 如果省略流程圖中的操作命令,可以僅用箭頭表示文件的生成關(guān)系,顯然也同樣表達(dá)了依賴關(guān)系。遞推原則 依賴關(guān)系符合遞推原則。例如,由于left.o依賴于left.c,而left.c依賴于left_top和left_btm,因此left.o也依賴于left_top和left_btm,依此類推。從而可以完整描述有關(guān)try的依賴關(guān)系。2.6.2make應(yīng)用基礎(chǔ)make在執(zhí)行時(shí),根據(jù)Makefile文件中對(duì)所有文件編譯順序的描述,通過比較對(duì)應(yīng)文件的最后修改時(shí)間,決定需要更新哪些文件;同時(shí)根據(jù)該文件中對(duì)所有文件編譯規(guī)則的描述,對(duì)需要更新的文件進(jìn)行重建。Makefile的規(guī)則 TARGET: DEPENDENT <TAB> COMMAND 或者 TARGET:DEPENDENT;COMMAND規(guī)則描述了在何種情況下使用什么命令來重建一個(gè)特定的文件,此文件被稱為規(guī)則的“目標(biāo)”(TARGET,通常規(guī)則中的目標(biāo)只有一個(gè))。規(guī)則中除“目標(biāo)”外所列出的文件DEPENDENT表示TARGET所依賴的文件,稱為依賴文件。而規(guī)則的命令COMMAND則表示生成TARGET所需要執(zhí)行的命令。(1)目標(biāo)(TARGET)和依賴(DEPENDENT):目標(biāo)是該規(guī)則需要生成的文件,如例一中的left.o:例一: left.c: left_topleft_btm <TAB> catleft_topleft_btm>left.c若不需要建立目標(biāo)文件,只需要執(zhí)行一些特定的命令,“目標(biāo)”也可以是“偽目標(biāo)”(phonytargets),即Makefile中那些沒有任何依賴只有執(zhí)行動(dòng)作的目標(biāo),如例二中的clean:例二: clean: <TAB> rmmain.oright.oleft.o終極目標(biāo)“終極目標(biāo)”是執(zhí)行make的唯一目的,指的是makefile文件中第一個(gè)規(guī)則的目標(biāo)。除了“終極目標(biāo)”所在的規(guī)則以外,其它規(guī)則的順序在Makefile文件中沒有意義。(2)命令(COMMAND):COMMAND可以和TARGET: DEPENDENT放在同一行,使用分號(hào)(;)分隔開。COMMAND也可以在TARGET: DEPENDENT的下一行,作為獨(dú)立的命令行,這時(shí)開頭必須使用制表符<TAB>,不能使用空格。(在Makefile中,在第一個(gè)規(guī)則之后出現(xiàn)的所有以<TAB>字符開始的行都會(huì)被當(dāng)作命令來處理)(3)Makefile規(guī)則的中心思想目標(biāo)文件的內(nèi)容是由依賴文件文件決定,依賴文件的任何一處改動(dòng),將導(dǎo)致目前已經(jīng)存在的目標(biāo)文件的內(nèi)容過期目標(biāo)在什么情況下已經(jīng)過期,需要重建目標(biāo)文件不存在目標(biāo)文件存在,但是依賴文件中存在一個(gè)文件的最后修改時(shí)間比目標(biāo)的最后修改時(shí)間晚如果需要重建目標(biāo)時(shí),如何去重建這個(gè)目標(biāo)make的執(zhí)行(三種基本形式) 在make中,需要建立一個(gè)描述文件,用于表述所有的依賴關(guān)系。描述文件通常取名為Makefile或者makefile,在Linux中還可以取名為GNUmakefile。在shell狀態(tài)下常用的make的執(zhí)行方式有以下三種:(1)使用不帶任何參數(shù)的make命令編譯所有過時(shí)的文件。這時(shí)make將按照GNUmakefile,makefile,Makefile的順序?qū)ふ襪ake的描述文件。$make(2)使用-f選項(xiàng)指定make_file作為make的描述文件$make-fmake_file例如:$make–fmy_make make將在描述文件my_make中尋找第一個(gè)出現(xiàn)的TARGET作為“終極目標(biāo)”,并且按照my_make文件中所描述的依賴關(guān)系執(zhí)行相關(guān)的命令。(3)通過命令行將一個(gè)Makefile中的目標(biāo)作為參數(shù)來執(zhí)行“make”,指定其為此次make過程的終極目標(biāo),替代默認(rèn)的終極目標(biāo)。$makeTARGET TARGET可以是一般的目標(biāo)文件,也可以是偽目標(biāo)。如例一可如下執(zhí)行:$makeleft.c 指定TARGET為left.ccatleft_topleft_btm>left.c 生成left.c 例二的執(zhí)行可以采用如下的形式:$makecleanrmmain.oright.oleft.o 這時(shí)將直接執(zhí)行命令rmmain.oright.oleft.o。make工作原理示例 根據(jù)文件的依賴關(guān)系,可以建立一個(gè)Makefile來描述try的所有依賴關(guān)系,內(nèi)容為: 例三: try: left.oright.omain.o <TAB> cc-otryleft.oright.omain.o main.o: main.c <TAB> cc-cmain.c left.o: left.c <TAB> cc-cleft.c right.o: right.c <TAB> cc-cright.c left.c: left_topleft_btm;catleft_topleft_btm>left.c right.c: right_topright_btm <TAB> catright_topright_btm>right.c clean: <TAB> rmmain.oleft.oright.oleft.cright.c(1)如果建立描述文件Makefile后第一次執(zhí)行,即:$make “make”將依次顯示運(yùn)行的命令如下: catleft_topleft_btm>left.c cc-cleft.c cc-cmain.c catright_topright_btm>right.c cc-cright.c cc-otryleft.omain.oright.o “make”將首先解析“終極目標(biāo)”(try)所在的規(guī)則(例三中的第一個(gè)規(guī)則),根據(jù)其依賴文件(left.oright.omain.o)依次(按照依賴文件列表從左到右的順序)尋找創(chuàng)建這些依賴文件的規(guī)則。首先為第一個(gè)依賴文件(left.o)尋找創(chuàng)建規(guī)則,如果第一個(gè)依賴文件依賴于其它文件(left.c),則同樣為這個(gè)依賴文件(left.c)尋找創(chuàng)建規(guī)則(left.c:left_topleft_btm;catleft_topleft_btm>left.c)。之后make從最后一個(gè)規(guī)則(例三中目標(biāo)為left.c的規(guī)則)回退開始執(zhí)行,最終完成終極目標(biāo)的第一個(gè)依賴文件left.o的創(chuàng)建和更新。之后對(duì)第二個(gè)、第三個(gè)、第四個(gè)……“終極目標(biāo)”的依賴文件執(zhí)行同樣的過程(例三的的順序是“right.o”、“main.o”)。創(chuàng)建或者更新每一個(gè)規(guī)則依賴文件的過程都是這樣的一個(gè)過程,即按照依賴文件列表順序,使用同樣方式(按照同樣的過程)去重建每一個(gè)依賴文件,在完成對(duì)所有依賴文件的重建之后,最后一步才是重建此規(guī)則的目標(biāo)。從上文給出的顯示結(jié)果可以清晰地看出“make”的這一執(zhí)行過程。 此后如果不修改任何文件而直接執(zhí)行make,將顯示:$makemake:‘try’isuptodate 偽目標(biāo)“clean”沒有出現(xiàn)在其它任何規(guī)則的依賴列表中,它不是一個(gè)文件。在shell環(huán)境下運(yùn)行makeclean:$makecleanrmmain.oleft.oright.oleft.cright.c(2)如果修改了某個(gè)源文件,例如right_top,然后再執(zhí)行make命令,make就會(huì)循著依賴關(guān)系,發(fā)現(xiàn)right_top是right.c的依賴文件,根據(jù)遞推原則,需要執(zhí)行三條命令。執(zhí)行make將依次顯示運(yùn)行的命令:$makecatright_topright_btm>right.c 生成right.ccc-cright.c 生成right.occ-otryleft.oright.omain.o 生成try(3)如果希望更新某個(gè)依賴文件的時(shí)間,可使用touch命令,如$touchright_top$make 則right_top成為最新的文件,將再次執(zhí)行以上三條命令。2.6.3make應(yīng)用進(jìn)階Makefile規(guī)則的其他書寫技巧(1)如果在COMMAND的前面沒有@,表示在執(zhí)行命令時(shí),首先將顯示命令,然后執(zhí)行。如果加@,表示不顯示命令直接執(zhí)行。例如: 在命令前不加@: greet:; echohello! 執(zhí)行make的效果為: $makegreet echohello! hello! 在命令前加@: greet:; @echohello! 執(zhí)行make的效果為: $makegreet hello!(2)在描述文件中,可以加注釋,并且用#作為前導(dǎo)。例如: #greeting greet:; echo“hello!”或者 greet: #greeting <TAB> echo“hello!”(3)可以將一個(gè)較長(zhǎng)行使用反斜線(\)來分解為多行,反斜線之后不能有空格,如 clean:; rmmain.oleft.oright.oleft.cright.c可以改寫為: clean:; rmmain.oleft.o\ <TAB> right.oleft.cright.c目錄搜尋 功能:在指定的若干個(gè)目錄下自動(dòng)搜索目標(biāo)文件和依賴文件。這樣當(dāng)項(xiàng)目的目錄結(jié)構(gòu)發(fā)生變化后,就可以做到不更改Makefile的規(guī)則,只更改搜索目錄。(1)一般性搜索:變量VPATH(大小寫敏感)“VPATH”變量指定的是Makefile中所有文件的搜索路徑,包括依賴文件和目標(biāo)文件。定義變量“VPATH”時(shí),使用空格或者冒號(hào)(:)將多個(gè)需要搜索的目錄分開。make按照變量“VPATH”定義中的目錄順序進(jìn)行搜索(當(dāng)前目錄永遠(yuǎn)是第一搜索目錄)。 例如: VPATH=src:../headers 這樣就為所有規(guī)則的依賴指定了除當(dāng)前目錄外的另外兩個(gè)搜索目錄,“src”和“../headers”(2)選擇性搜索:關(guān)鍵字vpath(大小寫敏感) 關(guān)鍵字vpath可以為不同類型的文件(由文件名區(qū)分)指定不同的搜索目錄,vpath有三種使用方法:vpathPATTERNDIRECTORIES:為所有符合模式“PATTERN”的文件指定搜索目錄“DIRECTORIES”。“PATTERN”通常包含模式字符“%”?!?”表示匹配一個(gè)或者多個(gè)字符,例如, vpath%.h../headers表示對(duì)于Makefile中出現(xiàn)的所有的.h文件,如果不能在當(dāng)前目錄下找到,則到目錄“../headers”下尋找。vpathPATTERN:清除之前為符合模式“PATTERN”的文件設(shè)置的搜索路徑。vpath:清除所有已被設(shè)置的文件搜索路徑。Makefile中的變量(1)一般變量,又叫宏。與C語言中的宏相似,變量的值代表一個(gè)文本字符串。在Makefile的目標(biāo)、依賴、命令中引用變量的地方,變量會(huì)被它的值所取代。宏的定義方式 宏名=值 等號(hào)的兩側(cè)可以有空格,也可以沒有空格。注意宏的名字是大小寫敏感的,“foo”、“Foo”是不同的宏。推薦的做法是在對(duì)于內(nèi)部定義的一般變量(例如:目標(biāo)文件列表objects)使用小寫方式,而對(duì)于一些參數(shù)列表(例如:編譯選項(xiàng)CFLAGS)采用大寫方式。宏的引用方式 $(宏名) 或者 ${宏名} 只有當(dāng)宏名是單字符x的時(shí)候,才可以采用$x表示。例如在Makefile中定義: foo=xyz prog:; @echo$foo;echo$(foo) 運(yùn)行$makeprog,將顯示, oo xyz 這里$foo實(shí)際上表示$(f)oo,引用了宏f,但這是沒有定義過的宏,所以make找不到,無法顯示。宏的應(yīng)用示例 如在Makefile中,有兩行為: try: left.oright.omain.o <TAB> cc-otryleft.oright.omain.o 使用宏定義,可以改寫為: task=try obj=left.oright.omain.o $(task): $(obj) <TAB> cc-o$(task)${obj} 類似C語言中我們要求盡量使用宏定義來表示常數(shù),在make中我們也要求盡量使用宏定義來表示文件,使得描述文件的表述簡(jiǎn)明、清晰和易于理解,同時(shí)也易于修改和擴(kuò)充軟件的框架結(jié)構(gòu)。(2)特殊變量,又叫自動(dòng)化變量。常用的有$@、$<、$^、$*等。$@:表示規(guī)則的目標(biāo)文件名。$^:表示規(guī)則中使用空格分隔的所有依賴文件列表。例如: try: left.oright.omain.o <TAB> cc-otryleft.oright.omain.o 可以改寫為: try: left.oright.omain.o <TAB> cc-o$@$^ 應(yīng)用宏,還可以改寫為: task=try obj=left.oright.omain.o $(task): $(obj) <TAB> cc-o$@$^$<:表示規(guī)則的第一個(gè)依賴文件名。例如: right.o: right.cabc.h <TAB> cc-cright.c 可以改寫為: right.o: right.cabc.h <TAB> cc-c$<$*:表示依賴源文件和目標(biāo)文件的共同前綴。例如: main.o:main.c;cc-cmain.c可以改寫為: main.o:main.c;cc-c$*.c傳遞規(guī)則 在大多數(shù)依賴關(guān)系中,根據(jù)依賴文件生成目標(biāo)文件是有規(guī)律的。例如,C語言目標(biāo)文件(.o文件)總是由源文件(.c文件)生成的。因此在make中可以將其定義為缺省的傳遞規(guī)則。在GNUmake中支持兩種傳遞規(guī)則定義方式:模式規(guī)則和后綴規(guī)則。模式規(guī)則 以上文中的Makefile為例,.c文件生成.o文件的依賴關(guān)系描述為: main.o: main.c <TAB> cc-cmain.c left.o: left.c <TAB> cc-cleft.c right.o: right.c <TAB> cc-cright.c 如果采用模式規(guī)則,可以改寫為: %.o:%.c; cc-c$< 這里利用了模式字符“%”,可以匹配任何非空字符串。這個(gè)模式規(guī)則指定了如何由文件“N.c”來創(chuàng)建文件“N.o”?!癗”在這里可以是main、left或者right。“cc-c$<”實(shí)際上是left.o、right.o或者main.o的編譯命令“cc-cmain.c”、“cc-cleft.c”和“cc-cright.c”的統(tǒng)一表述。后綴規(guī)則 由.c文件生成.o文件的規(guī)則也可以采用后綴規(guī)則描述為: .c.o: <TAB> cc-c$< 這一規(guī)則中,.c和.o分別是依賴文件和目標(biāo)文件的后綴,它的含義是所有“.o”文件的依賴文件是對(duì)應(yīng)的“.c”文件,并通過執(zhí)行對(duì)應(yīng)的命令生成。如果make發(fā)現(xiàn)某個(gè).o文件需要重新編譯,例如main.c的修改時(shí)間比main.o新,則將根據(jù)這一后綴規(guī)則,用main.c替換$<,從而執(zhí)行命令“cc-cmain.c”生成main.o。 如果希望將編譯產(chǎn)生的出錯(cuò)信息保留到后綴為.err的文件中,可以進(jìn)一步改寫以上的依賴關(guān)系: .c.o:;cc-c$<>$*.errmake中的控制結(jié)構(gòu) make提供了類似shell的控制結(jié)構(gòu),如if,for,while等。以for結(jié)構(gòu)為例,例如一個(gè)Bshell程序文件的內(nèi)容為: fordirind1d2d3 d1,d2和d3是三個(gè)目錄 do cd$dir 進(jìn)入某個(gè)目錄 make-f${dir}_make 執(zhí)行某個(gè)描述文件,如d1_make cd.. 返回父目錄 done 則可以在make的描述文件中,使用類似的for結(jié)構(gòu): SUBDIR=d1d2d3 build: <TAB> @fordirin$(SUBDIR);do\ 用反斜杠表示續(xù)行 cd$${dir};make-f$${dir}_make;\ 用$$引用變量 cd..;\ 不顯示cd命令 done 其中,在引用for結(jié)構(gòu)中的索引變量時(shí),也需要在$符號(hào)之前再加一個(gè)$。例如必須用$${dir}來引用dir,而不能簡(jiǎn)單地使用${dir}。 在make中,for結(jié)構(gòu)為一個(gè)語句組單位,需要用分號(hào)代替shell的回車符。make的內(nèi)嵌函數(shù)GNUmake的函數(shù)提供了處理文件名、變量、文本和命令的方法。函數(shù)的在調(diào)用它的地方被替換為它的處理結(jié)果。內(nèi)嵌函數(shù)的調(diào)用方式 $(FUNCTIONARGUMENTS)或者${FUNCTIONARGUMENTS} “FUNCTION”是make內(nèi)嵌的函數(shù)名,“ARGUMENTS”是函數(shù)的參數(shù),參數(shù)和函數(shù)名之間使用空格或者<TAB>字符分隔。以字符串替換函數(shù)subst為例,其調(diào)用方式是 $(substFROM,TO,TEXT) 該函數(shù)的功能是把字串“TEXT”中的“FROM”字符替換為“TO”,返回替換后的新字符串。例如若在Makefile中寫入: ori=feetonthestreet bar=$(substee,EE,$(ori)) prog:; @echo$(bar) shell下面運(yùn)行makeprog,將顯示: fEEtonthestrEEtshell函數(shù)的調(diào)用方式 作為make的內(nèi)嵌函數(shù)之一,shell函數(shù)需要一個(gè)shell命令作為此函數(shù)的參數(shù),函數(shù)的返回結(jié)果是此命令在shell中的執(zhí)行結(jié)果。例如若Makefile中包含以下語句: right=$(shellechoright*) right.c:$(right);cat$^>$@ 或者 right=$(shelllsright*) right.c:$(right);cat$^>$@ 運(yùn)行makeright.c后將顯示: catright_btmright_top>right.c2.6.4make應(yīng)用示例 應(yīng)用以上make的各種功能,可以改寫try的描述文件Makefile,內(nèi)容為: #Function:descriptionfiletomake“try” #Usage:$make TASK = try R_TXT= right_topright_btm L_TXT=left_topleft_btm LS= left.c RS= right.c OBJ= try.oleft.oright.o $(TASK): $(OBJ);cc-o$@$(OBJ) .c.o:; cc-c$< $(LS): $(L_TXT) <TAB> cat$(L_TXT)>$(LS) $(RS): $(R_TXT) <TAB> cat$(R_TXT)>$(RS)2.6.5make的其他應(yīng)用——檢測(cè)新任務(wù)的描述文件jobMake 設(shè)文件$HOME/todayJob記錄了當(dāng)天未完成的和新增的工作任務(wù),文件jobList記錄了未完成和已完成的任務(wù)。用make進(jìn)行檢測(cè)是否有新增的任務(wù),功能為:將todayJob加到j(luò)obList中,如果jobList發(fā)生變動(dòng),需要提醒。描述文件jobMake的內(nèi)容為: #Function:checkmyjoblist JOB=jobList TODAY=$$HOME/todayJob $(JOB): $(TODAY) jobList依賴todayJob <TAB> @cp$@$@.bak 產(chǎn)生備份文件 <TAB> @cat$@.bak$(TODAY)|sort-u>$@ 合并文件 <TAB> @if[-n“`diff$@$@.bak`”];\ 測(cè)試是否變動(dòng) <TAB> thenecho“youhavenewjobin$@”; 給出提示 <TAB> elseecho“notfoundnewjob”;fi 無新增任務(wù) 執(zhí)行make: $make-fjobMake【程序解析】首先,由jobList復(fù)制一個(gè)備份文件jobList.bak。然后執(zhí)行命令“cat$@.bak$(TODAY)|sort-u>$@”,表示合并備份文件和todayJob,并且通過命令“sort-u”刪去重復(fù)行(由可選項(xiàng)-u表示)。如果jobList和jobList.bak不相同,則用diff命令比較兩個(gè)文件的結(jié)果應(yīng)該是非空的字符串,從而給出提示。2.7版本管理工具SVN2.7.1版本管理版本管理工具主要用于管理同一項(xiàng)目的不同版本。通常,我們也可以將源文件復(fù)制若干份,自行進(jìn)行管理。但與版本管理工具相比,不僅管理不方便,而且會(huì)占用很多硬盤空間。版本管理工具希望實(shí)現(xiàn):文件共享:小組成員都能夠訪問源碼同時(shí)編輯:支持多人同時(shí)修改同一份文件版本恢復(fù):能夠恢復(fù)以前的不同版本的源碼常見的版本管理工具及其特點(diǎn):元老級(jí): SCCS(SourceCodeControlSystem)是一種基本的源文件版本控制工具,基于單一文件的版本控制。工作時(shí)需要一個(gè)專門的SCCS格式的文件保留其源文件的編碼版本。類似的還有RCS。中堅(jiān)級(jí): Clearcase是IBM一款重量級(jí)的軟件配置管理工具,涵蓋的范圍從最初的軟件配置計(jì)劃,到配置項(xiàng)的確立,從變更控制到版本控制,貫穿于整個(gè)軟件生命周期,是主流的商業(yè)工具。開源奇葩: CVS是開放源代碼軟件世界的一個(gè)偉大杰作,簡(jiǎn)單易用、功能強(qiáng)大,跨平臺(tái),支持并發(fā)版本控制,而且免費(fèi),在全球中小型軟件企業(yè)中得到了廣泛使用。CVS的繼任者: SVN(SubVersion)由CVS的主要作者開發(fā),其設(shè)計(jì)目的就是針對(duì)CVS的一些弱點(diǎn)進(jìn)行改進(jìn),用以替代CVS。2.7.2SVN的機(jī)制客戶/服務(wù)器系統(tǒng)SVN是一個(gè)典型的“集中式”信息共享系統(tǒng),即客戶/服務(wù)器系統(tǒng)。版本庫(kù)是SVN的核心部分,是存儲(chǔ)數(shù)據(jù)的中央倉(cāng)庫(kù)??截?修改-合并(Copy-Modify-Merge)方案(1)文件共享需要避免的問題:不同用戶之間的相互干擾,如下面“楊”修改版本File1的丟失(2)拷貝-修改-合并方案:解決合并時(shí)沖突的關(guān)鍵在于用戶之間的交流。SVN的特點(diǎn)目錄版本化: CVS只能管理單個(gè)文件的更改,而SVN可以跟蹤到目錄樹的變更保存文件的差異信息: SVN用了二進(jìn)制差異算法描述文件的變化,所以對(duì)于文本文件和二進(jìn)制文件,操作方法是一樣整體提交(原子提交)和整體版本號(hào): 將一系列文件的修改組成一個(gè)邏輯整體,以后可以一次性還原基于硬連接的分支操作: SVN使用一種類似硬鏈接(Unix名詞)的機(jī)制拷貝整個(gè)工程來對(duì)分支和標(biāo)簽進(jìn)行操作,消耗的時(shí)間跟修改部分成正比,而不是整個(gè)文件的大小,因此這些操作的時(shí)間和空間開銷都很小。2.7.3SVN的基本術(shù)語SVN的使用需要了解如下基本術(shù)語:中央版本庫(kù)、工作拷貝、全局版本號(hào)等。中央版本庫(kù)(Repository)中央版本庫(kù)是一種特殊的文件服務(wù)器,用于保存項(xiàng)目版本化數(shù)據(jù),記錄每一次改變,包括每一個(gè)文件的改變和目錄樹本身的改變。通常采用標(biāo)準(zhǔn)URL格式訪問版本庫(kù),例如, 如果要訪問本地版本庫(kù),需采用file:的訪問方法,如下:file:///path/to/repos工作拷貝(WorkingCopy)為了得到一個(gè)工作拷貝,你必須檢出版本庫(kù)的一個(gè)子樹。一個(gè)SVN工作拷貝是你本地機(jī)器一個(gè)普通的目錄,主要包括兩個(gè)部分:私有工作區(qū):可以任意的刪改文件。在明確的特定操作(如“svnupdate”等)之前,私有工作區(qū)不會(huì)影響版本庫(kù),也不會(huì)受到版本庫(kù)的影響。管理區(qū)域:工作拷貝的每一個(gè)文件夾都包含一個(gè)以.svn為名的文件夾,也做工作拷貝管理目錄,記錄兩項(xiàng)關(guān)鍵的信息:工作文件所作為基準(zhǔn)的修訂版本(叫做文件的工作修訂版本)一個(gè)本地拷貝最后更新的時(shí)間戳。從而SVN可以由此確定工作文件的狀態(tài)。全局版本號(hào)SVN的修訂號(hào)是針對(duì)整個(gè)目錄樹的,而不是單個(gè)文件。每一個(gè)修訂號(hào)代表了一次提交后版本庫(kù)整個(gè)目錄樹的特定狀態(tài)。版本庫(kù)的修訂號(hào)為N代表版本庫(kù)已經(jīng)經(jīng)過了N次提交。例如若當(dāng)前楊從版本庫(kù)檢出一個(gè)工作拷貝,版本號(hào)為4: calc/Makefile:4 integer.c:4 button.c:4即該項(xiàng)目中包含三個(gè)文件,當(dāng)前版本號(hào)都為4。這時(shí)楊修改了button.c并提交之后,假設(shè)沒有別的提交出現(xiàn),楊的提交會(huì)在版本庫(kù)建立修訂版本5,楊的工作拷貝會(huì)是這個(gè)樣子的: calc/Makefile:4 integer.c:4 button.c:5之后,江提交了對(duì)integer.c的修改,建立了修訂版本6。如果楊采用svnupdate更新他自己的工作拷貝,就會(huì)看到: calc/Makefile:6 integer.c:6 button.c:6這里Makefile在4、5、6修訂版本都是一樣的,button.c在5、6兩個(gè)修訂版本中都是一樣的。SVN會(huì)把楊的Makefile和button.c的修訂號(hào)都設(shè)為6來表明它是最新的。2.7.4SVN的基本操作SVN幫助在任何時(shí)候都可以運(yùn)行:$svnhelpSUBCOMMAND來查看SVN各種命令的用法,其中SUBCOMMAND是SVN的命令名。初始化(1)版本庫(kù)的建立(svnadmincreate)svnadmin是版本庫(kù)管理員的工具箱。SVN的版本庫(kù)建立就可以采用svnadmin工具中的子命令create,即運(yùn)行:$svnadmincreate/home/jiang/svn/maketest這樣就在目錄/home/jiang/svn/下建立了一個(gè)默認(rèn)數(shù)據(jù)存儲(chǔ)格式的新的版本庫(kù)。對(duì)于單一項(xiàng)目,SVN建議建立三個(gè)子目錄: trunk/ 保存項(xiàng)目的開發(fā)主線 branches/ 保存項(xiàng)目的各種開發(fā)分支 tags/ 保存項(xiàng)目的標(biāo)簽,即創(chuàng)建后永遠(yuǎn)不會(huì)修改的分支對(duì)于多項(xiàng)目,SVN建議根據(jù)項(xiàng)目彼此之間的關(guān)聯(lián)程度劃分為幾個(gè)組合,然后為每一個(gè)項(xiàng)目組合建立一個(gè)版本庫(kù)。這樣,在相關(guān)項(xiàng)目之間共享數(shù)據(jù)就比較簡(jiǎn)單。常見的一個(gè)多項(xiàng)目版本庫(kù)的布局如下: / calc/ trunk/ tags/ branches calendar/ trunk/ tags/ branches spreadsheet/ trunk/ tags/ branches(2)文件的初始化導(dǎo)入(svnimport)svnimport通常用在需要將一組文件加入到SVN版本庫(kù)時(shí),不需要工作拷貝,將文件直接提交版本庫(kù)。例如:$svnimporttry_makefile:///home/jiang/svn/maketest/trunk-m“Initialimport”Addingtry_make/right_btmAddingtry_make/right_topAddingtry_make/main.cAddingtry_make/left_topAddingtry_make/left_btmCommittedrevision1.這里假設(shè)已經(jīng)建立了版本庫(kù)/home/jiang/svn/maketest,該命令將創(chuàng)建目錄/home/jiang/svn/maketest/trunk,并將try_make下的所有文件全部導(dǎo)入到該版本庫(kù)的這一目錄中,建立版本號(hào)為1的修訂版本。值得注意的是,在導(dǎo)入之后,原來的目錄樹try_make并沒有轉(zhuǎn)化為工作拷貝。要運(yùn)行SVN進(jìn)行版本管理,仍然需要運(yùn)行svncheckout導(dǎo)出一個(gè)工作目錄。(3)工作拷貝的初始化檢出(svncheckout)svncheckout命令將會(huì)在本機(jī)創(chuàng)建一個(gè)新的“工作拷貝”,從而可以開始使用SVN。注意該命令得到的是版本庫(kù)中的最新版本。例如:$svncheckoutfile:///home/jiang/svn/maketest/AtrunkAtrunk/right_btmAtrunk/right_topAtrunk/main.cAtrunk/left_btmAtrunk/left_topCheckedoutrevision3.這里checkout命令將在當(dāng)前目錄下創(chuàng)建目錄trunk,并導(dǎo)出了最新的修訂版本。可以使用選項(xiàng)-r來得到過去版本的工作拷貝,如為了得到版本號(hào)為2的版本,可以運(yùn)行:$svncheckout-r2file:///home/jiang/svn/maketest/SVN的一天(1)工作拷貝的更新(svnupdate)svnupdate將使得工作拷貝與版本庫(kù)中的最新版本同步,得到團(tuán)隊(duì)中其他所有人作出的修改。例如下面楊進(jìn)行了更新:$svnupdateUtrunk/right_btmUtrunk/left_topCheckedoutrevision4.這里表示其它人在楊上次更新之后提交了對(duì)right_btm和left_top的修改,SVN更新了楊的工作拷貝引入了這些修改。(2)工作拷貝的修改:修改目錄樹的五個(gè)命令對(duì)于單個(gè)文件內(nèi)容的修改,不需要告訴SVN,SVN將自動(dòng)監(jiān)測(cè)到文件的修改。對(duì)于目錄樹的更改,需要告訴SVN預(yù)定的動(dòng)作,如刪除、添加、拷貝等。這些動(dòng)作會(huì)在工作拷貝上立刻發(fā)生效果,但是只有提交版本庫(kù)后才會(huì)在版本庫(kù)中生效。命令說明svnaddTEMP預(yù)定將文件或目錄TEMP添加到版本庫(kù)。如果TEMP是目錄,則所有TEMP中的內(nèi)容也會(huì)預(yù)定添加到版本庫(kù)。svndeteleTEMP預(yù)定刪除文件或目錄TEMP。如果TEMP是文件,則立即從工作拷貝中刪除。若TEMP是目錄,則提交版本庫(kù)之后才會(huì)從工作拷貝和版本庫(kù)中刪除。svncopyTEMP1TEMP2建立一個(gè)新的文件或目錄TEMP2作為TEMP1的復(fù)制svnmoveTEMP1TEMP2修改TEMP1的文件或目錄名為TEMP2svnmkdirTEMP創(chuàng)建新的目錄TEMP,并預(yù)定添加到版本庫(kù)中例如:$svnmkdirbranchAbranch$cdbranch利用vi或者Emacs等在該目錄下新建Makefile1文件,然后運(yùn)行:$cpMakefile1Makefile2$svnaddMakefile1Makefile2AMakefile1AMakefile2$svncommitAddingbranchAddingbranch/MakefileAddingbranch/Makefile2Transmittingfiledata..Committedrevision4.這里提交(svncommit)之后才在版本庫(kù)中添加了目錄branch和兩個(gè)文件。繼續(xù)運(yùn)行:$svndeleteMakefile2DMakefile2$svncommitDeletingbranch/Makefile2Committedrevision5.(3)檢查修改(svnstatus和svndiff)通常在提交工作拷貝前,可以通過svnstatus瀏覽上次更新后所作的所有修改,或者利用svndiff來查看修改的詳細(xì)信息。注意,這兩個(gè)命令的調(diào)用不需要聯(lián)系版本庫(kù),只是與.svn/中的原始數(shù)據(jù)進(jìn)行比較,因此可以在沒有網(wǎng)絡(luò)的狀態(tài)下工作。例如若楊修改了Makefile2文件:原來的Makefile2楊修改后的Makefile2try: main.oleft.oright.o<TAB> cc-o$@$^main.o: main.c<TAB> cc-cmain.cright.o: right.c<TAB> cc-cright.cleft.o: left.c<TAB> cc-cleft.otry: main.oleft.oright.o<TAB> cc-o$@$^#main.o: main.c#<TAB> cc-cmain.c#right.o: right.c#<TAB> cc-cright.c#left.o: left.c#<TAB> cc-cleft.o.c.o:<TAB> cc-c$<運(yùn)行svnstatus,顯示:$svnstatusMMakefile2如果要檢查工作拷貝中的所有項(xiàng)目,即使是沒有改變過的,可以運(yùn)行svnstatus,并添加-v選項(xiàng),$svnstatus-v77yang.M77yangMakefile274jiangMakefile1運(yùn)行svndiff,顯示:$svndiffIndex:Makefile2================================================================Makefile2 (revision7)+++Makefile2 (workingcopy)@@-1,9+1,12@@try: main.oleft.oright.o<TAB> cc-o$@$^-main.o: main.c-<TAB> cc-cmain.c-right.o: right.c-<TAB> cc-cright.c-left.o: left.c<TAB> cc-cleft.o+#main.o:main.c+#<TAB>cc-cmain.c+#right.o:right.c+#<TAB>cc-cright.c+#left.o:left.c+#<TAB>cc-cleft.o+.c.o:+ cc-c$<也可以將詳細(xì)的修改信息通過重定向生成一個(gè)區(qū)別文件,發(fā)給其他開發(fā)者作為參考,如:$svndiff>patchfile(4)解決沖突(svnupdate+svnresolved)這里假設(shè)楊和江首先分別update了各自的工作拷貝,更新到Version9。楊在Version9的基礎(chǔ)上對(duì)Makefile2作了修改,然后提交版本庫(kù)成功。更新版本庫(kù)為Version10。這時(shí)江剛剛在Version9的基礎(chǔ)上完成自己對(duì)Makefile2的修改,由于修改的部分與楊修改的部分沖突,提交的時(shí)候?qū)@示:$svnupdateConflictdiscoveredin'branch/Makefile2'.Select:(p)postpone,(df)diff-full,(e)edit,(r)resolved,(h)helpformoreoptions:pCbranch/Makefile2Updatedtorevision10.這時(shí),SVN不會(huì)允許提交,這里的C表示江修改的文件branch/Makefile2與服務(wù)器上最新版本的Makefile2發(fā)生沖突了,需要手工解決。對(duì)于每一個(gè)沖突的文件,SVN會(huì)產(chǎn)生三個(gè)新的文件到該文件所在的目錄中,分別是:Makefile2.mine修改前工作拷貝中的文件,沒有沖突標(biāo)記。Makefile2.rOLDREV上一次更新后但還沒有修改前的文件,OLDREV指得是上一次更新后文件的版本號(hào)Makefile2.rNEWREV客戶端剛剛從版本庫(kù)中收到的版本,即當(dāng)前版本庫(kù)中最新版本的文件,NEWREV是當(dāng)前版本庫(kù)中最新版本的版本號(hào)這時(shí)Makefile2文件也會(huì)改變,SVN將在該文件中置入沖突標(biāo)記(特殊的符號(hào))同時(shí)顯示沖突的內(nèi)容。下面表格中給出了更新后各個(gè)文件具體的內(nèi)容。Makefile2.r9(楊和江本次update的結(jié)果)楊對(duì)Makefile2的修改結(jié)果(已提交版本庫(kù),即版本庫(kù)中的Makefile2,Makefile2.r10)Makefile2try:main.oleft.oright.o<TAB> cc-o$@$^#main.o: main.c#<TAB> cc-cmain.c%.c:right.c#<TAB> cc-cright.c#left.o: left.c#<TAB> cc-cleft.o.c.o:<TAB> cc-c$<try: main.oleft.oright.o<TAB> cc-o$@$^#main.o:main.c#<TAB> cc-cmain.c%.c: right.c#<TAB> cc-cright.cleft.o: left.c#<TAB> cc-cleft.o.c.o:<TAB> cc-c$<try:main.oleft.oright.o<TAB> cc-o$@$^#main.o: main.c#<TAB> cc-cmain.c%.c: right.c#<TAB> cc-cright.c<<<<<<<.mineright.c:right_topright_btm=======left.o:left.c>>>>>>>.r10#<TAB> cc-cleft.o.c.o:<TAB> cc-c$<江的修改版本(Makefile2.mine)try: main.oleft.oright.o<TAB> cc-o$@$^#main.o: main.c#<TAB> cc-cmain.c%.c: right.c#<TAB> cc-cright.cright.c: right_topright_btm#<TAB> cc-cleft.o.c.o:<TAB> cc-c$<SVN不允許在這種情況下提交版本庫(kù)。如果已經(jīng)修改好Makefile2文件,首先需要運(yùn)行svnresolved告訴SVN沖突已經(jīng)解決,刪除Makefile2.mine、Makefile2.r9和Makefile2.r10,然后才能提交。$svnresolvedMakefile2Resolvedconflictedstateof'Makefile2'這時(shí)運(yùn)行$ls,可以發(fā)現(xiàn)SVN自動(dòng)刪除了Makefile2.mine、Makefile2.r9和Makefile2.r10。(5)工作拷貝的提交(svncommit)沖突解決后,就可以采用$svncommit命令進(jìn)行新版本的提交。屏幕會(huì)顯示GNUnano2.0.7File:svn-commit.tmp 表示此次版本的日志信息會(huì)寫入svn-commit.tmp 光標(biāo)閃爍,提示提交者寫日志信息--Thisline,andthosebelow,willbeignored--MMakefile 表示該次提交版本修改了Makefile2文件完成日志信息后,鍵入Ctrl+X(表示退出日志編寫),屏幕會(huì)顯示:Sendingbranch/Makefile2Transmittingfiledata.Committedrevision11.日志信息一般寫入修改者信息、本次版本的修改內(nèi)容等。也可以采用-m選項(xiàng)完成日志的編寫,如:$svncommit–m“Makefile2iscorrectedbyJiang”其他(1)檢查歷史(svnlog)svnlog命令可以給出一個(gè)指定文件或目錄的歷史信息,包括:文件/目錄的修改者、修訂的版本號(hào)、日期、時(shí)間以及日志信息。在沒有提供路徑的情況下,svnlog將使用當(dāng)前目錄作為默認(rèn)的目標(biāo)。例如:$svnlogr9|jiang|2009-04-0218:22:19+0800(四,024月2009)|2linesAddingMakefilebyJiangr8|yang|2009-04-0218:17:34+0800(四,024月2009)|2linesInitialimport表示當(dāng)前目錄在版本8的時(shí)候版本庫(kù)中才由楊建立該目錄,江在版本9中增加了Makefile文件。因此,若給定文件Makefile,運(yùn)行:$svnlogMakefiler9|jiang|2009-04-0218:22:19+0800(四,024月2009)|2linesAddingMakefilebyJiang表示Makefile文件是在版本9中由江增加的。(2)瀏覽版本庫(kù)(svnls)svnlist可以在不下載文件到本地目錄的情況下查看版本庫(kù)中個(gè)目錄中的文件,如下:$svnlsfile:///home/jiang/svn/maketest/trunkMakefileleft_btmleft_topmain.cright_btmright_top(3)狀態(tài)碼在更新工作拷貝、查看狀態(tài)或提交版本時(shí),文件名前會(huì)出現(xiàn)一列狀態(tài)碼提示文件的狀態(tài)。常見狀態(tài)碼的含義如下: A 預(yù)定該文件/目錄將加入到版本庫(kù) D 預(yù)定該文件/目錄將從版本庫(kù)中刪除 U 工作拷貝中的該文件/目錄已被更新 C 該文件與版本庫(kù)中的最新版本發(fā)生沖突 M 該文件的內(nèi)容已被修改2.7.5SVN的分支與合并分支(branch)、合并(merge)和標(biāo)簽(tag)是所有的版本控制系統(tǒng)的共同概念。分支與合并不同部門之間根據(jù)不同的需要,從開發(fā)主線建立自己獨(dú)立的分支,或是版本庫(kù)的開發(fā)線。這樣既能夠不打攪別人的工作,又可以實(shí)現(xiàn)選擇性的共享。例如如果采用SVN開發(fā)了一個(gè)國(guó)內(nèi)就業(yè)網(wǎng)站的源代碼,而在上海和北京都需要建立類似的網(wǎng)站,頁(yè)面代碼基本相同,只在某些接口等方面存在差異,這時(shí)最好的方法就是從原來網(wǎng)站代碼的開發(fā)主線上新建兩個(gè)分支,來分別對(duì)這兩個(gè)網(wǎng)站代碼進(jìn)行開發(fā)和管理。(1)分支的創(chuàng)建:利用svncopy對(duì)兩個(gè)URL的直接操作$svncopyfile:///home/jiang/svn/maketest/trunk\file:///home/jiang/svn/maketest/branches/my_branch\-m"creatingaprivatebranchof/trunk"Committedrevision21.這樣,江就從trunk創(chuàng)建了一個(gè)分支branches/my_branch。這種創(chuàng)建方式不需要本地的工作拷貝。這里SVN并不拷貝所有的數(shù)據(jù),而是建立一個(gè)已存在目錄樹的入口,類似Unix中的hard-link。因此copy的時(shí)間和空間消耗很小,與目錄大小無關(guān)。(2)合并(svnmerge)如果楊在對(duì)主線trunk進(jìn)行debug,江在自己的分支branches/my_branch上進(jìn)行開發(fā)。那么楊作的一些更新很可能對(duì)江也是有用的。因此江在分支開發(fā)的過程中,應(yīng)該考慮在楊對(duì)主線更新后將對(duì)自己有利的更新合并(merge)到自己的分支中。例如,版本號(hào)為20的trunk目錄中存在Makefile2文件,內(nèi)容如下: try: mai
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 46810-2025電力北斗時(shí)間同步系統(tǒng)安全防護(hù)技術(shù)要求
- 養(yǎng)老院醫(yī)療保健服務(wù)管理制度
- 企業(yè)員工獎(jiǎng)懲與激勵(lì)制度
- 會(huì)議信息發(fā)布與宣傳推廣制度
- 2026年房地產(chǎn)經(jīng)紀(jì)人從業(yè)資格題庫(kù)與答案
- 2026年?duì)I養(yǎng)師專業(yè)能力與知識(shí)考試題集
- 2026年移動(dòng)支付與金融科技產(chǎn)品實(shí)操試題
- 2026年財(cái)務(wù)管理高級(jí)筆試模擬卷
- 2026年軟件測(cè)試專家知識(shí)技能水平認(rèn)證題目
- 2026年新版原代細(xì)胞合同
- 山東煙草2026年招聘(197人)考試備考試題及答案解析
- 二級(jí)醫(yī)院的DRGs培訓(xùn)課件
- 空芯光纖行業(yè)分析報(bào)告
- 置業(yè)顧問崗位招聘考試試卷及答案
- 大眾試駕協(xié)議書
- 2026年醫(yī)療行業(yè)患者滿意度改善方案
- GB/T 4605-2025滾動(dòng)軸承推力滾針和保持架組件及推力墊圈
- 老年機(jī)構(gòu)養(yǎng)老心理健康評(píng)估方案
- 港澳聯(lián)考中文真題及答案
- GB 11174-2025液化石油氣
- 肝素鈉工藝流程
評(píng)論
0/150
提交評(píng)論