12-軟件開發(fā)工具_第1頁
12-軟件開發(fā)工具_第2頁
12-軟件開發(fā)工具_第3頁
12-軟件開發(fā)工具_第4頁
12-軟件開發(fā)工具_第5頁
已閱讀5頁,還剩89頁未讀 繼續(xù)免費閱讀

付費下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第二章 軟件開發(fā)工具 操作系統(tǒng) 陸松年 12.1 文本編輯器vi vi 文件通常一次只編輯一個文件。如果指定的文件不存在,vi就為你創(chuàng)建一個。如果不指定文件名,則必須在退出vi時指定存入的文件。在編輯一個已存在的文件時,vi將磁盤中文件的內(nèi)容拷貝至內(nèi)存編輯緩沖區(qū),所有的輸入、修改等操作都僅對編輯緩沖區(qū)內(nèi)的數(shù)據(jù)起作用,只有當要求vi寫入文件時,才用編輯緩沖區(qū)的內(nèi)容替換原文件的內(nèi)容。 12.1.1 vi 概要 Vi的基本工作方法vi有兩種基本工作方法,一種是輸入方法,另一種是命令方式。在輸入方式,用戶鍵入的任何內(nèi)容都插到編輯緩沖區(qū),直到按下ESC鍵才退出輸入方式,回到命令方式。在命令方式,用戶鍵入

2、的內(nèi)容作為命令解釋,以執(zhí)行vi提供的幾十條編輯功能。一種特殊的命令方式是底行命令方式,即在輸入命令:時,該字符連同光標移到了屏幕的底行,在該行上可執(zhí)行一切行編輯命令。12.1.2 屏幕編輯命令 (一)移動光標命令 1. 以字符為單位移動(包括垂直方向) 在命令狀態(tài)下光標控制鍵、 使用一些單字母的命令來移動光標: h 光標左移一個字符單位 j 光標下移一個字符單位 k 光標上移一個字符單位 l 光標右移一個字符單位 w 光標移到下一字的首字符處 3. 行首尾移動 0 光標移到當前行行首(第一列) 光標移到當前行中第一個 非空白字符處 $ 光標移到當前行行尾 4. 以行為單位移動 n RETURN

3、 光標下移n行 G 光標移到文件尾 2. 以字、句子、段落為單位移動 5. 以屏幕為單位移動 要使光標快速地在垂直方向移動以瀏覽或處理文件可以使用以下命令: H (Hight) 光標移到屏幕頂部 M (Middle) 光標移到屏幕中部 L (Low) 光標移到屏幕底部 以下命令使得編輯緩沖區(qū)數(shù)據(jù)在屏幕上“滾動”,而光標在屏幕上的相對位置并不改變: F (Fowlow) 下移一屏 B (Back) 上移一屏 (二)輸入方式 i(或a) 在光標之前(或之后)插入 o(或O) 在當前行下(或上)面插入在輸入過程中,你如果打錯了一個或多個字符,可以用BACKSPACE(或DELETE)鍵刪除它們。注意

4、,在一些終端上,插入過程中不要使用 、鍵(在命令行輸入命令時也一樣)。在刪除了這些字符后,你可以接著輸入正確的數(shù)據(jù),新輸入的字符,將覆蓋被刪字符。 (三)刪除命令 在用戶輸入數(shù)據(jù)并用ESC鍵退出了插入狀態(tài)回到了命令狀態(tài)后,就可以用刪除、修改等命令修改正文。刪除命令主要有以下幾個: x 刪除光標位置的一個字符 dw 刪除光標位置的一個字 d$(或D) 刪除自光標到本行未間的正文 dd 刪除當前行 dG 從當前行一直刪到最后一行 d1G 從當前行一直刪到第一行 大部分的刪除命令都可帶有重復(fù)數(shù),如 10 x 刪除自光標位置起的10個字符 d5w 刪除自光標位位置起的5個字(四)修改命令 1. 一對一

5、的字符替換(replace) r 字符 替換光標所在字符,如 ra 用字符a替換光標所在字符 3rabc 用abc三個字符替換自光標起的三個字符 R輸入串 用輸入串一對一地替換自光標位置起的任意多個字符,直至按ESC鍵 2. 替換指定數(shù)目的字符和行(substitude) s 替換指定數(shù)目的字符,如 3sxyz 用xyz替換光標開始處的三個字符,按ESC鍵退出替換,但輸入部可以多于3個字符,也可少于3個字符。 (五)緩沖區(qū)與刪除、抽取、放置命令 1. 通用緩沖區(qū)vi編輯程序有一個通用緩沖區(qū)和26個有名緩沖區(qū)。所有的刪除命令還把被刪正文置入通用緩沖區(qū)。用戶可以用p(put)命令將通用緩沖區(qū)的內(nèi)容

6、取出放置到指定位置,故用刪除命令和放置命令的組合可以實現(xiàn)把編輯緩沖區(qū)中的數(shù)據(jù)從一個位置搬移到另一個位置。例如:d5w命令刪去光標所處位置起的五個字,并把刪去的5個字置入通用緩沖區(qū)。將光標移動到新的位置后用p命令可使這5個字插到新的位置上。又如:先執(zhí)行3dd命令,將光標移到指定行后再執(zhí)行p命令就把原光標所在位置起的三行正文搬到了新的位置。 如果用戶不想刪去正文就可以使用y(yank)命令。用y命令和p命令的組合可以實現(xiàn)數(shù)據(jù)的拷貝。如使用命令 2yy 抽取當前行及下一行,將光標移到新的位置后用p命令把這二行拷貝至新的當前行之后。類似地y3w抽取3個字,而4y3w則抽取12個字。 (六)其他命令 u

7、 廢除上一條命令所做的修改 . 重復(fù)執(zhí)行上一個命令 12.1.3底行命令 在vi命令狀態(tài)下,鍵入/,?或:,光標就跳到屏幕的最底行,在該行可以輸入對文件操作的命令。 (一)搜索命令當用戶鍵入了/后,vi在最底行(命令行)顯示字符/和光標,接下來就可以鍵入查找模式了??梢杂谜齽t表達式指定模式。用/命令查找模式時,從當前的光標位置向下查找匹配模式的第一個字符串,光標停留在該字符串的第一個字符上。 ?命令是/命令的反向搜索方式。使用n(next)命令,用戶不必輸入模式就可以按原方向繼續(xù)上一次的查找。使用N命令則按反方向繼續(xù)查找。例: / mae.*y 查找一個字的首部含有mae.*y模式的串。該模式

8、將匹配many,may,merry等單詞。(二)字符串替代 :地址 s/模式/替代串/gcp ,例: :s/a lot of/ 在替代之前請求確認,可以再加上c :s/UNIX/Unix/cg要刪除指定模式的串,可將替代串部分置為空: :s/Sae*ing/gp字符串替代命令中如不指定地址部分,則僅對當前行執(zhí)行替換,否則替代命令在指定的地址范圍內(nèi)執(zhí)行。地址部分格式舉例如下: 地址 搜索范圍 15 第15行 5,15 從第5行至第15行 1,. 從第1行至當前行 .,$ 從當前行至最后一行 .,+25 從當前行至當前行后25行 1,$ 文件中的全部行 例: :1,$s/ten/10/g 在整個文

9、件中用字符串10替代字符串ten,即: ten-10, often-of10, tenant-10ant :1,$s/10/g 僅對單詞ten替換成10 (三)行編輯命令 刪除命令 :地址d 刪除地址部分指定的文件行, 如不指定地址,則只刪除當前行。如 :.,-10d 刪去當前行至當前行上面10行(共11行) 行移動:地址m單地址 將地址部分指定的文件行移到起始地址為單地址的地方。 例:10m20 將第10行移到第20行之下 (四)讀寫文件 讀文件命令的模式為 :單地址r文件 將文件中內(nèi)容插到指定的地址位置后,地址缺省為當前行,例: :$r myfile 將文件myfile中全部內(nèi)容插到編輯文

10、件尾。 寫文件的格式為 :地址w文件 如不指定地址,則將整個編輯緩沖區(qū)寫入文件; 如不指定文件,則將緩沖區(qū)數(shù)據(jù)寫入調(diào)用vi指定的原文件; 如指定的文件已在,而你確實想覆蓋它,可用w!file命令。 隔一段時間打一下w命令較為安全。還可使用添加寫的命令,如 :wfile 將編輯文件添加到磁盤文件file的后面。 :10,20wexample 將第10行至第20行添加到文件example之后如果用戶曾在vi中修改過正文,則先要執(zhí)行:w命令將編輯文件盤后才能用:q命令退出vi,或直接執(zhí)行保存文件后退出vi的命令 :wq不存盤而強制退出的命令為 :q! (六)設(shè)置參數(shù)命令 :set nu(mber)

11、在每一文件行前面顯示行號 :set nonu(mber) 取消行號,所有的設(shè)置命令都可以在參數(shù)前加上“no”取消。 屏幕上顯示的行號在編輯緩沖區(qū)中是不存在的,故在存盤時不會把行號存入文件中。 12.1.4 在vi程序中執(zhí)行shell命令 :! shell命令在shell命令執(zhí)行完成后,按RETURN返回vi。利用在vi中執(zhí)行shell命令的功能可使用戶在編寫、調(diào)試源程序不必經(jīng)常要進出vi。源程序輸入完成后先用:w命令存盤,然后在vi中執(zhí)行編譯程序,如 !cc %命令中%代表當前文件名,如果你的系統(tǒng)不支持%,也可用 “!cc 源文件”或“ !cc 源文件 -o目標文件” 命令。記下編譯時的出錯信

12、息,按RETURN返回到vi中去修改。 最基本的vi命令 vi filename.ci(或a) 在光標之前(或之后)插入o(或O) 在當前行下(或上)面插入BACKSPACE(或DELETE)鍵刪除ESC鍵退出插入狀態(tài) h 光標左移一個字符單位 j 光標下移一個字符單位 k 光標上移一個字符單位 l 光標右移一個字符單位 0 光標移到當前行行首(第一列) $ 光標移到當前行行尾保存文件后退出vi F (Fowlow) 下移一屏 B (Back) 上移一屏 x 刪除光標位置的一個字符dd 刪除當前行ra 用字符a替換光標所在字符nsstr 用str替換光標開始處的n個字符nyy 將n行數(shù)據(jù)拷貝至

13、緩沖區(qū)p 把緩沖區(qū)行拷貝至新的當前行之后 u 廢除上一條命令所做的修改:set nu(mber) 在文件行前面顯示行號 :set nonu(mber) 取消行號 /str 搜索指定模式的字符串str:地址 s/模式/替代串/g 對字符串進行替換:w file 則將整個編輯緩沖區(qū)寫入文件:! shell命令 在vi程序中執(zhí)行shell命令:wq 保存文件后退出vi:q! 不保存文件退出vi 12.2 C編譯系統(tǒng) cc是UNIX系統(tǒng)中的c語言編譯程序,它能完成宏擴展、文件包括、編譯、優(yōu)化、匯編連接和裝入等多種功能。 cc編譯命令的一般形式是: cc 選項 源程序和目標代碼文件表 -l庫. 12.2

14、.1 C編譯基本過程 2. 編譯選項 影響cc編譯階段的選項是: -g 調(diào)試選項。這個選項使得編譯程序在最終的可執(zhí)行目標文件中包含附加的關(guān)于變量和源程序語句的信息,這些信息對于運行符號調(diào)試程序sdb是必須的。 -O 優(yōu)化選項。該選項調(diào)用外加的編譯步驟優(yōu)化程序,以生成更有效的代碼。12.2.5 連接裝入程序 掃描命令行中的目標文件和庫文件參數(shù) libc.a: 標準c函數(shù)庫,當cc生成二進制可執(zhí)行文件時自動搜索該庫。 libm.a: 數(shù)學函數(shù)庫。 libplot.a 繪圖子程序庫。連接/裝入選項 -o name 該選項使得最后生成的二進制可執(zhí)行代碼存入名為name的文件中,如不用-o選項,則存入名

15、為a.out的文件中。 -lx 這個選項是檔案庫名/lib/libx.a的縮寫。如果該檔案庫不存在,ld程序再看/usr/lib/libx.a。庫名參數(shù)x不限于單個字符,它可以是一個字符串。 -Ldir 當用-lx指定檔案庫時,先在-L選項中指出的dir目錄中查找檔案庫, 再到/lib和/usr/lib中查找。 12.2.6 一個使用cc的綜合例子 cc -Ddebug -O example.c more.c io.s unit.o -o example -lm cc首先調(diào)用預(yù)處理程序,將源程序中說明的頭文件包含進來,并將標識符debug的值置為1,處理有關(guān)條件編譯的事務(wù);然后調(diào)用編譯程序,生

16、成example.c,more.c的匯編語言目標程序example.s和more.s,并對它們進行優(yōu)化;再調(diào)用匯編程序生成目標代碼example.o、more.o和io.o;最后調(diào)用連接/裝入程序?qū)c生成的目標代碼,參數(shù)表中列出的目標代碼和數(shù)學庫中的一些檔案文件連接起來,對它們進行重定位,并生成可執(zhí)行的二進制文件example。12.3 庫的維護 12.3.1 庫的概念 一個庫文件是由一組文件通過運行ar庫維護程序構(gòu)成的,多數(shù)庫文件是目標文件的集合。如C的標準庫文件/lib/libc.a中就含有C的標準子程序及系統(tǒng)調(diào)用的全部目標文件。這些目標文件是由編譯相應(yīng)的.c文件集合而得到的。 按約定,

17、庫文件名字以lib開頭,以.a為后綴。庫文件與目標文件的差異盡管庫文件與目標文件很相似,但是它們之間還是有關(guān)鍵的差異。當用戶把幾個目標文件連接成一個大程序時,這些目標文件中所有的內(nèi)容都成為最終的可執(zhí)行程序的一部分,根本不管你是否使用了其中的代碼。當編譯程序連接庫的時候,用戶在源程序要用到什么函數(shù),編譯程序就將庫中對應(yīng)的函數(shù)連接到用戶的程序中。連接/裝入程序把從庫中取出的目標代碼文件的符號表和二進制制可執(zhí)行文件的符號表合并起來。12.3.2 庫的維護 1. 創(chuàng)建新檔案庫或把文件加到現(xiàn)存檔案庫中這是一個最重要的庫管理程序。 ar rv 庫名 目標文件表如將目標文件filea.o,fileb.o,f

18、ilec.o加入庫文件libfile.a中可用命令 ar rv libfile.a filea.o fileb.o filec.o也可利用模式生成文件名: ar rv libfile.a filea-c.o ar新建立包含這三個目標文件的庫。與很多的UNIX系統(tǒng)程序不一樣,ar的選項(rv)的前面沒有,但這不會造成二義性,因為ar程序至少要求一個選項。選項r表示將指定的文件加入庫中,必要時創(chuàng)建庫文件。如果庫中已有要加入的文件,則這個文件被新文件所代替。選項v表示詳細(verbose)方式,使ar將每一完成的操作都顯示出來。ar會自動地產(chǎn)生與目標文件外部符號名有關(guān)的符號表。 2. 列出庫中的文件

19、 這也是一個常用的命令,其格式為: ar tv 庫 文件表如指定文件表參數(shù),則只列出這些文件。當選項v與t一起使用時,列出文件的詳細描述,這類似于ls -l命令的l選項。如命令: ar tv libfile.a以詳細方式按序列出庫文件libfile.a中的所有文件。3. 從庫中提取文件(extract) ar x libfile.a fileb.o 從庫中提取fileb.o,存放在當前目錄下。該操作不改變庫的內(nèi)容。如果不提供目標文件名,則提取庫中所有的文件。一般說,提取源代碼或正文的檔案要比提取目標代碼的檔案用的更普遍。如選項v與x一起使用,則詳細方式 12.3.3 動態(tài)庫 前面介紹的庫稱為靜

20、態(tài)庫。在編輯、連接程序時,編譯程序?qū)⒂脩舫绦蛞{(diào)用的庫函數(shù)全部連接到用戶的程序中,組合成一個完整的不可分割的執(zhí)行代碼。在運行時,用戶程序就與原庫脫離了聯(lián)系。如果有若干的應(yīng)用程序要調(diào)用相同的庫函數(shù),那么各個應(yīng)用分別都要把庫中有關(guān)的函數(shù)連入自己的程序庫中,這些冗余的代碼極大地增加了程序的長度,平時要消耗較多的磁盤存儲空間,這些應(yīng)用同時運用時也要占用較大的內(nèi)存空間。動態(tài)庫的原理 動態(tài)庫的原理類似于共享代碼段,當用戶在編譯行中指定庫時,編譯程序并不將動態(tài)庫中的函數(shù)連入用戶的程序中,而只建立了對動態(tài)庫的引用連接,因此所生成的目標代碼長度要比使用靜態(tài)庫時小得多。在實際裝入運行時,系統(tǒng)根據(jù)用戶程序中的引用連

21、接信息,再把動態(tài)庫從盤中調(diào)入內(nèi)存。當有若干程序要使用同一個動態(tài)庫時,系統(tǒng)只要在內(nèi)存中駐留該動態(tài)庫的一個副本,各個調(diào)用程序共享同一個庫的代碼,這樣大大減小了系統(tǒng)中執(zhí)行代碼的總長度,也使更多的用戶程序可以并發(fā)地運行。從另一方面講,如果系統(tǒng)中只有一個程序要使用庫,那么采用動態(tài)庫的方式比起采用靜態(tài)庫的方式非但不能減少執(zhí)行代碼的總長度,反而可能增加其長度。因為在連接靜態(tài)庫時,系統(tǒng)只把用戶要調(diào)用的庫函數(shù)連入程序中。而在連接動態(tài)庫時,盡管所生成的目標代碼中不包含庫中的函數(shù)代碼,但在執(zhí)行時系統(tǒng)卻要把整個動態(tài)庫度都調(diào)入內(nèi)存(在虛擬存儲管理系統(tǒng)中只要部分調(diào)入即可),而不管是否要用到庫中的全部函數(shù)。由靜態(tài)庫生成對應(yīng)

22、的動態(tài)庫 方法是先從靜態(tài)庫中抽出所有的目標代碼(以.o為后綴),再由這些目標代碼組合而生成動態(tài)庫。在一個不含其他目標代碼的臨時目錄中,可通過執(zhí)行以下命令產(chǎn)生動態(tài)庫libisode.so: ar x libisode.a ld -G *.o -o libisode.so 12.4 維護程序的程序Make 多數(shù)的程序設(shè)計項目包含了大量的程序或模塊。當系統(tǒng)要修改或增強功能時,這些源程序要經(jīng)歷各種變化,對一個源程序的改動就會使本模塊或其他模塊不能照原樣工作。在大型軟件開發(fā)項目中,要跟蹤所有文件的變化是非常困難的。如果沒有Make,在修改了一些文件后為了安裝新的程序版本,所有的源程序都要重新編譯和連接,

23、否則將有很大的風險,因為要判斷哪些程序才真正需要重新編譯和連接是一個繁瑣而乏味的過程。Make的功能Make根據(jù)一些說明和文件的修改時間自動地維護模塊間的關(guān)系。說明規(guī)定了模塊之間的依賴關(guān)系以及為更新目標文件必須執(zhí)行的動作或命令。Make的說明是存放在makefile或Makefile中的。Makefile定義程序是由哪些文件構(gòu)成的,并用依賴性表示文件之間的相互聯(lián)系。Make的主要責任是重新編譯任何最近一次編譯以后又已修改過的源文件以及任何依賴于其他已改變模塊的源文件。只有依賴的文件修改或更新以后,而被依賴的目標文件還沒有被更新,換句話說,目標文件已經(jīng)“過時”了,就用跟隨著依賴行后的構(gòu)造命令更新

24、目標文件。12.4.1 Make使用初步 如有一個網(wǎng)絡(luò)程序network,它是由編譯二個源程序subnet.c和service.c而生成的。二個源程序都包含一個公共的頭文件netdefs.h,它們之間的關(guān)系見圖11-2。 頭文件 netdefs.h 預(yù)處理 源程序文件 subnet.c service.c 編譯 目標代碼文件 subnet.o service.o 連接 可執(zhí)行代碼文件 network 圖11-2 一個示例軟件系統(tǒng)的關(guān)系圖Make的依賴關(guān)系在Makefile中,以非TAB符開始有冒號的一行描述文件的依賴關(guān)系,稱為依賴行。冒號左邊的文件是目標文件,冒號右邊的文件是目標文件所依賴的文

25、件或預(yù)需的文件。依賴行下面以至少一個TAB符開始的若干行描述了一組動作,即當依賴行冒號右邊的文件得到更新從而使得左邊的目標文件已“過時”后,就執(zhí)行依賴行下面各個動作行所描述的一系列UNIX命令。在目標文件右面的依賴也可以為空,在依賴文件為空的情況下,該依賴行下面的命令就無條件地執(zhí)行。 network的依賴關(guān)系與動作對于本例,因為程序network依賴于兩個目標代碼文件subnet.o和service.o,故只要這兩個目標代碼文件中的任一個在生成了執(zhí)行程序network之后又得到了更新,程序network就過時了,應(yīng)當重新連接subnet.o和service.o,以生成network的新版本。這

26、樣的依賴關(guān)系與動作在Makefile中可表示為: network: subnet.o service.o cc -o network subnet.o service.o類似地,subnet.o依賴于subnet.c,又由于subnet.c中含有一個包含netdefs.h文件的編譯控制行,所以編譯時的正文實際來自于兩個文件:subnet.c和netdefs.h。只要在生成subnet.o之后對這兩個文件中任何一個又進行了更新,就要重新編譯subnet.c以生成更新版本的subnet.o。這樣的依賴關(guān)系與動作在Makefile中表示為: subnet.o: subnet.c netdefs.h

27、cc -c subnet.c綜合起來,對于圖11-2所示的軟件系統(tǒng),維護network程序的說明文件Makefile全部的依賴行和動作為: network: subnet.o service.o cc -o network subnet.o servie.o subnet.o: subnet.c netdefs.h cc -c subnet.c service.o:service.c netdefs.h cc -c service.c 依賴說明可以嵌套,依賴行上的依賴文件可以是其他依賴行上的目標文件,這樣就構(gòu)成了系統(tǒng)內(nèi)部各文件層次狀的依賴關(guān)系。如用戶新改動了netdefs.h,以后執(zhí)行命令ma

28、ke network,Make從“network:”這一依賴行開始自頂向下遍歷以network為根的依賴關(guān)系樹,由底向上考察每一個依賴行,并根據(jù)文件更新時間執(zhí)行相應(yīng)動作。由于每一個模塊都依賴于頭文件netdefs.h,因此Make將依次執(zhí)行每一組動作: cc -c service.c cc -c subnet.c cc -o network subnet.o service.o 如果用戶僅僅修改了源程序service.c,Make只發(fā)現(xiàn)service.o和network這兩個文件已過時,就執(zhí)行了以下兩個動作: cc -c service.c cc -o network subnet.o ser

29、vice.o實際上為了生成一個network的更新版本,Make將執(zhí)行最少量的必須做的再編譯工作。Make是最講效率的。在一個依賴行下可跟隨任意多行的UNIX命令,直至下一個依賴行或空行為止。12.4.2 Make的內(nèi)部規(guī)則 上例給出的Make的說明比較繁瑣,一般來說,service.o通常都依賴于service.c,對于其他的模塊也是如此。為了簡化說明,Make提供了一組內(nèi)部依賴規(guī)則,只要在Make的說明文件中沒有對這些規(guī)則的另外說明,Make就使用這些規(guī)則來產(chǎn)生目標文件。表11-1列出了Make內(nèi)部規(guī)則。 目標 依賴 規(guī)則/命令 x.o x.c cc -c x.c x.o x.s as -

30、o x.s x.o x.y yacc x.y cc -c y.tab.c rm y.tab.c mv y.tab.o x.o x.c x.y yacc x.y mv y.tab.c x.c x.a x.c cc -c x.c ar rv x.a x.o rm -f x.o 如果一個目標文件已過時,make在當前目錄下搜索與目標文件有相同的基本名但后綴不同的源文件,例如c源文件x.c,并執(zhí)行Make內(nèi)部的規(guī)則或命令。用戶也可以定義自己的缺省后綴推理規(guī)則: .c.o: cc -g -c $*.c僅有一個后綴的規(guī)則,例如.c:是描述怎樣由x.c建立x的規(guī)則,這對于從c源程序建立目標文件是很方便的。利

31、用圖11-3的Make內(nèi)部規(guī)則,重寫Makefile: network:subnet.c service.c cc -o network subnet.o service.o subnet.o service.o :netdefs.h由上可以看到,由于利用了Make內(nèi)部規(guī)則,原有關(guān)subnet.o和service.o的兩個依賴行,現(xiàn)合并成一個依賴行,其動作部分取Make內(nèi)部隱含規(guī)則/命令。使用Make內(nèi)部規(guī)則也帶來了一個新的問題。由x.c,x.s,x.y和x.l都可以產(chǎn)生x.o目標文件,如果現(xiàn)在要更新x.o,那么使用哪一條內(nèi)部規(guī)則來產(chǎn)生x.o呢?通過使用后綴的依賴關(guān)系表可以解決這個問題。后綴依

32、賴關(guān)系缺省表為: .SUFFIXES: .o .c .y .l .s .sh表中的后綴次序決定了當Make發(fā)現(xiàn)了多重路徑時,就按后綴表中的優(yōu)先次序產(chǎn)生目標文件。例如在更新x.o時,如系統(tǒng)中同時存在x.c,x.y,x.l,x.s和x.sh文件,由于在表中.c后綴是在.o后綴之后最先出現(xiàn),故采用編譯x.c的命令更新x.o目標文件。12.4.3 Make中的宏 類似于定義shell變量,在Makefile中可以定義和使用宏(或稱變量)。宏定義的格式為: 標識符串表在定義了一個宏后,可以用$(標識符)來引用宏。例如: CC=/usr/ucb/cc $(CC) -g -c *.c用宏指令可以減少很多重復(fù)

33、的部分,如要修改也只要修改宏定義這一行。如果不使用宏,用戶就不得不對替代部分的每一次出現(xiàn)都進行修改,且有潛在的危險性很可能造成不一致性。 Make也使用shell變量或環(huán)境變量,所有的環(huán)境變量都被Make看成宏定義,例如,在Makefile中能以$(HOME)取得用戶的主目錄。對環(huán)境變量的處理是在處理內(nèi)部規(guī)則之后,但在處理Makefile之前,故在發(fā)生沖突的情況下,Makefile中的宏定義覆蓋環(huán)境變量。與C語言的include編譯指示行類似,可以在Makefile含有包含文件指示行。如 include macros.mkmake程序就讀入include后面的文件名,而后處理該文件中的各種宏定

34、義符。 2. 內(nèi)部宏 Make使用五種不同形式內(nèi)部宏(或稱內(nèi)部變量),它們是$*,$,$,$?和$%。這些宏對建立目標文件要寫的規(guī)則非常有用。下面是一個由.c文件產(chǎn)生.o文件的缺省規(guī)則: .c.o: cc -g -c $宏$擴展成使目標已過時的依賴文件名,在上面例子中被擴展成.c文件。宏$*擴展成不帶后綴的依賴文件名,上面的推理規(guī)則可重寫成: .c.o: cc -g -c $*.c宏$擴展成目標文件的名字,只能用于跟隨在顯式說明行下面的命令中,如在依賴關(guān)系行使用,要寫成$。在下例的說明中,$代表目標文件network。 network: subnet.c service.c cc -o $ s

35、ubnet.o service.o宏$?與宏$類似,但它用于顯式產(chǎn)生目標文件規(guī)則的情況下,擴展成使目標文件已過時的依賴文件名。宏$%用于目標是庫文件時的情況,如果目標或依賴文件包括括號,那么該目標或依賴文件是檔案庫,括號中的串名就是庫中的一個成員文件。假定依賴行是具有l(wèi)ibx.a:libx.a(file.o)的形式,那么$%擴展成庫libx.a的成員file.o,而$賦值為libx.a。3. 預(yù)置宏 make有一組預(yù)置宏,這些宏主要用于Make的推理規(guī)則和命令中。一些重要的預(yù)置宏列舉表11-2中。在表中的預(yù)置值一欄里,減號()表示該宏被置為空。這些宏也能像其用戶定義的任何其他宏一樣在Makef

36、ile中重置。如CFLAGS=-g -c。 12.4.4 用Make維護庫 與檔案庫有關(guān)的推理規(guī)則形如.x.a。下面是一個關(guān)于庫lib的規(guī)則: libx.a:libx.a(file1.o)libx.a(file2.o) libx.a(file3.o) echo lib is now up-to-date .c.a: $(CC) -c $(CFLAGS) $ /tmp/cleanlog.$ print: $(SOUCE) $(HEADER) echo printing modified source and head files pr $? | lp -touch $ readable: -ec

37、ho test -r netdefs.h | sh幾點說明在上面的Makefile中,目標all不是文件名,在該行以下也沒有動作行,如以命令make all啟動make程序,make將依次考察network和install這兩個目標。宏定義CFLAGS=-O -g不僅使得在編譯命令行的宏代換時,而且也在make用隱含的構(gòu)造命令調(diào)用c編譯程序時總是選用優(yōu)化選項-O和調(diào)試選項-g。在install依賴行以下的命令是在生成了執(zhí)行程序network和庫libnet.a后,將它們搬移到系統(tǒng)的公用目錄中,以便于用戶共享。 clean依賴行沒有依賴文件,因此以clean為目標啟動make時,總是要執(zhí)行該依賴

38、行下面的命令,其目的是在編譯和安裝完成后,清除一些不必保存的文件以節(jié)省磁盤空間。在print依賴行中,第一次執(zhí)行時,也沒有一個真正的print目標文件,它只是一個假想已過時的文件,只要指定print為目標,make總是執(zhí)行下面的打印命令,在打印了文件后,用UNIX的touch命令產(chǎn)生了名為print的輔助文件,并記住了print的修改時間。以后重新修改一些源程序或頭文件后。根據(jù)依賴行和打印參數(shù)$?,只打印在上一次打印后重新修改過的文件。接著再重置print的更新時間。下面對Makefile作其他方面的說明: 1. 消除顯示命令 一般情況下make將顯示它執(zhí)行的每一個命令,但有三種方法可以消除顯

39、示make執(zhí)行的命令。(1) make執(zhí)行任何以字符開頭的命令時,不顯示該命令。(2) 在makefile中加入偽依賴行 .SILENT:,該依賴行使得make在執(zhí)行命令時關(guān)閉命令顯示機構(gòu)。偽依賴行在Makefile中的位置無關(guān)緊要,另外,一旦命令顯示被關(guān)閉以后就不能再打開了。(3) 以-s選項啟動make。這與在makefile中的偽依賴行 .SILENT:的作用一樣。 2. 忽略返回代碼 在UNIX系統(tǒng)中每一個命令都返回一個數(shù)值代碼。該值為零說明程序執(zhí)行成功,正常返回;相反,非零返回碼說明程序執(zhí)行失敗,或出錯。 make使用命令的返回碼來決定它是否要繼續(xù)執(zhí)行在命令行或內(nèi)部規(guī)則中給出的命令。

40、如命令返回非零碼,make就停止處理Makefile,并顯示出錯信息。有時用戶也需要make在發(fā)現(xiàn)一個錯誤時能繼續(xù)處理余下部分。(1)在Makefile的命令前面加上前導(dǎo)連字符()。(2)在Makefile中任何位置上加入偽依賴行.IGNORE: 忽略了所有程序的返回碼。(3) 以-i選項啟動make。3. 注釋和續(xù)行 在Makefile中以#開頭的是注釋行,make將不處理這些行。如果一個依賴行或命令行太長可以用出現(xiàn)在行尾的反斜線()來續(xù)行。make對于每一行命令及以反斜線連續(xù)的下一行命令啟動同一個shell進程處理。4. shell內(nèi)部命令 make啟動的shell只能按環(huán)境查找和執(zhí)行UN

41、IX的外部命令,因為test是shell內(nèi)部命令,所以該命令必須以標準輸入的形式傳給shell進程。 12.4.6 make命令選項和參數(shù) make程序能讀取命令行上的很多選項。 -f 用跟在f后面的指定的文件作為Make的描述文件。該選項如缺省。make首先在當前目錄中找makefile,其次找Makefile。如-f后的參數(shù)為,make所將從標準輸入上讀取描述文件Makefile。 -i 迫使make忽略命令的非零返回值。該選項的作用同Makefile中的偽依賴行 .IGNORE:。 -n 展開所有的元字符,進行宏代換,印出命令,向用戶顯示make將做什么,但不真正執(zhí)行命令。-s 沉默方式

42、,在執(zhí)行命令前不印出命令行。該選項的作用同Makefile中的偽依賴行.SILENT:。-t 觸摸(touch), Makefile中所有過時的目標,即更新任何跟隨依賴行的命令。用該選項啟動make主要用于僅僅對一些依賴文件作一些加入注釋之類的修改,這樣可以省做很多不必要的重新編譯工作,來產(chǎn)生同樣的目標代碼。雖然用-t選項能代替對單個目標文件執(zhí)行touch命令,但一般情況下這可能會破壞Make的一致性。除了選項以外,make命令行還能帶有其他參數(shù)。如在命令行上置宏,一旦在命令行置宏,任何進一步的賦值都不能改變這些宏。在make命令行也能指定要更新的目標,這對打算生成部分的系統(tǒng)而不是完整的系統(tǒng)時

43、是非常有用的。如不指定目標,make就更新Makefile中的第一個依賴行上的目標。下面是包括選項,指定目標和置宏的make命令行: make -f mymakefile network CFLAGS=-g只要掌握了Make的原理,也能將它用于維護其他的軟件系統(tǒng),如維護用戶手冊,很多其他的軟件任務(wù)也就借助于Make來實現(xiàn),Make的威力是無限的。12.5 調(diào)試程序 調(diào)試排錯程序在程序設(shè)計環(huán)境中得到了廣泛的應(yīng)用,調(diào)試程序包括在程序員的控制下運行程序和檢查在程序非正常終止后由系統(tǒng)轉(zhuǎn)儲的內(nèi)存映像。程序非正常終止時一般顯示類似Bus errorcore dumped 或Memory faultcore

44、 dumped等信息。由于程序本身的錯誤而造成非正常終止后,用戶可以靜態(tài)地檢查,分析各個源程序和模塊之間的接口,也可在源程序中插入一些打印語句,動態(tài)地跟蹤,觀察程序執(zhí)行的過程。但一種更為系統(tǒng)的方法是利用UNIX系統(tǒng)提供的調(diào)試排錯軟件Debuggers,通過檢查源程序和出錯時系統(tǒng)轉(zhuǎn)儲的內(nèi)存映像文件(core image file)來幫助排除錯誤,開發(fā)程序。當前使用的主要的調(diào)試排錯軟件程序有dbx、adb和sdb。12.5.1 調(diào)用sdb 第一個參數(shù)是可執(zhí)行目標程序名,第二個參數(shù)是內(nèi)存映像文件core,第三個參數(shù)是用冒號隔開的源文件所在的目錄表。所有的參數(shù)都是可選的,在缺省時,sdb將把a.out

45、作為目標文件,core作為內(nèi)存映像文件,當前目錄作為第三個目錄表參數(shù)。 對要調(diào)試的程序example用-g選項編譯 cc -g -o example example.c當運行程序example時產(chǎn)生了“core dumped”信息接下來就可運行sdb來調(diào)試程序了: sdb example core12.5.2 sdb的調(diào)試命令 /模式 定位到匹配模式的字符串所在的源程序行。該命令類似于vi的查找模式命令。行號b 命令;命令. 在行號處設(shè)置斷點。程序在斷點處執(zhí)行命令組后繼續(xù)向下執(zhí)行。如無命令,sdb在斷點處等待用戶輸入命令。 變量名/項數(shù)長度格式 顯示變量的內(nèi)容。 地址/顯示格式 按格式顯示指定

46、地址單元的內(nèi)容。 s 單步執(zhí)行12.6 源代碼控制系統(tǒng)(SCCS) 一個需長時間開發(fā),維護的軟件包含很多文件。當程序的一個版本已經(jīng)在使用時,常因發(fā)現(xiàn)錯誤和為增強功能需要對它進行修改。為安全起見,在實際修改之前對有關(guān)該程序的很多文件進行備份是必須的。如果用戶只保存文件的最新版本,這就很容易丟失版本的變化情況,不能恢復(fù)到修改前的情況,當有需要回溯到一個程序的老版本,以圖再開發(fā)時,這尤其重要。這種靠對程序的所有版本都進行備份的簡單方就顯得非常笨拙,不易使用和低效,而且很有可能造成版本的不一致和混亂的情況。 SCCS(Source Code Control System) 用于控制和維護程序的各個歷史

47、版本。SCCS并不存儲程序的多個拷貝。對于程序的不同版本,SCCS總是只存儲一個物理文件,并在其中存儲了程序經(jīng)歷的增量變化,即修改內(nèi)容。SCCS有一個復(fù)雜而精致的機制來標識和編號不同的版本。SCCS能用于存儲,查詢文件的任一版本,提供控制文件修改權(quán)限機制,記錄每次修改的原因,內(nèi)容,時間等內(nèi)容。SCCS適合于維護任何類型的正文文件版本,但最多的還是用于維護源程序的不同版本。12.6.1 創(chuàng)建SCCS的初始版本 admin -isubnet.c netslib/s.subnet.c admin -iservice.c netslib/s.service.c現(xiàn)在已創(chuàng)建了在SCCS管理下的s-文件,s

48、-文件必須以s.開頭,SCCS總是將s-文件創(chuàng)建為只讀模式(444)。admin命令一次只能創(chuàng)建一個s-文件。用戶可以編寫一個shell過程自動地處理這批文件。在創(chuàng)建了所有的s-文件后,對應(yīng)的原始文件應(yīng)當刪除,在上面這個例子中應(yīng)當刪除工作目錄的subnet.c和service.c這兩個文件。在netslib目錄中的兩個s-文件是這個軟件版本的最終拷貝,12.6.2 提取一個版本 用get命令提取的文件稱為g-文件,g-文件名同原admin命令所處理的原始文件名,即s-文件去掉前綴s.的文件名。由路徑1獲得的g-文件使用戶能夠編譯它,以產(chǎn)生相應(yīng)的目標代碼文件,使用該命令的一個例子為: get n

49、etslib/s.subnet.c netslib/s.service.c上面的get命令從netslib目錄中提取二個只讀文件放入工作目錄中。提取出來的文件命名為去除前綴s.的s-文件名。 get 命令 1 s-文件 2 get -e命令 只讀文件 delta命令 可編輯文件 圖11-5 提取s-文件的版本如果用戶需要提取netslib目錄中很多s-文件,對此SCCS為用戶提供了方便的操作方法,即可以用一個目錄作為get的參數(shù),在這種情況下,SCCS就提取那個目錄中的所有s-文件,例: get netslib當從SCCS數(shù)據(jù)庫中提取了有關(guān)文件后,用戶就可以用尋常的方法對它們進行編譯,或使用m

50、ake來創(chuàng)建目標程序。路徑1的set命令所提取的文件是s-文件的只讀拷貝,用戶不應(yīng)修改這些文件的權(quán)限和內(nèi)容。路徑2帶-e選項的get命令提取一個可編輯的文件版本并向用戶顯示原先版本號和將建立的版本號。用戶可以用普通的編輯軟件對它們進行修改。 get -e netslib/s.subnet.c可以防止不同用戶同時對一個s-文件操作的措施是當一個用戶用get -e命令提取SCCS數(shù)據(jù)庫目錄的一個s-文件后,SCCS在該目錄中創(chuàng)建了一個p-file,其他用戶試圖再執(zhí)行g(shù)et -e操作時就會出錯,直至前一用戶完成了修改和測試,執(zhí)行delta操作后才將p-file刪去。12.6.3 建立一個新版本 在對

51、用get -e命令獲得的g-文件完成了修改和測試后就可用delta命令創(chuàng)建新版本。例: delta netslib/subnet.c comment?delta命令首先提示用戶輸入注釋,用戶可輸入有關(guān)本次修改的目的和摘要,以便跟蹤軟件系統(tǒng)的變化。在delta程序完成了建立新版本的工作后就將g-文件刪除。用戶如果要編譯該文件或用make創(chuàng)建目標程序,必須再做另外一次get操作,以獲得該文件的一個只讀拷貝。12.6.4 顯示SCCS文件的歷史 prs命令用于顯示對一個SCCS文件所做的所有變化,例 prs netslib/s.subnet.cprs程序顯示s-文件的由最新到最老的每一個版本號,創(chuàng)建

52、版本的日期和時間,誰創(chuàng)建該版本,在創(chuàng)建該版本時用戶所做的修改摘要插入行數(shù)/刪除行數(shù)/未變行數(shù)。最后顯示用戶在delta命令中輸入的注釋。 12.6.5 SCCS的版本號結(jié)構(gòu) 用admin命令建立的SCCS文件初始版為1.1,以后由相繼的get -e和delta命令建立的SCCS文件各個版本依次為1.2,1.3。版本號更一般的形式為: release.level.branch.sequence (發(fā)表號,級號,分支號,序列號)如果用戶對SCCS文件做了較大的修改,可以改變新版本的release號: get -e -r2 netslib/s.subnet.c 這樣就產(chǎn)生了新的版本號2.1。也可以用get命令提取一個以前的版本: get -r1.3 netslib/s.subnet.cSCCS的版本號可以構(gòu)成樹形結(jié)構(gòu)。12.6.6 ID關(guān)鍵

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論