版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第9章 Linux程序設(shè)計(jì)基礎(chǔ) 本章學(xué)習(xí)目標(biāo)本章學(xué)習(xí)目標(biāo)通過(guò)對(duì)本章的學(xué)習(xí),讀者應(yīng)該掌握以下主要內(nèi)容:Linux編程風(fēng)格Linux下IDE的使用Linux下使用GNU cc開(kāi)發(fā)應(yīng)用程序Linux程序的調(diào)試Linux下使用RCS/CVS來(lái)管理源程序Linux下軟件打包9.1 概述概述 9.1.1 Linux編程編程 Linux軟件開(kāi)發(fā)一直在Internet環(huán)境下講行。這個(gè)環(huán)境是全球性的,編程人員來(lái)自世界各地。只要能夠訪(fǎng)問(wèn)Web站點(diǎn),就可以啟動(dòng)一個(gè)以L(fǎng)inux為基礎(chǔ)的軟件項(xiàng)目。Linux開(kāi)發(fā)工作經(jīng)常是在Linux用戶(hù)決定共同完成一個(gè)項(xiàng)目時(shí)開(kāi)始的。當(dāng)開(kāi)發(fā)工作完成后,該軟件就被放到Internet站點(diǎn)上
2、,任何用戶(hù)都可以訪(fǎng)問(wèn)和下載它。由于這個(gè)活躍的開(kāi)發(fā)環(huán)境,新的以L(fǎng)inux為基礎(chǔ)的軟件功能日益強(qiáng)大,而且呈現(xiàn)爆炸式的增長(zhǎng)態(tài)勢(shì)。 大多數(shù)Linux軟件是經(jīng)過(guò)自由軟件基金會(huì)(Free Software Foundation)提供的GNU(GNU 即 GNUs not UNIX)公開(kāi)認(rèn)證授權(quán)的,因而通常被稱(chēng)作GNU軟件。GNU軟件免費(fèi)提供給用戶(hù)使用,并被證明是非常可靠和高效的。許多流行的Linux實(shí)用程序如C編譯器、shell和編輯器都是GNU軟件應(yīng)用程序。 Linux程序需要首先轉(zhuǎn)化為低級(jí)機(jī)器語(yǔ)言即所謂的二進(jìn)制代碼以后,才能被操作系統(tǒng)執(zhí)行。例如編程時(shí),先用普通的編程語(yǔ)言生成一系列指令,這些指令可被翻譯
3、為適當(dāng)?shù)目蓤?zhí)行應(yīng)用程序的二進(jìn)制代碼。這個(gè)翻譯過(guò)程可由解釋器一步步來(lái)完成,或者也可以立即由編譯器明確地完成。shell編程語(yǔ)言如BASH、TCSH、GAWK、Perl、Tcl和Tk都利用自己的解釋器。用這些語(yǔ)言編制的程序盡管是應(yīng)用程序文件,但可以直接運(yùn)行。編譯器則不同,它將生成一個(gè)獨(dú)立的二進(jìn)制代碼文件然后才可以運(yùn)行。 9.1.2 Linux編程風(fēng)格編程風(fēng)格 (1)函數(shù)返回類(lèi)型說(shuō)明和函數(shù)名分兩行放置,函數(shù)起始字符和函數(shù)開(kāi)頭左花括號(hào)放到最左邊。(2)盡量不要讓兩個(gè)不同優(yōu)先級(jí)的操作符出現(xiàn)在相同的對(duì)齊方式中,應(yīng)該附加額外的括號(hào)使得代碼縮進(jìn)可以表示出嵌套。 (3)按照如下方式排版do-while語(yǔ)句: (
4、4)每個(gè)程序都應(yīng)該以一段簡(jiǎn)短的說(shuō)明其功能的注釋開(kāi)頭。 (5)請(qǐng)為每個(gè)函數(shù)書(shū)寫(xiě)注釋?zhuān)f(shuō)明函數(shù)是做什么的,需要哪些入口參數(shù),參數(shù)可能值的含義和用途。如果用了非常見(jiàn)的、非標(biāo)準(zhǔn)的東西,或者可能導(dǎo)致函數(shù)不能工作的任何可能的值,應(yīng)該進(jìn)行特殊說(shuō)明。如果存在重要的返回值,也需要說(shuō)明。 (6)不要聲明多個(gè)變量時(shí)跨行,每一行都以一個(gè)新的聲明開(kāi)頭。 (7)當(dāng)一個(gè)if中嵌套了另一個(gè)if-else時(shí),應(yīng)用花括號(hào)把if-else括起來(lái)。 (8)要在同一個(gè)聲明中同時(shí)說(shuō)明結(jié)構(gòu)標(biāo)識(shí)和變量或者結(jié)構(gòu)標(biāo)識(shí)和類(lèi)型定義(typedef)。先定義變量,再使用。 1 1GNUGNU風(fēng)格風(fēng)格 (9)盡量避免在if的條件中進(jìn)行賦值。 (10)請(qǐng)
5、在名字中使用下劃線(xiàn)以分割單詞,盡量使用小寫(xiě);把大寫(xiě)字母留給宏和枚舉常量,以及根據(jù)統(tǒng)一慣例使用的前綴。例如,應(yīng)該使用類(lèi)似ignore_space_change_flag的名字;不要使用類(lèi)似iCantReadThis的名字。(11)用于表明一個(gè)命令行選項(xiàng)是否給出的變量應(yīng)該在選項(xiàng)含義的說(shuō)明之后,而不是選項(xiàng)字符之后被命名。 2 2Linux Linux 內(nèi)核編程風(fēng)格內(nèi)核編程風(fēng)格 (1)Linux內(nèi)核縮進(jìn)風(fēng)格是8個(gè)字符。 (2)Linux內(nèi)核風(fēng)格采用K&R標(biāo)準(zhǔn),將開(kāi)始的大括號(hào)放在一行的最后,而將結(jié)束的大括號(hào)放在一行的第一位。(3)命名盡量簡(jiǎn)潔。不應(yīng)該使用諸如ThisVariableIsATemp
6、oraryCounter之類(lèi)的名字。應(yīng)該命名為tmp,這樣容易書(shū)寫(xiě),也不難理解。但是命名全局變量,就應(yīng)該用描述性命名方式,例如應(yīng)該命名“count_active_users()”,而不是“cntusr()”。本地變量應(yīng)該避免過(guò)長(zhǎng)。 (4)函數(shù)最好短小精悍,一般來(lái)說(shuō)不要讓函數(shù)的參數(shù)多于個(gè),否則應(yīng)該嘗試分解這個(gè)過(guò)于復(fù)雜的函數(shù)。 (5)通常情況,注釋說(shuō)明代碼的功能,而不是其實(shí)現(xiàn)原理。避免把注釋插到函數(shù)體內(nèi),而寫(xiě)到函數(shù)前面,說(shuō)明其功能,如果這個(gè)函數(shù)的確很復(fù)雜,其中需要有部分注釋?zhuān)梢詫?xiě)些簡(jiǎn)短的注釋來(lái)說(shuō)明那些重要的部分,但是不能過(guò)多。 9.2 IDE使用使用 9.2.1 VIM編輯器編輯器 1 1VIM
7、VIM的簡(jiǎn)介的簡(jiǎn)介 VI是Linux世界里最常用的全屏編輯器,所有的Linux機(jī)器都提供該編輯器,而Linux里提供的是VI的加強(qiáng)版VIM,但同VI是完全兼容。VI的原意是“visual interface”,即可視編輯器,用戶(hù)鍵入的內(nèi)容會(huì)立即被顯示出來(lái)、而且其強(qiáng)大的編輯功能可以同任何一種最新的編輯器相媲美。它在Linux上的地位就仿佛Edit程序在DOS上一樣。它可以執(zhí)行輸出、刪除、查找、替換、塊操作等眾多文本操作,而且用戶(hù)可以根據(jù)需要對(duì)其進(jìn)行定制,這是其他編輯程序所沒(méi)有的。VI不是一個(gè)排版程序,不象Word或WPS那樣可以對(duì)字體、格式、段落等其他屬性進(jìn)行編排,它只是一個(gè)文本編輯程序。 2
8、2VIM VIM 的基本觀念的基本觀念 VIM有三種操作方式,分別是:命令方式插入方式命令行方式 3 3VIMVIM的進(jìn)入與離開(kāi)的進(jìn)入與離開(kāi) 在系統(tǒng)提示符“$”下鍵入命令VIM,后面跟上想要編輯(或者建立)的文件名,VIM 可以自動(dòng)載入所要編輯的文件或是開(kāi)啟一個(gè)新文件。 VIM的退出,可以在命令行方式下使用命令“:wq”或者“:q!”,前者的功能是寫(xiě)文件并從VIM中退出,后者的功能是從VIM中退出,但不保存所作的修改(注意冒號(hào))。 4 4VIMVIM的命令方式的命令方式 (1)光標(biāo)移動(dòng) 要對(duì)正文內(nèi)容進(jìn)行修改,必須先把光標(biāo)移動(dòng)到要修改的內(nèi)容所在的位置,用戶(hù)除了通過(guò)按鍵盤(pán)的上、下、左、右箭頭鍵來(lái)移
9、動(dòng)光標(biāo),還可以利用VIM提供的眾多字符組合鍵,在正文中移動(dòng)光標(biāo),迅速達(dá)到指定的行或列,實(shí)現(xiàn)定位,常用的快捷鍵有:表9-1 (2)替換和刪除 將光標(biāo)定位于文檔中指定位置后,可以用其他字符替換光標(biāo)所指向的字符,或從當(dāng)前光標(biāo)位置刪除一個(gè)或多個(gè)字符,常用命令有:表9-2 (3)粘貼和復(fù)制 在VIM編輯器中,與Windows系統(tǒng)不同的是從正文中刪除的內(nèi)容(如字符、字段或行)并沒(méi)有真正丟失,而是被剪貼并復(fù)制到了一個(gè)內(nèi)存緩沖區(qū)中,用戶(hù)可將其粘貼到正文中的任意位置,完成這一操作的命令是:表9-3 (4)查找字符串 為了方便文檔的編輯,VIM提供了強(qiáng)大的字符串查找功能,要查找文件中指定字符或字段出現(xiàn)的位置,可以
10、用該功能直接進(jìn)行搜索,搜索方法是:在命令行鍵入字符“/”,后面加上要搜索的字符串,然后按回車(chē)鍵,編輯程序?qū)?zhí)行正向搜索(從光標(biāo)所在的位置向文件末尾方向),并在找到指定字符串后,將光標(biāo)停在該字符串的開(kāi)頭;鍵入n命令可以繼續(xù)執(zhí)行搜索,找出這一字符串下次出現(xiàn)的位置,用字符“?”取代“/”,可以實(shí)現(xiàn)反向搜索(從光標(biāo)所在的位置向文件開(kāi)頭方向),舉例說(shuō)明如下:表9-5 (5)撤銷(xiāo)和重復(fù) 在編輯文檔的過(guò)程中,可以取消錯(cuò)誤的編輯命令造成的后果,另外,如果用戶(hù)希望在新的光標(biāo)位置再次執(zhí)行先前的編輯命令,可用重復(fù)命令。表9-6 5 5VIMVIM的插入方式的插入方式 (1)進(jìn)入插入方式 在命令方式下正確定位光標(biāo)之后
11、,可用一下命令切換到插入方式:表9-7 如果用戶(hù)想利用已有的文件內(nèi)容,可以使用命令“:ifilename”,則VIM將指定文件的內(nèi)容輸入當(dāng)前光標(biāo)的下一行,且VIM仍處于命令方式。 (2)退出插入方式 退出插入方式的方法是,按ESC鍵或組合鍵Ctrl+I (3)正文替換 除了幾種簡(jiǎn)單的切換到插入方式的方法外,還有一些命令允許用戶(hù)在插入模式之前首先刪去一段文字,從而實(shí)現(xiàn)正文的替換,這些命令包括:表9-8 6 6VIMVIM的命令方式的命令方式 (1)行號(hào)與文件 編輯中文檔的每一行正文都有隱藏的行號(hào),用下列命令可以移動(dòng)光標(biāo)到指定行:表9-9 在命令方式下,用戶(hù)可以規(guī)定命令操作的行號(hào)范圍,數(shù)值用來(lái)指定
12、絕對(duì)行號(hào);字符“,”表示光標(biāo)所在行的行號(hào);字符“$”表示正文最后一行的行號(hào),示例如下:表9-10 在命令方式下,用戶(hù)還可以對(duì)文件進(jìn)行操作,允許從文件中讀取正文,或?qū)⒄膶?xiě)入文件,常用命令如下:表9-11 9.2.1 VIM編輯器編輯器 1 1emacsemacs的簡(jiǎn)介的簡(jiǎn)介 emacs文本編輯器可以用來(lái)編輯文本、剪輯和粘貼文本內(nèi)容、提供個(gè)人日歷和日記,閱讀Usenet新聞、發(fā)送電子郵件,同時(shí)還是一種程序語(yǔ)言解釋器,可以編輯C、Lisp、Tev源代碼文件、以及Linux的Shell。 emacs是由 Richard Stallman發(fā)明的,這位發(fā)明者還創(chuàng)建了自由軟件基金會(huì)(Free Softwa
13、re Foundation,簡(jiǎn)稱(chēng)FSF)。最初的emacs是用來(lái)編輯宏命令的,現(xiàn)已進(jìn)一步擴(kuò)充為 UNIX用戶(hù)中裝機(jī)用戶(hù)數(shù)量最大、功能最齊全的免費(fèi)文本編輯器了。 emacs同VI不一樣,沒(méi)有編輯狀態(tài)和指令狀態(tài)之分,其最重要的概念是其獨(dú)特的緩沖區(qū),emacs編輯的所有文件都是放在緩沖區(qū)中的,emacs支持同時(shí)編輯多個(gè)緩沖區(qū),可以將一個(gè)文件在多個(gè)緩沖區(qū)中打開(kāi)不同的拷貝,甚至其所有的在線(xiàn)幫助和文檔以及出錯(cuò)信息都是作為一個(gè)緩沖區(qū)來(lái)顯示的,當(dāng)然這些緩沖區(qū)是不可寫(xiě)的,用戶(hù)可以在這些緩沖區(qū)之間拷貝和粘貼文本。并且一般所有的緩沖區(qū)在硬盤(pán)上都有一個(gè)以“#”開(kāi)頭的備份文件,這樣在系統(tǒng)突然崩潰的時(shí)候可以即時(shí)將用戶(hù)的工
14、作進(jìn)行備份。在編輯文件時(shí),如果用戶(hù)在編輯一些特殊類(lèi)型的文件,例如當(dāng)用戶(hù)編輯擴(kuò)展名為.c的C語(yǔ)言文件時(shí),emacs會(huì)產(chǎn)生菜單選項(xiàng)c,向用戶(hù)提供一些針對(duì)編輯c程序特別有用的一些命令。當(dāng)用戶(hù)編輯擴(kuò)展名為.txt的文件則會(huì)多出菜單選項(xiàng)tex,讓用戶(hù)在編輯完tex文件后可以即時(shí)地觀看輸出并打印。首先介紹一下幾個(gè)常見(jiàn)的鍵盤(pán)操作符號(hào)的意義:所有的emacs的操作鍵都是由Control鍵(一般是鍵盤(pán)上的Ctrl鍵)和META鍵(一般是鍵盤(pán)上的Alt鍵)加上一些鍵的組合組成的,如果沒(méi)有Alt鍵,則可以用輸入一個(gè)Esc,再輸入相應(yīng)的鍵來(lái)代替。例如: C-x:表示同時(shí)按住Ctrl鍵和x鍵。 C x:表示先按住Ctr
15、l鍵,然后釋放它,再按下x鍵。 M-x:表示同時(shí)按住Alt鍵和x鍵。 M x:表示先按住Alt鍵,釋放它,再按下x鍵。 2emacs的啟動(dòng)和退出的啟動(dòng)和退出 emacs可以用兩種方法啟動(dòng)。第一種啟動(dòng)emacs的方法是不裝載任何文本文件啟動(dòng)emacs,輸入以下命令行:# emacs 在屏幕上會(huì)出現(xiàn)無(wú)任何文本emacs編輯窗口,如圖9-2所示。 如果用戶(hù)是初學(xué)者,最好的學(xué)習(xí)方法是:按下Ctrl-h鍵(即按住Ctrl鍵后不放,再按下h字母鍵),就會(huì)自動(dòng)進(jìn)入emacs的聯(lián)機(jī)幫助,在屏幕底部emacs命令行中會(huì)出現(xiàn)一個(gè)提示符,這時(shí)再按下字母鍵t和回車(chē)鍵,便進(jìn)入了簡(jiǎn)捷有效的emacs文本編輯器的教程。參照
16、此教程的步驟,用戶(hù)將對(duì)如何使用emacs有個(gè)概括的了解。 第二種啟動(dòng)emacs的方法是通過(guò)裝載某一個(gè)文本文件啟動(dòng)emacs,輸入以下命令行:# emacs filename如果裝載的文件不在當(dāng)前目錄時(shí)必須輸入該文件名的全稱(chēng)(包括所在目錄)。例如,當(dāng)前目錄下有一個(gè)文本文件myfile.txt,用emacs對(duì)其編輯時(shí),輸入命令行啟動(dòng)emacs:# emacs myfile.txt 屏幕上將出現(xiàn)如圖9-3所示的emacs編輯窗口。 3emacs的基本操作的基本操作 (1)光標(biāo)的移動(dòng)下面列出emacs中的光標(biāo)的移動(dòng)情況及其鍵盤(pán)操作: M-b:光標(biāo)移動(dòng)到光標(biāo)左邊的單詞的開(kāi)始處。 M-f:光標(biāo)移動(dòng)到光標(biāo)右
17、邊的單詞的開(kāi)始處。 M-a:光標(biāo)移動(dòng)到當(dāng)前句子的開(kāi)始處。 M-e:光標(biāo)移動(dòng)到當(dāng)前句子的結(jié)束處。 C-n:光標(biāo)移動(dòng)到下一行。 C-p:光標(biāo)移動(dòng)到上一行。 C-a:光標(biāo)移動(dòng)到行首。 C-e:光標(biāo)移動(dòng)到行尾。 M-:光標(biāo)移動(dòng)到文件尾。 M-編譯”命令進(jìn)行程序的編譯,如圖9-15所示。如果程序沒(méi)有出錯(cuò),將看到Kdevelop下方的信息框之中顯示編譯成功的信息。 接著便可以執(zhí)行應(yīng)用程序了,執(zhí)行“建立-執(zhí)行”命令進(jìn)行程序的連接,如圖9-16所示。若沒(méi)有發(fā)生問(wèn)題,就會(huì)在另一個(gè)窗口中看到程序的執(zhí)行結(jié)果,如圖9-17所示。 圖9-15 編譯應(yīng)用程序 圖9-16 執(zhí)行應(yīng)用程序 圖9-17 應(yīng)用程序的執(zhí)行結(jié)果 9.
18、3 使用使用GNU cc開(kāi)發(fā)應(yīng)用程序開(kāi)發(fā)應(yīng)用程序 9.3.1 使用使用GNU cc 1gcc的簡(jiǎn)介的簡(jiǎn)介 gcc可以使程序員靈活地控制編譯過(guò)程。編譯過(guò)程一般可以分為下面四個(gè)階段,每個(gè)階段分別調(diào)用不同的工具進(jìn)行處理,如圖9-18所示。 預(yù)處理鏈接編譯組譯源程序(*.c)可執(zhí)行文件預(yù)處理器編譯器組譯器連接器2gcc的版本信息的版本信息 一般來(lái)說(shuō),系統(tǒng)安裝后就已經(jīng)安裝和設(shè)定好了gcc。在shell的提示符下鍵入gcc v,屏幕上就會(huì)顯示出目前正在使用的gcc的版本,同時(shí)這可以確定系統(tǒng)所支持的是ELF還是a.out可執(zhí)行文件格式。 Linux系統(tǒng)中可執(zhí)行文件有兩種格式。第一種格式是a.out格式,這種
19、格式用于早期的Linux系統(tǒng)以及 Unix系統(tǒng)的原始格式。a.out來(lái)自于Unix C編譯程序默認(rèn)的可執(zhí)行文件名。當(dāng)使用共享庫(kù)時(shí),a.out格式就會(huì)發(fā)生問(wèn)題。把a(bǔ).out格式調(diào)整為共享庫(kù)是一種非常復(fù)雜的操作,由于這個(gè)原因,一種新的文件格式被引入U(xiǎn)nix系統(tǒng)5的第四版本和Solaris系統(tǒng)中。它被稱(chēng)為可執(zhí)行和連接的格式(ELF)。這種格式很容易實(shí)現(xiàn)共享庫(kù)。 ELF格式已經(jīng)被Linux系統(tǒng)作為標(biāo)準(zhǔn)的格式采用。gcc編譯程序產(chǎn)生的所有的二進(jìn)制文件都是ELF格式的文件(即使可執(zhí)行文件的默認(rèn)名仍然是a.out)。較舊的a.out格式的程序仍然可以運(yùn)行在支持ELF格式的系統(tǒng)上。 3gcc的使用的使用 gc
20、c的使用格式如下:$ gcc optionsfilenames其中filenames為所要編譯的程序源文件。 當(dāng)使用gcc時(shí),gcc會(huì)完成預(yù)處理、編譯、匯編和連接。前三步分別生成目標(biāo)文件,連接時(shí),把生成的目標(biāo)文件鏈接成可執(zhí)行文件。gcc可以針對(duì)支持不同的源程序文件進(jìn)行不同處理,文件格式以文件的后綴來(lái)識(shí)別,常見(jiàn)的如表9-1所示。 4使用優(yōu)化選項(xiàng)使用優(yōu)化選項(xiàng) 當(dāng)用gcc編譯C代碼時(shí),它會(huì)試著用最少的時(shí)間完成編譯并且使編譯后的代碼易于調(diào)試. 易于調(diào)試意味著編譯后的代碼與源代碼有同樣的執(zhí)行次序,編譯后的代碼沒(méi)有經(jīng)過(guò)優(yōu)化。有很多選項(xiàng)可用于告訴gcc,在耗費(fèi)更多編譯時(shí)間和犧牲易調(diào)試性的基礎(chǔ)上,產(chǎn)生更小更快
21、的可執(zhí)行文件。這些選項(xiàng)中最典型的是-O和-O2選項(xiàng)。 -O選項(xiàng)告訴gcc對(duì)源代碼進(jìn)行基本優(yōu)化。這些優(yōu)化在大多數(shù)情況下都會(huì)使程序執(zhí)行的更快。 -O2選項(xiàng)告訴gcc產(chǎn)生盡可能小和盡可能快的代碼。-O2選項(xiàng)將使編譯的速度比使用-O 時(shí)慢。但通常產(chǎn)生的代碼執(zhí)行速度會(huì)更快。 5使用調(diào)試和剖析選項(xiàng)使用調(diào)試和剖析選項(xiàng) GCC 支持?jǐn)?shù)種調(diào)試和剖析選項(xiàng)。在這些選項(xiàng)里最常用的是-g和-pg選項(xiàng)。-g選項(xiàng)告訴gcc產(chǎn)生能被GNU調(diào)試器使用的調(diào)試信息以便調(diào)試程序。gcc 提供了一個(gè)很多其他C編譯器里沒(méi)有的特性,在gcc里能使-g和-O(產(chǎn)生優(yōu)化代碼)連用。這一點(diǎn)非常有用,因?yàn)槟茉谂c最終產(chǎn)品盡可能相近的情況下調(diào)試代碼。
22、同時(shí)使用這兩個(gè)選項(xiàng)時(shí)必須清楚所寫(xiě)的某些代碼已經(jīng)在優(yōu)化時(shí)被gcc作了改動(dòng)。 -pg選項(xiàng)告訴gcc在程序里加入額外的代碼,執(zhí)行時(shí),產(chǎn)生gprof用的剖析信息以顯示程序的耗時(shí)情況。 9.3.2使用使用GNU make編輯編輯makefile 1準(zhǔn)備工作準(zhǔn)備工作 要使用make,必須編寫(xiě)一個(gè)叫做Makefile的文件,這個(gè)文件描述了軟件包中文件之間的關(guān)系,提供更新每個(gè)文件的命令。一般在一個(gè)軟件包里,通常是可執(zhí)行文件靠目標(biāo)文件來(lái)更新,目標(biāo)文件靠編譯源文件來(lái)更新。Makefile寫(xiě)好之后,每次改變了某些源文件,只要執(zhí)行make命令:# make 所有必要的重新編譯將執(zhí)行。Make程序利用makefile中
23、的數(shù)據(jù)和每個(gè)文件的最后修改時(shí)間來(lái)確定那個(gè)文件需要更新,對(duì)于需要更新的文件,make程序執(zhí)行makefile數(shù)據(jù)中定義的命令來(lái)更新。 2makefile文件的基本結(jié)構(gòu)文件的基本結(jié)構(gòu) GNU make的主要功能是讀進(jìn)一個(gè)文本文件makefile并根據(jù)makefile的內(nèi)容執(zhí)行一系列的工作。makefile的默認(rèn)文件名為GNUmakefile、makefile或Makefile,當(dāng)然也可以在make的命令行中指定別的文件名。如果不特別指定,make命令在執(zhí)行時(shí)將按順序查找默認(rèn)的makefile文件。多數(shù)Linux程序員使用第三種文件名Makefile。因?yàn)榈谝粋€(gè)字母是大寫(xiě),通常被列在一個(gè)目錄的文件列
24、表的最前面。 Makefile是一個(gè)文本形式的數(shù)據(jù)庫(kù)文件,其中包含一些規(guī)則來(lái)告訴make處理哪些文件以及如何處理這些文件。這些規(guī)則主要是描述哪些文件(稱(chēng)為target目標(biāo)文件,不要和編譯時(shí)產(chǎn)生的目標(biāo)文件相混淆)是從哪些別的文件(稱(chēng)為dependency依賴(lài)文件)中產(chǎn)生的,以及用什么命令(command)來(lái)執(zhí)行這個(gè)過(guò)程。依靠這些信息,make會(huì)對(duì)磁盤(pán)上的文件進(jìn)行檢查,如果目標(biāo)文件的生成或被改動(dòng)時(shí)的時(shí)間(稱(chēng)為該文件時(shí)間戳)至少比它的一個(gè)依賴(lài)文件還舊的話(huà),make就執(zhí)行相應(yīng)的命令,以更新目標(biāo)文件。目標(biāo)文件不一定是最后的可執(zhí)行文件,可以是任何一個(gè)中間文件并可以作為其他目標(biāo)文件的依賴(lài)文件。一個(gè)Makef
25、ile文件主要含有一系列的規(guī)則,每條規(guī)則包含以下內(nèi)容。一個(gè)目標(biāo)(target),即make最終需要?jiǎng)?chuàng)建的文件,如可執(zhí)行文件和目標(biāo)文件;目標(biāo)也可以是要執(zhí)行的動(dòng)作,如“clean”。一個(gè)或多個(gè)依賴(lài)文件(dependency)列表,通常是編譯目標(biāo)文件所需要的其他文件。 一系列命今(command),是make執(zhí)行的動(dòng)作,通常是把指定的相關(guān)文件編譯成目標(biāo)文件的編譯命令,每個(gè)命令占一行,且每個(gè)命令行的起始字符必須為T(mén)AB字符。 除非特別指定,否則make的工作目錄就是當(dāng)前目錄。target是需要?jiǎng)?chuàng)建的二進(jìn)制文件或目標(biāo)文件,dependency是在創(chuàng)建target時(shí)需要用到的一個(gè)或多個(gè)文件的列表,命令序列
26、是創(chuàng)建target文件所需要執(zhí)行的步驟,比如編譯命令。Makefile規(guī)則的一般形式如下:target:dependency dependency(tab) 例如,有以下的Makefile文件:# 一個(gè)簡(jiǎn)單的Makefile的例子# 以#開(kāi)頭的為注釋行test:prog.o code.ogcc o test prog.o code.o prog.o:prog.c prog.h code.hgcc c prog.c o prog.o code.o:code.c code.hgcc c code.c o code.o clean:rm f *.o 上面的Makefile文件中共定義了四個(gè)目標(biāo):te
27、st、prog.o、code.o和clean。目標(biāo)從每行的最左邊開(kāi)始寫(xiě),后面跟一個(gè)冒號(hào)(:),如果有與這個(gè)目標(biāo)有依賴(lài)性的其他目標(biāo)或文件,把它們列在冒號(hào)后面,并以空格隔開(kāi)。然后另起一行開(kāi)始寫(xiě)實(shí)現(xiàn)這個(gè)目標(biāo)的一組命令。在Makefile中,可使用續(xù)行號(hào)()將一個(gè)單獨(dú)的命令行延續(xù)成幾行。但要注意在續(xù)行號(hào)()后面不能跟任何字符(包括空格和鍵)。一般情況下,調(diào)用make命令可輸入:# make targettarget是Makefile文件中定義的目標(biāo)之一,如果省略target,make就將生成Makefile文件中定義的第一個(gè)目標(biāo)。對(duì)于上面Makefile的例子,單獨(dú)的一個(gè)“make”命令等價(jià)于:# m
28、ake test 因?yàn)閠est是Makefile文件中定義的第一個(gè)目標(biāo),make首先將其讀入,然后從第一行開(kāi)始執(zhí)行,把第一個(gè)目標(biāo)test作為它的最終目標(biāo),所有后面的目標(biāo)的更新都會(huì)影響到test的更新。第一條規(guī)則說(shuō)明只要文件test的時(shí)間戳比文件prog.o或code.o中的任何一個(gè)舊,下一行的編譯命令將會(huì)被執(zhí)行。 但是,在檢查文件prog.o和code.o的時(shí)間戳之前,make會(huì)在下面的行中尋找以prog.o和code.o為目標(biāo)的規(guī)則,在第三行中找到了關(guān)于prog.o的規(guī)則,該文件的依賴(lài)文件是prog.c、prog.h和code.h。同樣,make會(huì)在后面的規(guī)則行中繼續(xù)查找這些依賴(lài)文件的規(guī)則,
29、如果找不到,則開(kāi)始檢查這些依賴(lài)文件的時(shí)間戳,如果這些文件中任何一個(gè)的時(shí)間戳比prog.o的新,make將執(zhí)行“gcc c prog.c o prog.o”命令,更新prog.o文件。以同樣的方法,接下來(lái)對(duì)文件code.o做類(lèi)似的檢查,依賴(lài)文件是code.c和code.h。當(dāng)make執(zhí)行完所有這些套嵌的規(guī)則后,make將處理最頂層的test規(guī)則。如果關(guān)于prog.o和code.o的兩個(gè)規(guī)則中的任何一個(gè)被執(zhí)行,至少其中一個(gè).o目標(biāo)文件就會(huì)比test新,那么就要執(zhí)行test規(guī)則中的命令,因此make去執(zhí)行g(shù)cc命令將prog.o和code.o連接成目標(biāo)文件test。在上面Makefile的例子中,還
30、定義了一個(gè)目標(biāo)clean,它是Makefile中常用的一種專(zhuān)用目標(biāo),即刪除所有的目標(biāo)模塊。 現(xiàn)在來(lái)看一下make做的工作:首先make按順序讀取makefile中的規(guī)則,然后檢查該規(guī)則中的依賴(lài)文件與目標(biāo)文件的時(shí)間戳哪個(gè)更新,如果目標(biāo)文件的時(shí)問(wèn)戳比依賴(lài)文件還早,就按規(guī)則中定義的命令更新目標(biāo)文件。如果該規(guī)則中的依賴(lài)文件又是其他規(guī)則中的目標(biāo)文件,那么依照規(guī)則鏈不斷執(zhí)行這個(gè)過(guò)程,直到Makefile文件的結(jié)束,至少可以找到一個(gè)不是規(guī)則生成的最終依賴(lài)文件,獲得此文件的時(shí)間戳,然后從下到上依照規(guī)則鏈執(zhí)行目標(biāo)文件的時(shí)間戳比此文件時(shí)間戳舊的規(guī)則,直到最頂層的規(guī)則。 通過(guò)以上的分析過(guò)程,可以看到make的優(yōu)點(diǎn),
31、因?yàn)?o目標(biāo)文件依賴(lài).c源文件,源碼文件里一個(gè)簡(jiǎn)單改變都會(huì)造成那個(gè)文件被重新編譯,并根據(jù)規(guī)則鏈依次由下到上執(zhí)行編譯過(guò)程,直到最終的可執(zhí)行文件被重新連接。例如,當(dāng)改變一個(gè)頭文件的時(shí)候,由于所有的依賴(lài)關(guān)系都在Makefile里,因此不再需要記住依賴(lài)此頭文件的所有源碼文件,make可以自動(dòng)的重新編譯所有那些因依賴(lài)這個(gè)頭文件而改變了的源碼文件,如果需要,再進(jìn)行重新連接。 3Makefile中的變量中的變量 Makefile里的變量就像一個(gè)環(huán)境變量。事實(shí)上,環(huán)境變量在make中也被解釋成make的變量。這些變量對(duì)大小寫(xiě)敏感,一般使用大寫(xiě)宇母。幾乎可以從任何地方引用定義的變量,變量的主要作用如下: 保存文
32、件名列表。在前面的例子里,作為依賴(lài)文件的一些目標(biāo)文件名出現(xiàn)在可執(zhí)行文件的規(guī)則中,而在這個(gè)規(guī)則的命令行里同樣包含這些文件并傳遞給gcc做為命令參數(shù)。如果使用一個(gè)變量來(lái)保存所有的目標(biāo)文件名,則可以方便地加入新的目標(biāo)文件而且不易出錯(cuò)。 保存可執(zhí)行命令名,如編譯器。在不同的Linux系統(tǒng)中存在著很多相似的編譯器 系統(tǒng),這些系統(tǒng)在某些地方會(huì)有細(xì)微的差別,如果項(xiàng)目被用在一個(gè)非gcc的系統(tǒng) 里,則必須將所有出現(xiàn)編譯器名的地方改成用新的編譯器名。但是如果使用一個(gè)變量來(lái)代替編譯器名,那么只需要改變?cè)撟兞康闹怠F渌械胤降拿蠲投几淖兞恕?保存編譯器的參數(shù)。在很多源代碼編譯時(shí),gcc需要很長(zhǎng)的參數(shù)選項(xiàng),在很多
33、情況下,所有的編譯命令使用一組相同的選項(xiàng),如果把這組選項(xiàng)使用一個(gè)變量代表,那么可以把這個(gè)變量放在所有引用編譯器的地方。當(dāng)要改變選項(xiàng)的時(shí)候,只需改變一次這個(gè)變量的內(nèi)容即可。 Makefile中的變量是用一個(gè)文本串在Makefile中定義的,這個(gè)文本串就是變量的值。只要在一行的開(kāi)始寫(xiě)下這個(gè)變量的名字,后面跟一個(gè)“”號(hào),以及要設(shè)定這個(gè)變量的值即可定義變量,下面是定義變量的語(yǔ)法:VARNAME=string使用時(shí),把變量用括號(hào)括起來(lái),并在前面加上$符號(hào),就可以引用變量的值: $VARNAME make解釋規(guī)則時(shí),VARNAME在等式右端展開(kāi)為定義它的字符串。變量一般都在Makefile的頭部定義。按照
34、慣例,所有的Makefile變量都應(yīng)該是大寫(xiě)。如果變量的值發(fā)生變化,就只需要在一個(gè)地方修改,從而簡(jiǎn)化了Makefile的維護(hù)。 現(xiàn)在利用變量把前面的Makefile重寫(xiě)一遍:OBJS=prog.o code.oCC=gcc test:$ OBJS $ CC o test $ OBJS prog.o:prog.c prog.h code.h$ CC c prog.c o prog.o code.o:code.c code.h$ CC c code.c o code.o clean:rm f *.o 除用戶(hù)自定義的變量外,make還允許使用環(huán)境變量、自動(dòng)變量和預(yù)定義變量。使用環(huán)境變量的方法很簡(jiǎn)單,
35、在make啟動(dòng)時(shí),make讀取系統(tǒng)當(dāng)前已定義的環(huán)境變量,并且創(chuàng)建與之同名同值的變量,因此用戶(hù)可以像在shell中一樣在Makefile中方便的引用環(huán)境變量。需要注意的是,如果用戶(hù)在Makefile中定義了同名的變量,用戶(hù)自定義變量將覆蓋同名的環(huán)境變量。此外,Makefile中還有一些預(yù)定義變量和自動(dòng)變量,但是看起來(lái)并不像自定義變量那樣直觀。表9-3中給出了常見(jiàn)的自動(dòng)變量。 除了自動(dòng)變量外,Makefile中還有一些預(yù)定義的內(nèi)部變量,用于定義編譯命令名、編譯參數(shù)等,如表9-4所示: 4Makefile的隱含規(guī)則的隱含規(guī)則 在上面的例子中,幾個(gè)產(chǎn)生目標(biāo)文件的命令都是從“.c”的C語(yǔ)言源文件和相關(guān)文
36、件通過(guò)編譯產(chǎn)生“.o”目標(biāo)文件,這也是一般的步驟。實(shí)際上,make可以使工作更加自動(dòng)化,也就是說(shuō),make知道一些默認(rèn)的動(dòng)作,它有一些稱(chēng)作隱含規(guī)則的內(nèi)置的規(guī)則,這些規(guī)則告訴make當(dāng)用戶(hù)沒(méi)有完整地給出某些命令的時(shí)候,應(yīng)該怎樣執(zhí)行。例如,把生成prog.o和code.o的命令從規(guī)則中刪除,make將會(huì)查找隱含規(guī)則,然后會(huì)找到并執(zhí)行一個(gè)適當(dāng)?shù)拿?。由于這些命令會(huì)使用一些變量,因此可以通過(guò)改變這些變量來(lái)定制make。象在前面的例子中所定義的那樣,make使用變量CC來(lái)定義編譯器,并且傳遞變量CFLAGS(編譯器參數(shù))、CPPFLAGS(C語(yǔ)言預(yù)處理器參數(shù))、TARGET_ARCH(目標(biāo)機(jī)器的結(jié)構(gòu)定義
37、)給編譯器,然后加上參數(shù)-c,后面跟變量$(第一個(gè)依賴(lài)文件名),然后是參數(shù)-o加變量$(目標(biāo)文件名)。綜上所述,一個(gè)C編譯的具體命令將會(huì)是:$ CC $ CFLAGS $ CPPFLAGS $ TARGET_ARCH c $ -o $在上面的例子中,利用隱含規(guī)則,可以簡(jiǎn)化為:OBJS=prog.o code.oCC=gcctest:$ OBJS $ CC o $ $ prog.o:prog.c prog.h code.hcode.o:code.c code.h clean:rm f *.o 5、常用的、常用的make命令行選項(xiàng)命令行選項(xiàng) make命令有豐富的命令行選項(xiàng)。表9-5中列出了常用的部
38、分。 9.3.3 使用使用automake和和autoconf產(chǎn)生產(chǎn)生Makefile 在開(kāi)始使用Automake和autoconf之前,請(qǐng)先確認(rèn)系統(tǒng)已經(jīng)安裝以下的軟件:GNU AutomakeGNU AutoconfGNU m4Perl GNU Libtool (如果你需要產(chǎn)生 shared library) Automake 所產(chǎn)生的 Makefile 除了可以做到程序的編譯和連接,也已經(jīng)把如何產(chǎn)生程序文件的操作,以及把安裝程序都考慮進(jìn)去了,所以源程序所存放的目錄架構(gòu)最好符合GNU的標(biāo)準(zhǔn)慣例,下面用hello.c 來(lái)作為例子進(jìn)行說(shuō)明。 在工作目錄下建立一個(gè)新的子目錄devel,再在deve
39、l下建立一個(gè)hello的子目錄,這個(gè)目錄將作為存放 hello 這個(gè)程序及其相關(guān)文件的地方: 用編輯器寫(xiě)個(gè)hello.c文件:#include int main(int argc, char* argv) printf(Hello, GNU!n); return 0;接下來(lái)就要使用 Autoconf 及 Automake 來(lái)產(chǎn)生Makefile文件,步驟如下:(1)autoscan 產(chǎn)生一個(gè)configure.in的模板,執(zhí)行 autoscan 后會(huì)產(chǎn)生一個(gè)configure.scan 的文件,可以用它做為configure.in文件的模板:(2)編輯configure.scan文件,如下所示
40、,并且把文件名改成configure.in (3)執(zhí)行aclocal和autoconf ,分別會(huì)產(chǎn)生 aclocal.m4 及 configure 兩個(gè)文件:(4)編輯Makefile.am文件,內(nèi)容如下: (5)執(zhí)行automake -add-missing ,Automake 會(huì)根據(jù) Makefile.am產(chǎn)生一些文件,包含最重要的Makefile.in: (6)最后執(zhí)行 ./configure :現(xiàn)在你的目錄下已經(jīng)產(chǎn)生了一個(gè)Makefile文件,執(zhí)行make命令就可以開(kāi)始編譯hello.c 成執(zhí)行文件,最后執(zhí)行./hello:# makegcc -DPACKAGE=hello -DVER
41、SION=1.0 -I. -I. -g -O2 -c hello.cgcc -g -O2 -o hello hello.o# ./helloHello! GNU! 9.4 調(diào)試工具調(diào)試工具GDB 9.4.1 GDB調(diào)試器簡(jiǎn)介調(diào)試器簡(jiǎn)介 Linux系統(tǒng)中包含了GNU 調(diào)試程序gdb,它是一個(gè)用來(lái)調(diào)試C和 C+ 程序的調(diào)試器??梢允钩绦蜷_(kāi)發(fā)者在程序運(yùn)行時(shí)觀察程序的內(nèi)部結(jié)構(gòu)和內(nèi)存的使用情況。gdb 所提供的一些功能如下所示:運(yùn)行程序,設(shè)置所有的能影響程序運(yùn)行的參數(shù)和環(huán)境;控制程序在指定的條件下停止運(yùn)行; 當(dāng)程序停止時(shí),可以檢查程序的狀態(tài);修改程序的錯(cuò)誤,并重新運(yùn)行程序; 動(dòng)態(tài)監(jiān)視程序中變量的值; 可
42、以單步執(zhí)行代碼,觀察程序的運(yùn)行狀態(tài)。 gdb的功能非常強(qiáng)大,到目前為止,gdb已能夠支持Moduls-2、Chill、Pascal和FORTRAN程序的調(diào)試,但是調(diào)試這些語(yǔ)言的源程序時(shí)有一些功能還不能使用。例如調(diào)試FORTRAN程序時(shí)還不支持表達(dá)式的輸入、輸出變量或類(lèi)FORTRAN的詞法。 gdb程序調(diào)試的對(duì)象是可執(zhí)行文件,而不是程序的源代碼文件。然而,并不是所有的可執(zhí)行文件都可以用gdb調(diào)試。如果要讓產(chǎn)生的可執(zhí)行文件可以用來(lái)調(diào)試,需在執(zhí)行g(shù)cc指令編譯程序時(shí),加上-g參數(shù),指定程序在編譯時(shí)包含調(diào)試信息。調(diào)試信息包含程序里的每個(gè)變量的類(lèi)型和在可執(zhí)行文件里的地址映射以及源代碼的行號(hào)。gdb 利用
43、這些信息使源代碼和機(jī)器碼相關(guān)聯(lián)。 在命令行上輸入gdb并按回車(chē)鍵就可以運(yùn)行g(shù)db了,如果一切正常的話(huà),將啟動(dòng)gdb,可以在屏幕上看到以下的內(nèi)容: GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)Copyright 2003 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under c
44、ertain conditions.Type show copying to see the conditions.There is absolutely no warranty for GDB. Type show warranty for details.This GDB was configured as i386-redhat-linux-gnu.(gdb)啟動(dòng)gdb后,可以在命令行上指定很多的選項(xiàng)。輸入:help可以獲得gdb的幫助信息。如果想要了解某個(gè)具體命令(比如break)的幫助信息,在gdb提示符下輸入下面的命令:break屏幕上會(huì)顯示關(guān)于break的幫助信息。從返回的信息可
45、知,break是用于設(shè)置斷點(diǎn)的命令。另一個(gè)獲得gdb幫助的方法是瀏覽gdb的手冊(cè)頁(yè)。在Linux Shell提示符輸入:man gdb 可以看到man的手冊(cè)頁(yè)。 9.4.2 GDB命令的基本使用和應(yīng)用命令的基本使用和應(yīng)用 1gdb基本命令基本命令 還可以用下面的方式來(lái)運(yùn)行g(shù)db:gdb filename其中,filename是要調(diào)試的可執(zhí)行文件。用這種方式運(yùn)行g(shù)db可以直接指定想要調(diào)試的程序。這和啟動(dòng)gdb后執(zhí)行file filename命令效果完全一樣。也可以用gdb去檢查一個(gè)因程序異常終止而產(chǎn)生的core文件,或者與一個(gè)正在運(yùn)行的程序相連。 gdb支持很多的命令且能實(shí)現(xiàn)不同的功能。這些命令
46、從簡(jiǎn)單的文件裝入到允許你檢查所調(diào)用的堆棧內(nèi)容的復(fù)雜命令, 下面列出了在使用gdb 調(diào)試時(shí)會(huì)用到的一些命令。1)file命令:裝入想要調(diào)試的可執(zhí)行文件。 2)cd命令:改變工作目錄。 3)pwd命令:返回當(dāng)前工作日錄。 4)run命令:執(zhí)行當(dāng)前被調(diào)試的程序。 5)kill命令:停止正在調(diào)試的應(yīng)用程序。 6)list命令:列出正在調(diào)試的應(yīng)用程序的源代碼。 7)break命令:設(shè)置斷點(diǎn)。 8)Tbreak命令;設(shè)置臨時(shí)斷點(diǎn)。它的語(yǔ)法與break相同。區(qū)別在于用tbreak設(shè)置的斷點(diǎn)執(zhí)行一次之后立即消失。 9)watch命令:設(shè)置監(jiān)視點(diǎn),監(jiān)視表達(dá)式的變化。 10)awatch命令:設(shè)置讀寫(xiě)監(jiān)視點(diǎn)。當(dāng)要
47、監(jiān)視的表達(dá)式被讀或?qū)憰r(shí)將應(yīng)用程序掛起。它的語(yǔ)法與watch命令相同。 11)rwatch命令:設(shè)置讀監(jiān)視點(diǎn),當(dāng)監(jiān)視表達(dá)式被讀時(shí)將程序掛起,等侍調(diào)試。此命令的語(yǔ)法與watch相同。 12)next命令:執(zhí)行下一條源代碼,但是不進(jìn)入函數(shù)內(nèi)部。也就是說(shuō),將一條函數(shù)調(diào)用作為一條語(yǔ)句執(zhí)行。執(zhí)行這個(gè)命令的前提是已經(jīng)run,開(kāi)始了代碼的執(zhí)行。 13)step命令:執(zhí)行下一條源代碼,進(jìn)入函數(shù)內(nèi)部。如果調(diào)用了某個(gè)函數(shù),會(huì)跳到函數(shù)所在的代碼中等候一步步執(zhí)行。執(zhí)行這個(gè)命令的前提是已經(jīng)用run開(kāi)始執(zhí)行代碼。 14)display命令:在應(yīng)用程序每次停止運(yùn)行時(shí)顯示表達(dá)式的值。15)info break命令:顯示當(dāng)前斷點(diǎn)
48、列表,包括每個(gè)斷點(diǎn)到達(dá)的次數(shù)。 16)info files命令:顯示調(diào)試文件的信息。 17)info func命令:顯示所有的函數(shù)名。 18)info local命令:顯示當(dāng)前函數(shù)的所有局部變量的信息。 19)info prog命令:顯示調(diào)試程序的執(zhí)行狀態(tài)。 20)print命令;顯示表達(dá)式的值。 21)delete命令:刪除斷點(diǎn)。指定一個(gè)斷點(diǎn)號(hào)碼,則刪除指定斷點(diǎn)。不指定參數(shù)則刪除所有的斷點(diǎn)。 22)Shell命令:執(zhí)行Linux Shell命令。 23)make命令:不退出gdb而重新編譯生成可執(zhí)行文件。 24)Quit命令:退出gdb。 2gdb應(yīng)用實(shí)例應(yīng)用實(shí)例 下面使用gdb調(diào)試程序來(lái)調(diào)
49、試一個(gè)實(shí)例。被調(diào)試的程序相當(dāng)?shù)暮?jiǎn)單, 但展示了gdb的典型應(yīng)用。下面列出了將被調(diào)試的程序代碼,這個(gè)程序被稱(chēng)為greeting.c , 功能是顯示一個(gè)簡(jiǎn)單的問(wèn)候, 再用反序?qū)⑺谐觥?9.5 使用使用RCS/CVS來(lái)管理源代碼來(lái)管理源代碼 9.5.1 RCS的使用的使用 RCS(Revision Control System)即程序改版控制系統(tǒng),主要功能是用來(lái)管理文件的版本,可以節(jié)省空間和時(shí)間。這樣就不需要在每個(gè)程序開(kāi)發(fā)到某一個(gè)階段就將數(shù)據(jù)拷貝到其他的地方備份起來(lái)了。RCS提供了如下幾個(gè)最重要的指令的: ci指令:將文件放入RCS目錄下的控制系統(tǒng) co指令:從RCS目錄下將文件取出 rcs指令:
50、用來(lái)對(duì)RCS文件進(jìn)行參數(shù)的設(shè)置 1基本操作方式基本操作方式 一般而言,RCS所產(chǎn)生出來(lái)的文件會(huì)放在RCS目錄中。所以第一步必須要在當(dāng)前的目錄下制作一個(gè)文件:rootwyh linux# mkdir RCS接下來(lái)只要使用ci指令。就可以把文件備份到RCS改版控制系統(tǒng)中: rootwyh linux# ci test.c 若要將文件取出,可以使用下列指令: rootwyh linux# co test.c 取出來(lái)的文件是只讀文件,若要取出可以寫(xiě)入的工作文件,可以加上-l參數(shù)來(lái)鎖定它:rootwyh linux# co -l test.c 此外將文件放入RCS控制系統(tǒng)時(shí),可以使用-l參數(shù)鎖定文件,那
51、么目錄下的文件依然存在: rootwyh linux# ci -l test.c 若要比較當(dāng)前的文件和RCS中最新版本的文件,可以使用下列指令:rootwyh linux# rcsdiff test.c 2指定版本指定版本 若不指定版本編號(hào)時(shí),co會(huì)從RCS取得最新的版本。如果要以特定的版本號(hào)碼寫(xiě)入RCS或讀出,可以使用-r參數(shù)選項(xiàng)。rootwyh linux# ci -l -r3.25 test.c-以3.25作為版本編號(hào) rootwyh linux# co -l -r1.2 test.c-將RCS中1.2版的test.c讀出 此外,rcsdiff也可以用來(lái)指定任何一個(gè)版本和當(dāng)前程序代碼進(jìn)行
52、比較。rootwyh linux# rcsdiff -r3.25 test.c-取出3.25版與test.c進(jìn)行比較 3關(guān)鍵詞的使用關(guān)鍵詞的使用 在RCS中可以將關(guān)鍵詞變量放入程序代碼中。這些變量經(jīng)過(guò)RCS會(huì)變成版本的注解。用戶(hù)可以將這些關(guān)鍵詞說(shuō)明當(dāng)作是程序中的批注。常用的關(guān)鍵詞如下:$Author$:將版本放入RCS的用戶(hù)名稱(chēng)。$Data$:記錄程序代碼放入RCS時(shí)的日期和時(shí)間。$Header$:記錄文件的標(biāo)頭,包括RCS路徑名稱(chēng)、版本號(hào)碼、日期、作者等。$ID$:和$Header$相同,但不包括RCS路徑名稱(chēng)。$Locker$:記錄鎖定本版本的用戶(hù)名稱(chēng)。$Log$:記錄將RCS鎖住的時(shí)間,
53、所輸入的文本語(yǔ)句。$RCSfiles$:記錄RCS文件名稱(chēng)。$Rivision$:指定版本號(hào)碼。$Source$:RCS文件名稱(chēng),包括其路徑。$State$:使用-s選項(xiàng)所指定的特殊狀態(tài)。 使用關(guān)鍵詞的步驟如下所示:(1)在程序代碼中加入任一關(guān)鍵詞 rootwyh linux#vi test.c (2)將程序代碼放入RCS版本控制系統(tǒng) rootwyh linux# ci -l test.c (3)將文件再次取出。在取出的過(guò)程中,co會(huì)將每個(gè)關(guān)鍵詞展開(kāi)成其對(duì)應(yīng)的值 rootwyh linux# co -l test.c rootwyh linux# cat test.c 9.5.2 CVS的使用
54、的使用 CVS(Concurrent Version System)是個(gè)版本控制系統(tǒng),利用該系統(tǒng)可以記錄源代碼文件的歷史。例如,當(dāng)軟件修改時(shí)會(huì)產(chǎn)生Bug,并且可能在做這次修改后很長(zhǎng)時(shí)間不會(huì)發(fā)現(xiàn)這些問(wèn)題。使用CVS就可以容易地回顧老的代碼版本去發(fā)現(xiàn)哪一次的修改導(dǎo)致這些問(wèn)題。如果CVS保留每一次的代碼版本,會(huì)浪費(fèi)很多的空間。因此CVS使用一種比較聰明的辦法保存多個(gè)版本在一個(gè)文件中。它僅僅保留版本間的不同內(nèi)容。如果很多人在同一個(gè)項(xiàng)目上工作,則CVS使用讓不同開(kāi)發(fā)者獨(dú)立工作的方式解決了這個(gè)問(wèn)題。每一個(gè)開(kāi)發(fā)者的工作都在他自己的目錄內(nèi),并且CVS將在每個(gè)開(kāi)發(fā)者的工作完成后進(jìn)行合并工作。在Linux下,CV
55、S的使用一般是以命令行方式。通常,CVS有兩種使用方式,一是本機(jī)方式,一是遠(yuǎn)程執(zhí)行方式。CVS的命令格式是:cvs cvs的選項(xiàng) cvs的動(dòng)作 選項(xiàng) 讀者可以用cvs H command列出命令command的使用方法。 1開(kāi)始項(xiàng)目開(kāi)始項(xiàng)目 用CVS管理代碼,首先要?jiǎng)?chuàng)建一個(gè)“信息倉(cāng)庫(kù)”?!靶畔}(cāng)庫(kù)”簡(jiǎn)單來(lái)說(shuō)包含一個(gè)目錄結(jié)構(gòu)。它包括要管理的源代碼和用于管理源代碼的各種管理文件。 先設(shè)置環(huán)境變量CVSROOT,指向信息倉(cāng)庫(kù)的絕對(duì)路徑,然后調(diào)用CVS的init命令:# CVSROOT=/usr/local/cvsroot;export CVSROOT# cvs init # ls -l $CVSRO
56、OT 2添加項(xiàng)目的文件、目錄到信息倉(cāng)庫(kù)添加項(xiàng)目的文件、目錄到信息倉(cāng)庫(kù) 要將需要管理的項(xiàng)目的文件加入到信息倉(cāng)庫(kù),并做上標(biāo)志。如果從頭開(kāi)始一個(gè)新的項(xiàng)目,就需要?jiǎng)?chuàng)建一個(gè)單獨(dú)的目錄,并把所有要使用的文件做一個(gè)有效的組織。而如果在開(kāi)始使用源文件之前該目錄就已經(jīng)存在,則只需進(jìn)入該目錄就行了。然后,就可以輸入源文件目錄: # cvs import -m Create Source Dir cvstest/c wu cvstest 這樣會(huì)生成 $CVSROOT/cvstest/c 目錄。 其中-m用來(lái)指定注釋信息,如果后面在命令行不指定注釋信息,則會(huì)啟動(dòng)缺省編輯器(vi)要求輸入注釋信息;cvstest/c是
57、項(xiàng)目名稱(chēng)(實(shí)際上是倉(cāng)庫(kù)名,在CVS服務(wù)器上會(huì)存儲(chǔ)在以這個(gè)名字命名的倉(cāng)庫(kù)里);wu, cvstest分別標(biāo)識(shí)了作者和發(fā)行標(biāo)識(shí)。 3命令簡(jiǎn)介命令簡(jiǎn)介 (1)導(dǎo)出源文件 cvs checkout -r rev-D date-d dir-j merg1 -j merg2 modules -r 導(dǎo)出指定版本的模塊 -D 導(dǎo)出指定日期的模塊 -d 導(dǎo)出指定目錄而不是模塊 -j 合并當(dāng)前版本和指定版本 使用下面的命令會(huì)導(dǎo)出剛才生成的模塊,并在當(dāng)前目錄下生成與文件倉(cāng)庫(kù)中完全一樣的目錄結(jié)構(gòu): # cvs checkout cvstest/c 對(duì)于目錄結(jié)構(gòu)比較復(fù)雜的模塊可以在 $CVSROOT/CVSROOT/m
58、odules中加以指定: # cvs checkout CVSROOT/modules 在modules文件中加入下面一行: SOURCE cvstest/c 然后執(zhí)行: # cvs commit m “Add SOURCE” 以后就可以使用下面的命令在當(dāng)前路徑下生成cvstest/c目錄 # cvs checkout SOURCE 在當(dāng)前路徑下生成的這個(gè)目錄就被稱(chēng)為工作目錄,對(duì)源文件的所有修改都應(yīng)該在這個(gè)目錄下完成,而絕對(duì)不允許去改動(dòng)在文件倉(cāng)庫(kù)中$CVSROOT 目錄下的文件。 (2)刪除、增加、重命名文件和目錄 cvs add -k kflags-m message files. -k 指
59、定以后該文件的缺省導(dǎo)出目錄 -m 對(duì)文件的描述 上述命令會(huì)加入一個(gè)新的文件到文件倉(cāng)庫(kù)里,但直到使用了提交命令它才會(huì)真正更新文件倉(cāng)庫(kù)。 cvs remove options files 上述命令會(huì)從文件倉(cāng)庫(kù)中刪除文件,但也要到提交之后才有作用。 (3)提交源文件 cvs commit -Rl-m mesg files-R 連子目錄一起提交-l 只提交本地目錄(不提交子目錄)-m 注釋信息在導(dǎo)出源文件之后,在工作目錄中對(duì)源文件進(jìn)行的所有修改都必須在提交之后才能對(duì)文件倉(cāng)庫(kù)中的源文件起作用,并且新的文件才能夠被分配一個(gè)新的版本號(hào)。 (4)釋放工作目錄 cvs release d SOURCE 這個(gè)命令
60、會(huì)刪除工作目錄 cvstest/c(建議在提交了修改的模塊后執(zhí)行這一步),比使用 rm rf cvstest 要好。 4多用戶(hù)開(kāi)發(fā)多用戶(hù)開(kāi)發(fā) 在多用戶(hù)的情況下,如果不同用戶(hù)修改的是同一個(gè)文件的不同部分,則使用下面的命令就能進(jìn)行版本合并(把檢出的文件與當(dāng)前的最新版本合并): # cvs update (1)沖突解決 在有多個(gè)用戶(hù)對(duì)同一個(gè)文件進(jìn)行修改時(shí),如果修改了其中的相同部分,而修改后的內(nèi)容如果有不同的話(huà),出現(xiàn)沖突是不可避免的。如果在CVS 文件倉(cāng)庫(kù)中有一個(gè)文件 test.c ,它的版本是1.4,用戶(hù)A 先檢出該文件進(jìn)行修改,而稍后有用戶(hù)B檢出該文件進(jìn)行修改,并提前提交成 1.5,而在用戶(hù)A再提交時(shí)就會(huì)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度園林景觀綠化工程養(yǎng)護(hù)管理合同匯編3篇
- 2025版醫(yī)療機(jī)構(gòu)護(hù)士規(guī)范化培訓(xùn)及勞動(dòng)合同3篇
- 2025年度個(gè)人對(duì)個(gè)人小額消費(fèi)貸款合同書(shū)2篇
- 二零二五年度網(wǎng)絡(luò)安全風(fēng)險(xiǎn)評(píng)估與治理合同集3篇
- 2025年度留學(xué)簽證逾期處理合同4篇
- 2025年機(jī)動(dòng)車(chē)質(zhì)押借款合同解除及賠償條款3篇
- 二零二五年度零食店收銀員食品安全責(zé)任承諾合同4篇
- 二零二五年度大型工業(yè)鍋爐設(shè)備采購(gòu)合同2篇
- 2025年度塔吊操作人員勞務(wù)派遣及技能培訓(xùn)合同
- 二零二五年度企業(yè)項(xiàng)目管理培訓(xùn)服務(wù)合同標(biāo)準(zhǔn)3篇
- 電化學(xué)儲(chǔ)能電站安全規(guī)程
- 幼兒園學(xué)習(xí)使用人民幣教案教案
- 2023年浙江省紹興市中考科學(xué)真題(解析版)
- 語(yǔ)言學(xué)概論全套教學(xué)課件
- 大數(shù)據(jù)與人工智能概論
- 《史記》上冊(cè)注音版
- 2018年湖北省武漢市中考數(shù)學(xué)試卷含解析
- 測(cè)繪工程產(chǎn)品價(jià)格表匯編
- 《腎臟的結(jié)構(gòu)和功能》課件
- 裝飾圖案設(shè)計(jì)-裝飾圖案的形式課件
- 護(hù)理學(xué)基礎(chǔ)教案導(dǎo)尿術(shù)catheterization
評(píng)論
0/150
提交評(píng)論