




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 2005 博創(chuàng)科技北北 京京 博博 創(chuàng)創(chuàng) 興興 業(yè)業(yè) 科科 技技 有有 限限 公公 司司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD博創(chuàng)科技 嵌入互動(dòng)Linux開發(fā)基礎(chǔ)原倉(cāng)周博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技第二章 Linux程序設(shè)計(jì)基礎(chǔ)C環(huán)境 Linux編程概述 文本編輯器vi Linux下函數(shù)庫(kù) GCC及其使用 調(diào)試工具gdb GNU make和makefile 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Linux編程概述 Linux軟件開發(fā)一直在Internet環(huán)境下講行。這個(gè)環(huán)境是全球性的,編程人員來(lái)自世界各地。只要能夠訪問Web
2、站點(diǎn),就可以啟動(dòng)一個(gè)以Linux為基礎(chǔ)的軟件項(xiàng)目。 Linux開發(fā)工作經(jīng)常是在Linux用戶決定共同完成一個(gè)項(xiàng)目時(shí)開始的。當(dāng)開發(fā)工作完成后,該軟件就被放到Internet站點(diǎn)上,任何用戶都可以訪問和下載它。由于這個(gè)活躍的開發(fā)環(huán)境,新的以Linux為基礎(chǔ)的軟件功能日益強(qiáng)大,而且呈現(xiàn)爆炸式的增長(zhǎng)態(tài)勢(shì)。 大多數(shù)Linux軟件是經(jīng)過自由軟件基金會(huì)(Free Software Foundation)提供的GNU(GNU 即 GNUs not UNIX)公開認(rèn)證授權(quán)的,因而通常被稱作GNU軟件。GNU軟件免費(fèi)提供給用戶使用,并被證明是非常可靠和高效的。許多流行的Linux實(shí)用程序如C編譯器、shell和編
3、輯器都是GNU軟件應(yīng)用程序。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技 Linux程序需要首先轉(zhuǎn)化為低級(jí)機(jī)器語(yǔ)言即所謂的二進(jìn)制代碼以后,才能被操作系統(tǒng)執(zhí)行。 例如編程時(shí),先用普通的編程語(yǔ)言生成一系列指令,這些指令可被翻譯為適當(dāng)?shù)目蓤?zhí)行應(yīng)用程序的二進(jìn)制代碼。這個(gè)翻譯過程可由解釋器一步步來(lái)完成,或者也可以立即由編譯器明確地完成。 shell編程語(yǔ)言如BASH、TCSH、GAWK、Perl、Tcl和Tk都利用自己的解釋器。用這些語(yǔ)言編制的程序盡管是應(yīng)用程序文件,但可以直接運(yùn)行。編譯器則不同,它將生成一個(gè)獨(dú)立的二進(jìn)制代碼文件然后才可以運(yùn)行。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Linux編程風(fēng)格 GN
4、U風(fēng)格 Linux 內(nèi)核編程風(fēng)格 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技GNU風(fēng)格 (1/2) 函數(shù)返回類型說(shuō)明和函數(shù)名分兩行放置,函數(shù)起始字符和函數(shù)開頭左花括號(hào)放到最左邊。 盡量不要讓兩個(gè)不同優(yōu)先級(jí)的操作符出現(xiàn)在相同的對(duì)齊方式中,應(yīng)該附加額外的括號(hào)使得代碼縮進(jìn)可以表示出嵌套。 按照如下方式排版do-while語(yǔ)句:dowhile() 每個(gè)程序都應(yīng)該以一段簡(jiǎn)短的說(shuō)明其功能的注釋開頭。 請(qǐng)為每個(gè)函數(shù)書寫注釋,說(shuō)明函數(shù)是做什么的,需要哪些入口參數(shù),參數(shù)可能值的含義和用途。如果用了非常見的、非標(biāo)準(zhǔn)的東西,或者可能導(dǎo)致函數(shù)不能工作的任何可能的值,應(yīng)該進(jìn)行特殊說(shuō)明。如果存在重要的返回值,也需要說(shuō)明。 不
5、要聲明多個(gè)變量時(shí)跨行,每一行都以一個(gè)新的聲明開頭。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技GNU風(fēng)格 (2/2) 當(dāng)一個(gè)if中嵌套了另一個(gè)if-else時(shí),應(yīng)用花括號(hào)把if-else括起來(lái)。 要在同一個(gè)聲明中同時(shí)說(shuō)明結(jié)構(gòu)標(biāo)識(shí)和變量或者結(jié)構(gòu)標(biāo)識(shí)和類型定義(typedef)。先定義變量,再使用。 盡量避免在if的條件中進(jìn)行賦值。 請(qǐng)?jiān)诿种惺褂孟聞澗€以分割單詞,盡量使用小寫;把大寫字母留給宏和枚舉常量,以及根據(jù)統(tǒng)一慣例使用的前綴。例如,應(yīng)該使用類似ignore_space_change_flag的名字;不要使用類似iCantReadThis的名字。 用于表明一個(gè)命令行選項(xiàng)是否給出的變量應(yīng)該在選項(xiàng)含
6、義的說(shuō)明之后,而不是選項(xiàng)字符之后被命名。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Linux 內(nèi)核編程風(fēng)格 Linux內(nèi)核縮進(jìn)風(fēng)格是8個(gè)字符。 Linux內(nèi)核風(fēng)格采用K&R標(biāo)準(zhǔn),將開始的大括號(hào)放在一行的最后,而將結(jié)束的大括號(hào)放在一行的第一位。 命名盡量簡(jiǎn)潔。 不應(yīng)該使用諸如ThisVariableIsATemporaryCounter之類的名字。應(yīng)該命名為tmp,這樣容易書寫,也不難理解。 命名全局變量,應(yīng)該用描述性命名方式,例如應(yīng)該命名“count_active_users()”,而不是“cntusr()”。 本地變量應(yīng)該避免過長(zhǎng)。 函數(shù)最好短小精悍,一般來(lái)說(shuō)不要讓函數(shù)的參數(shù)多于10個(gè),否則應(yīng)
7、該嘗試分解這個(gè)過于復(fù)雜的函數(shù)。 通常情況,注釋說(shuō)明代碼的功能,而不是其實(shí)現(xiàn)原理。避免把注釋插到函數(shù)體內(nèi),而寫到函數(shù)前面,說(shuō)明其功能,如果這個(gè)函數(shù)的確很復(fù)雜,其中需要有部分注釋,可以寫些簡(jiǎn)短的注釋來(lái)說(shuō)明那些重要的部分,但是不能過多。博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技文本編輯器vi vi的模式 vi的進(jìn)入 命令模式 插入模式 末行模式博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技vi的模式 Command Mode (命令模式) 這是執(zhí)行vi后的缺省模式 此時(shí)鍵盤輸入當(dāng)作命令 命令有大小寫之區(qū)分 Input Mode (插入模式) 使用 a、i、o、c、r、s 進(jìn)入插入模式 用戶輸入的任何字符都被vi
8、當(dāng)做文件內(nèi)容保存起來(lái),并將其顯示在屏幕上 按下 ESC 鍵即可回到 Command Mode博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技vi的模式 Last Mode (末行模式) 在 Command Line 按下 : 即可進(jìn)入該模式 用來(lái)進(jìn)行保存文件、打開文檔或環(huán)境的設(shè)定 命令有大小寫之分博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技vi的進(jìn)入和內(nèi)容輸入 進(jìn)入: vi 文件名 輸入文件內(nèi)容 (進(jìn)入插入模式) 新增 (append) a 從光標(biāo)所在位置后面開始新增內(nèi)容 A 從光標(biāo)所在行最后面的地方開始新增內(nèi)容。 插入 (insert) i 從光標(biāo)所在位置前面開始插入內(nèi)
9、容 I 從光標(biāo)所在行的第一個(gè)非空白字符前面開始插入資料。 開始 (open) o 在光標(biāo)所在行下新增一行并進(jìn)入輸入模式。 O 在光標(biāo)所在行上新增一行并進(jìn)入輸入模式。 (命令模式)博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技命令模式 1、光標(biāo)的移動(dòng) h 左移一個(gè)字符 l 右移一個(gè)字符j 下移一行 k 上移一行w,W 跳至后一個(gè)字的開頭(W忽略標(biāo)點(diǎn))b,B 跳至前一個(gè)字的開頭(B忽略標(biāo)點(diǎn))e 移動(dòng)到后一個(gè)字的末尾 至本行第一個(gè)非空字符 $ 至行尾 0 至行首H 移動(dòng)到當(dāng)前窗口的第一列 M 移動(dòng)到當(dāng)前窗口的中間列 L 移動(dòng)到視窗的最后一列) 光標(biāo)所在位置到下個(gè)句子的第一個(gè)字母 ( 光標(biāo)所在位置到該句子的第
10、一個(gè)字母 光標(biāo)所在位置到該段落的最后一個(gè)字母 光標(biāo)所在位置到該段落的第一個(gè)字母博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技命令模式 1、光標(biāo)的移動(dòng)(續(xù))nH 將光標(biāo)移到屏幕的第 n 行nL 將光標(biāo)移到屏幕的倒數(shù)第 n 行CTRL-d 向下半頁(yè)CTRL-f 向下一頁(yè)CTRL-u 向上半頁(yè) CTRL-b 向上一頁(yè) n-減號(hào)移動(dòng)到上一行的第一個(gè)非空白字符,前面加上數(shù)字可以指定移動(dòng)到以 上 n 行n+ 加號(hào)移動(dòng)到下一行的第一個(gè)非空白字符,前面加上數(shù)字可以指定移動(dòng)到以下 n 行博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技命令模式 2、刪除x 刪除光標(biāo)所在字符 X 刪除光標(biāo)前面的字符 s 刪除光標(biāo)所在字符,并進(jìn)入輸入
11、模式 S 刪除光標(biāo)所在的行,并進(jìn)入輸入模式 dd 刪除光標(biāo)所在的行 D 從光標(biāo)位置開始刪除到行尾 d與光標(biāo)移動(dòng)命令的組合博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技命令模式 3、修改 r 修改光標(biāo)所在字符,r 后接著要修改的字符。如,rc 可以用字符“ c ”替換光標(biāo)所指向的當(dāng)前字符 R 進(jìn)入替換狀態(tài),新增內(nèi)容會(huì)覆蓋原先內(nèi)容,直到按 ESC 回到命令模式下為止 cc 修改光標(biāo)所在行 C 修改從光標(biāo)位置到該行末尾的內(nèi)容 c 與光標(biāo)移動(dòng)命令的組合博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技命令模式 4、復(fù)制和移動(dòng)yy 復(fù)制當(dāng)前行到內(nèi)存緩沖區(qū)nyy 復(fù)制 n 行內(nèi)容到內(nèi)存緩沖區(qū) y與光標(biāo)移動(dòng)的組合p 將緩沖區(qū)的
12、內(nèi)容粘貼到光標(biāo)的后面P 將緩沖區(qū)的內(nèi)容粘貼到光標(biāo)的前面另:在末行模式下實(shí)現(xiàn)移動(dòng):n1,n2 m n3 : 把 n1到n2 行內(nèi)容搬到第 n3 行后博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技5 5、搜索字符串、搜索字符串/pattern 移至下一個(gè)包含pattern的行?pattern 移至上一個(gè)包含pattern的行/往下重復(fù)查找? 往上重復(fù)查找n 在同一方向重復(fù)查找N在相反方向重復(fù)查找/pattern/+n移至下一個(gè)pattern所在行后的第n行?pattern?-n 移至上一個(gè)Pattern所在行前的第n行6 6、其他、其他 u 撤銷前一條命令的結(jié)果*. $ /包含在查找字符串中,要用轉(zhuǎn)義字符
13、( )命令模式博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技末行模式 1、文件的保存和退出:w 保存:q 退出:w! 強(qiáng)制保存:q! 強(qiáng)制退出:wq 保存退出:wq! 強(qiáng)制保存退出博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技末行模式 2、字符串的替換 :s/str1/str2/ 用字符串 str2 替換行中首次出現(xiàn)的字符串 str1 :s/str1/str2/g 用字符串 str2 替換行中所有出現(xiàn)的字符串 str1 :.,$ s/str1/str2/g 用字符串 str2 替換正文當(dāng)前行到末尾所有出現(xiàn)的字符串 str1 :1,$ s/str1/str2/g 用字符串 str2 替換正文中所有出現(xiàn)的字符串
14、str1 :g/str1/s/str2/g 功能同上 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技末行模式 其他:: n 將光標(biāo)移到第 n 行 編輯多個(gè)文件vi file1 file2 :n 編輯下一個(gè)文件:e 編輯指定文件博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Linux下函數(shù)庫(kù)(1/3) 一個(gè)“程序函數(shù)庫(kù)”就是一個(gè)文件包含了一些編譯好的代碼和數(shù)據(jù),這些編譯好的代碼和數(shù)據(jù)可以在事后供其他的程序使用。程序函數(shù)庫(kù)可以使整個(gè)程序更加模塊化,更容易重新編譯,而且更方便升級(jí)。可分為兩種類型: 靜態(tài)函數(shù)庫(kù)(static libraries):是一個(gè)普通的目標(biāo)文件的集合,一般用“.a”作為文件的后綴。靜態(tài)函數(shù)庫(kù)和
15、共享函數(shù)庫(kù)相比有很多的缺點(diǎn),占用內(nèi)存空間多。但使用ELF格式的靜態(tài)庫(kù)函數(shù)生成的代碼可以比使用共享函數(shù)庫(kù)的程序運(yùn)行速度上快一些。 可以用ar這個(gè)程序來(lái)創(chuàng)建一個(gè)靜態(tài)函數(shù)庫(kù)文件,或者往一個(gè)已經(jīng)存在地靜態(tài)函數(shù)庫(kù)文件添加新的目標(biāo)代碼。 例如, 把和加入到my_library.a這個(gè)函數(shù)庫(kù)文件: ar rcs my_library.a 然后運(yùn)行 ranlib,以給庫(kù)加入一些索引信息博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Linux下函數(shù)庫(kù)(2/3) 共享函數(shù)庫(kù)(shared libraries):當(dāng)一個(gè)可執(zhí)行程序在啟動(dòng)的時(shí)候被加載的函數(shù)。每個(gè)共享函數(shù)庫(kù)都有個(gè)特殊的名字,稱作“soname”。soname名字
16、命名必須以“l(fā)ib”作為前綴,然后是函數(shù)庫(kù)的名字,然后是“.so”,最后是版本號(hào)信息。 優(yōu)點(diǎn):多進(jìn)程使用同一函數(shù)庫(kù);修改函數(shù)庫(kù)不需重新連編。 安裝一個(gè)新版本的函數(shù)庫(kù)的時(shí)候,要先將這些函數(shù)庫(kù)文件拷貝到一些特定的目錄中,運(yùn)行l(wèi)dconfig就可以。ldconfig檢查已經(jīng)存在的庫(kù)文件,然后創(chuàng)建soname的符號(hào)鏈接到真正的函數(shù)庫(kù),同時(shí)設(shè)置/etc/ld.so.cache這個(gè)緩沖文件。 例如,創(chuàng)建兩個(gè)目標(biāo)文件(a.o和b.o),然后創(chuàng)建一個(gè)包含a.o和b.o的共享函數(shù)庫(kù)。 gcc -fPIC -g -c -Wall a.cgcc -fPIC -g -c -Wall b.cgcc -shared -W
17、l,-soname,liblusterstuff.so.1 -o liblusterstuff.so.1.0.1 a.o b.o lc 注:” -fPIC ”是位置無(wú)關(guān)參數(shù), ”-g”和“Wall”參數(shù)不是必須的。博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Linux下函數(shù)庫(kù)(3/3) 函數(shù)庫(kù)和頭文件的保存位置 a. 函數(shù)庫(kù) /lib:系統(tǒng)必備共享函數(shù)庫(kù) /usr/lib:標(biāo)準(zhǔn)共享函數(shù)庫(kù)和靜態(tài)函數(shù)庫(kù) /usr/i486-linux-libc5/lib:libc5 兼容性函數(shù)庫(kù) /usr/X11R6/lib:X11R6 的函數(shù)庫(kù) /usr/local/lib:本地函數(shù)庫(kù) b. 頭文件 /usr/inc
18、lude:系統(tǒng)頭文件 /usr/local/include:本地頭文件 c. 共享函數(shù)庫(kù)的相關(guān)配置和命令 /etc/ld.so.conf:包含共享庫(kù)的搜索位置 ldconfig:共享庫(kù)管理工具,一般在更新了共享庫(kù)之后要運(yùn)行該命令 ldd:可查看可執(zhí)行文件所使用的共享函數(shù)庫(kù) 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技使用GNU cc開發(fā)應(yīng)用程序 gcc的簡(jiǎn)介 可執(zhí)行文件的格式可執(zhí)行文件的格式 gcc的使用 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gcc的簡(jiǎn)介 gcc 是 GNU 的 C 和 C+ 編譯器。實(shí)際上,gcc 能夠編譯多種多種語(yǔ)言:C、C+ 和 Object C等。利用 gcc 命令可同時(shí)編
19、譯并連接 C 和 C+ 源程序。也可以對(duì)幾個(gè) C 源文件利用 gcc 編譯、連接并生成可執(zhí)行文件。 gcc可以使程序員靈活地控制編譯過程。編譯過程一般可以分為下面四個(gè)階段,每個(gè)階段分別調(diào)用不同的工具進(jìn)行處理預(yù)處理鏈接編譯組譯源 程 序(*.c)可執(zhí)行文件預(yù)處理器編譯器組譯器連接器博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gcc的四個(gè)階段 命令gcc首先調(diào)用cpp進(jìn)行預(yù)處理,在預(yù)處理過程中,對(duì)源代碼文件中的文件包含(include)、預(yù)編譯語(yǔ)句(如宏定義define等)進(jìn)行分析。 接著調(diào)用cc1進(jìn)行編譯,這個(gè)階段根據(jù)輸入文件生成以.o為后綴的目標(biāo)文件。 匯編過程是針對(duì)匯編語(yǔ)言的步驟,調(diào)用as進(jìn)行工作
20、,一般來(lái)講,.S或.s為后綴的匯編語(yǔ)言源代碼文件匯編之后都生成以.o為后綴的目標(biāo)文件。 當(dāng)所有的目標(biāo)文件都生成之后,gcc就調(diào)用ld來(lái)完成最后的關(guān)鍵性工作,這個(gè)階段就是連接。在連接階段,所有的目標(biāo)文件被安排在可執(zhí)行程序中的恰當(dāng)?shù)奈恢?,同時(shí),該程序所調(diào)用到的庫(kù)函數(shù)也從各自所在的函數(shù)庫(kù)中連到合適的地方。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技可執(zhí)行文件格式可執(zhí)行文件格式 Linux系統(tǒng)中可執(zhí)行文件有兩種格式。 第一種格式是a.out格式,這種格式用于早期的Linux系統(tǒng)以及 Unix系統(tǒng)的原始格式。a.out來(lái)自于Unix C編譯程序默認(rèn)的可執(zhí)行文件名。當(dāng)使用共享庫(kù)時(shí),a.out格式就會(huì)發(fā)生問題。
21、把a(bǔ).out格式調(diào)整為共享庫(kù)是一種非常復(fù)雜的操作。 因此,一種新的文件格式被引入U(xiǎn)nix系統(tǒng)5的第四版本和Solaris系統(tǒ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)上。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技GNU C 的使用 基本語(yǔ)法 gcc options 說(shuō)明: 在gcc后面可以有多個(gè)編譯選項(xiàng),同時(shí)進(jìn)行多個(gè)編譯操作。很多的gcc選項(xiàng)包括一個(gè)以上的字符
22、。因此你必須為每個(gè)選項(xiàng)指定各自的連字符。例如,下面的兩個(gè)命令是不同的: gcc -p -g test1.c gcc -pg test1.c 當(dāng)你不用任何選項(xiàng)編譯一個(gè)程序時(shí),GCC將會(huì)建立(假定編譯成功)一個(gè)名為a.out的可執(zhí)行文件。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gcc選項(xiàng) -o選項(xiàng) 你能用 -o 編譯選項(xiàng)來(lái)為將產(chǎn)生的可執(zhí)行文件指定一個(gè)文件名來(lái)代替 a.out。 例:gcc o count count.c -c選項(xiàng):告訴GCC僅把源代碼編譯為目標(biāo)代碼而跳過匯編和連接的步驟。這個(gè)選項(xiàng)使用的非常頻繁,因?yàn)樗沟镁幾g多個(gè)C程序時(shí)速度更快并且更易于管理。缺省時(shí)GCC建立的目標(biāo)代碼文件有一個(gè).
23、o的擴(kuò)展名。 例:gcc c test2.c -E 只運(yùn)行 C 預(yù)編譯器。 -S 編譯選項(xiàng)告訴 gcc 在為 C 代碼產(chǎn)生了匯編語(yǔ)言文件后停止編譯。 -shared 生成共享目標(biāo)文件。通常用在建立共享庫(kù)時(shí)。 -static 禁止使用共享連接。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技警告選項(xiàng)警告選項(xiàng) 在在gccgcc中用開關(guān)中用開關(guān)-Wall-Wall控制警告信息,使用示例命令如下:控制警告信息,使用示例命令如下: gcc Wall -o test3_1 test3_1.cgcc Wall -o test3_1 test3_1.c -w -w 不生成任何警告信息。不生成任何警告信息。 博創(chuàng)科技
24、嵌入互動(dòng) 2006 博創(chuàng)科技查找選項(xiàng) gcc一般使用默認(rèn)路徑查找頭文件和庫(kù)文件。如果文件所用的頭文件或庫(kù)文件不在缺省目錄下,則編譯時(shí)要指定它們的查找路徑。-I選項(xiàng):指定頭文件的搜索目錄例:gcc I/export/home/st o test1 test1.c-L選項(xiàng):指定庫(kù)文件的搜索目錄例:gcc L/usr/X11/R6/lib o test1 test1.c博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技多個(gè)源文件生成一個(gè)可執(zhí)行文件 問題:有多個(gè)源文件時(shí),如何生成一個(gè)可執(zhí)行文件? 方法1:gcc Wall o mytest test1.c test2.c test3.c 方法2:gcc-Wall
25、-c test1.cgcc-Wall c test2.cgcc-Wall c test3.c gcc o mytest test1.o test2.o test3.o博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技優(yōu)化選項(xiàng) 優(yōu)化選項(xiàng)可以使GCC在耗費(fèi)更多編譯時(shí)間和犧牲易調(diào)試性的基礎(chǔ)上產(chǎn)生更小更快的可執(zhí)行文件。這些選項(xiàng)中最典型的是-O和-O2選項(xiàng)。 -O0 不進(jìn)行優(yōu)化處理。 -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ì)更快。 -O3選項(xiàng):比 -
26、O2 更進(jìn)一步優(yōu)化,包括 inline 函數(shù)。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技版本選項(xiàng) -v選項(xiàng) 用戶將會(huì)得到自己目前正在使用的gcc的版本及與版本相關(guān)的一些信息。 gcc -v 將得到如下結(jié)果: Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs gcc version 2.7.2 -V 選項(xiàng) 如果安裝了多個(gè)版本的gcc,并且想強(qiáng)制執(zhí)行其中的某個(gè)版本,可以用命令通知系統(tǒng)用戶要使用的版本。 gcc -V2.6.3 -v博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技宏定義選項(xiàng) -D MACRO 以字符串“1”定義 MACR
27、O 宏。 -D MACRO=DEFN 以字符串“DEFN”定義 MACRO 宏。 -U MACRO 取消對(duì) MACRO 宏的定義。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技調(diào)試和剖析選項(xiàng) 使用調(diào)試選項(xiàng)后,gcc在進(jìn)行編譯的時(shí)候,在目標(biāo)文件(.o)和創(chuàng)建的可執(zhí)行文件中插入額外信息,這些額外信息使gdb能夠判斷編譯過的代碼和源代碼之間的關(guān)系。 -g選項(xiàng):告訴GCC產(chǎn)生能被 GNU 調(diào)試器使用的調(diào)試信息以便調(diào)試你的程序。例:gcc g o test3 test3.c -pg選項(xiàng):告訴GCC在你的程序里加入額外的代碼,執(zhí)行時(shí),產(chǎn)生gprof用的剖析信息以顯示你的程序的耗時(shí)情況。 使用gdb調(diào)試工具,命令
28、行如下: 例:gcc ggdb3 o test3 test3.c 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技調(diào)試工具gdb GDB調(diào)試器簡(jiǎn)介 gdb 的常用命令 gdb應(yīng)用實(shí)例 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gdb 簡(jiǎn)介 Linux系統(tǒng)中包含了GNU 調(diào)試程序gdb,它是一個(gè)用來(lái)調(diào)試C和 C+ 程序的調(diào)試器。可以使程序開發(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)視程序中變量的值; 可以
29、單步逐行執(zhí)行代碼,觀察程序的運(yùn)行狀態(tài)。 分析崩潰程序的產(chǎn)生的core文件博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gdb的特點(diǎn) gdb的功能非常強(qiáng)大 到目前為止,gdb已能夠支持Moduls-2、Chill、Pascal和FORTRAN程序的調(diào)試,但是調(diào)試這些語(yǔ)言的源程序時(shí)有一些功能還不能使用。 例如調(diào)試FORTRAN程序時(shí)還不支持表達(dá)式的輸入、輸出變量或類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)試信息。
30、 調(diào)試信息包含程序里的每個(gè)變量的類型和在可執(zhí)行文件里的地址映射以及源代碼的行號(hào)。 gdb 利用這些信息使源代碼和機(jī)器碼相關(guān)聯(lián)。 gdb是一個(gè)用來(lái)調(diào)試C和C+程序的常用調(diào)試工具之一。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gdb的啟動(dòng) 在命令行上輸入gdb并按回車鍵就可以運(yùn)行g(shù)db了,如果一切正常的話,將啟動(dòng)gdbgdb 出現(xiàn)(gdb)在這里,可以輸入調(diào)試命令 在可以使用 gdb 調(diào)試程序之前,必須使用 -g 選項(xiàng)編譯源文件??稍?makefile 中如下定義 CFLAGS 變量: CFLAGS = -g 運(yùn)行 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技獲取幫助信息 啟動(dòng)gdb后,可以在命令行上指定
31、很多的選項(xiàng)。輸入:help可以獲得gdb的幫助信息。 如果想要了解某個(gè)具體命令(比如break)的幫助信息,在gdb提示符下輸入下面的命令:break屏幕上會(huì)顯示關(guān)于break的幫助信息。從返回的信息可知,break是用于設(shè)置斷點(diǎn)的命令。 另一個(gè)獲得gdb幫助的方法是瀏覽gdb的手冊(cè)頁(yè)。在Linux Shell提示符輸入:man gdb可以看到man的手冊(cè)頁(yè)博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gdb命令的分類 在 gdb 提示符處鍵入help,將列出命令的分類,主要的分類有: aliases:命令別名 breakpoints:斷點(diǎn)定義; data:數(shù)據(jù)查看; files:指定并查看文件; i
32、nternals:維護(hù)命令; running:程序執(zhí)行; stack:調(diào)用棧查看; statu:狀態(tài)查看; tracepoints:跟蹤程序執(zhí)行。 后跟命令的分類名,可獲得該類命令的詳細(xì)清單 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技基本gdb命令(1/2) file命令:裝入想要調(diào)試的可執(zhí)行文件。 cd命令:改變工作目錄。 pwd命令:返回當(dāng)前工作目錄。 run命令:執(zhí)行當(dāng)前被調(diào)試的程序。 kill命令:停止正在調(diào)試的應(yīng)用程序。 list命令:列出正在調(diào)試的應(yīng)用程序的源代碼。 break命令:設(shè)置斷點(diǎn)。 watch命令:設(shè)置監(jiān)視點(diǎn),監(jiān)視表達(dá)式的變化。 awatch命令:設(shè)置讀寫監(jiān)視點(diǎn)。當(dāng)要監(jiān)視的
33、表達(dá)式被讀或?qū)憰r(shí)將應(yīng)用程序掛起。它的語(yǔ)法與watch命令相同。 rwatch命令:設(shè)置讀監(jiān)視點(diǎn),當(dāng)監(jiān)視表達(dá)式被讀時(shí)將程序掛起,等侍調(diào)試。此命令的語(yǔ)法與watch相同。 next命令:執(zhí)行下一條源代碼,但是不進(jìn)入函數(shù)內(nèi)部。也就是說(shuō),將一條函數(shù)調(diào)用作為一條語(yǔ)句執(zhí)行。執(zhí)行這個(gè)命令的前提是已經(jīng)run,開始了代碼的執(zhí)行。博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技基本gdb命令(2/2) step命令:執(zhí)行下一條源代碼,進(jìn)入函數(shù)內(nèi)部。如果調(diào)用了某個(gè)函數(shù),會(huì)跳到函數(shù)所在的代碼中等候一步步執(zhí)行。執(zhí)行這個(gè)命令的前提是已經(jīng)用run開始執(zhí)行代碼。 display命令:在應(yīng)用程序每次停止運(yùn)行時(shí)顯示表達(dá)式的值。 info
34、break命令:顯示當(dāng)前斷點(diǎn)列表,包括每個(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。 博創(chuàng)科技 嵌入互動(dòng) 200
35、6 博創(chuàng)科技gdb 使用實(shí)例(1/2) /* 一個(gè)有錯(cuò)誤的 C 源程序 */ #include #include static char buff 256; static char* string; int main () printf (Please input a string: ); gets (string); printf (nYour string is: %sn, string); 上面這個(gè)程序非常簡(jiǎn)單,其目的是接受用戶的輸入,然后將用戶的輸入打印出來(lái)。該程序使用了 一個(gè)未經(jīng)過初始化的字符串地址 string,因此,編譯并運(yùn)行之后,將出現(xiàn) Segment Fault 錯(cuò)誤: $
36、gcc -o test -g test.c $ ./test Please input a string: asfd Segmentation fault (core dumped) 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技gdb 使用實(shí)例(2/2) 為了查找該程序中出現(xiàn)的問題,我們利用 gdb,并按如下的步驟進(jìn)行: 1運(yùn)行 gdb bugging 命令,裝入 bugging 可執(zhí)行文件; 2執(zhí)行裝入的 bugging 命令; 3使用 where 命令查看程序出錯(cuò)的地方; 4利用 list 命令查看調(diào)用 gets 函數(shù)附近的代碼; 5唯一能夠?qū)е?gets 函數(shù)出錯(cuò)的因素就是變量 string。
37、用 print 命令查看 string 的值; 6在 gdb 中,我們可以直接修改變量的值,只要將 string 取一個(gè)合法的指針值就可以了,為 此,我們?cè)诘?11 行處設(shè)置斷點(diǎn); 7程序重新運(yùn)行到第 11 行處停止,這時(shí),我們可以用 set variable 命令修改 string 的取值; 8然后繼續(xù)運(yùn)行,將看到正確的程序運(yùn)行結(jié)果。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技GNU make和makefile GNU make概述 Makefile 的基本結(jié)構(gòu) Makefile中的變量 GNU make 的主要預(yù)定義變量 Makefile的隱含規(guī)則 make命令行選項(xiàng) 使用automake和a
38、utoconf產(chǎn)生Makefile 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技GNU make概述 在大型的開發(fā)項(xiàng)目中,人們通常利用 make 工具來(lái)自動(dòng)完成編譯工作。這些工作包括: 如果僅修改了某幾個(gè)源文件,則只重新編譯這幾個(gè)源文件; 如果某個(gè)頭文件被修改了,則重新編譯所有包含該頭文件的源文件。 利用這種自動(dòng)編譯可大大簡(jiǎn)化開發(fā)工作,避免不必要的重新編譯。 實(shí)際上,make 工具通過一個(gè)稱為 makefile 的文件來(lái)完成并自動(dòng)維護(hù)編譯工作。makefile 需要按照某種語(yǔ)法進(jìn)行編寫,其中說(shuō)明了如何編譯各個(gè)源文件并連接生成可執(zhí)行文件,并定義了源文件之間的依賴關(guān)系。 當(dāng)修改了其中某個(gè)源文件時(shí),如果其
39、他源文件依賴于該文件,則也要重新編譯所有依賴該文件的源文件。 默認(rèn)情況下,GNU make 工具在當(dāng)前工作目錄按如下順序搜索 makefile: GNUmakefile makefile Makefile 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技makefile舉例 在UNIX中,習(xí)慣使用makefile 作為 makfile 文件。 Linux程序員使用第三種文件名Makefile。因?yàn)榈谝粋€(gè)字母是大寫,通常被列在一個(gè)目錄的文件列表的最前面。 如果要使用其他文件作為 makefile,則可利用類 似下面的 make 命令選項(xiàng)指定 makefile 文件: $ make -f Make 例1:一
40、個(gè)簡(jiǎn)單的makefile prog:prog1.o prog2.o gcc prog1.o prog2.o -o prog prog1.o:prog1.c lib.h gcc -c -I. -o prog1.o prog1.c prog2.o:prog2.c gcc -c prog2.c 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile 的基本結(jié)構(gòu)(1/2) Makefile是一個(gè)文本形式的數(shù)據(jù)庫(kù)文件,其中包含一些規(guī)則來(lái)告訴make處理哪些文件以及如何處理這些文件。 規(guī)則主要是描述哪些文件(稱為target目標(biāo)文件,不要和編譯時(shí)產(chǎn)生的目標(biāo)文件相混淆)是從哪些別的文件(稱為dependen
41、cy依賴文件)中產(chǎn)生的,以及用什么命令(command)來(lái)執(zhí)行這個(gè)過程。 依靠這些信息,make會(huì)對(duì)磁盤上的文件進(jìn)行檢查,如果目標(biāo)文件的生成或被改動(dòng)時(shí)的時(shí)間(稱為該文件時(shí)間戳)至少比它的一個(gè)依賴文件還舊的話,make就執(zhí)行相應(yīng)的命令,以更新目標(biāo)文件。 目標(biāo)文件不一定是最后的可執(zhí)行文件,可以是任何一個(gè)中間文件并可以作為其他目標(biāo)文件的依賴文件。博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile 的基本結(jié)構(gòu)(2/2) Makefile規(guī)則的一般形式如下:target:dependency dependency(tab) 一個(gè)Makefile文件主要含有一系列的規(guī)則,每條規(guī)則包含以下內(nèi)容。 一個(gè)目
42、標(biāo)(target),即make最終需要?jiǎng)?chuàng)建的文件,如可執(zhí)行文件和目標(biāo)文件;目標(biāo)也可以是要執(zhí)行的動(dòng)作,如“clean”。 一個(gè)或多個(gè)依賴文件(dependency)列表,通常是編譯目標(biāo)文件所需要的其他文件。 一系列命今(command),是make執(zhí)行的動(dòng)作,通常是把指定的相關(guān)文件編譯成目標(biāo)文件的編譯命令,每個(gè)命令占一行,且每個(gè)命令行的起始字符必須為TAB字符。 除非特別指定,否則make的工作目錄就是當(dāng)前目錄。target是需要?jiǎng)?chuàng)建的二進(jìn)制文件或目標(biāo)文件,dependency是在創(chuàng)建target時(shí)需要用到的一個(gè)或多個(gè)文件的列表,命令序列是創(chuàng)建target文件所需要執(zhí)行的步驟,比如編譯命令。 博
43、創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile實(shí)例(1/3)# 以#開頭的為注釋行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):test、prog.o、code.o和clean。 目標(biāo)從每行的最左邊開始寫,后面跟一個(gè)冒號(hào)(:),如果有與這個(gè)目標(biāo)有依賴性的其他目標(biāo)或文件,把它們列在冒號(hào)后面,并以空
44、格隔開。然后另起一行開始寫實(shí)現(xiàn)這個(gè)目標(biāo)的一組命令。 在Makefile中,可使用續(xù)行號(hào)()將一個(gè)單獨(dú)的命令行延續(xù)成幾行。但要注意在續(xù)行號(hào)()后面不能跟任何字符(包括空格和鍵)博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile實(shí)例(2/3) 一般情況下,調(diào)用make命令可輸入: # make target target是Makefile文件中定義的目標(biāo)之一,如果省略target,make就將生成Makefile文件中定義的第一個(gè)目標(biāo)。 對(duì)于上面Makefile的例子,單獨(dú)的一個(gè)“make”命令等價(jià)于: # make test 因?yàn)閠est是Makefile文件中定義的第一個(gè)目標(biāo),make首先
45、將其讀入,然后從第一行開始執(zhí)行,把第一個(gè)目標(biāo)test作為它的最終目標(biāo),所有后面的目標(biāo)的更新都會(huì)影響到test的更新。 第一條規(guī)則說(shuō)明只要文件test的時(shí)間戳比文件prog.o或code.o中的任何一個(gè)舊,下一行的編譯命令將會(huì)被執(zhí)行。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile實(shí)例(3/3) 但是,在檢查文件prog.o和code.o的時(shí)間戳之前,make會(huì)在下面的行中尋找以prog.o和code.o為目標(biāo)的規(guī)則,在第三行中找到了關(guān)于prog.o的規(guī)則,該文件的依賴文件是prog.c、prog.h和code.h。同樣,make會(huì)在后面的規(guī)則行中繼續(xù)查找這些依賴文件的規(guī)則,如果找不到,
46、則開始檢查這些依賴文件的時(shí)間戳,如果這些文件中任何一個(gè)的時(shí)間戳比prog.o的新,make將執(zhí)行“gcc c prog.c o prog.o”命令,更新prog.o文件。 以同樣的方法,接下來(lái)對(duì)文件code.o做類似的檢查,依賴文件是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的例子中,還定義了一
47、個(gè)目標(biāo)clean,它是Makefile中常用的一種專用目標(biāo),即刪除所有的目標(biāo)模塊博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技make的工作過程 現(xiàn)在來(lái)看一下make做的工作: 首先make按順序讀取makefile中的規(guī)則, 然后檢查該規(guī)則中的依賴文件與目標(biāo)文件的時(shí)間戳哪個(gè)更新 如果目標(biāo)文件的時(shí)問戳比依賴文件還早,就按規(guī)則中定義的命令更新目標(biāo)文件。 如果該規(guī)則中的依賴文件又是其他規(guī)則中的目標(biāo)文件,那么依照規(guī)則鏈不斷執(zhí)行這個(gè)過程,直到Makefile文件的結(jié)束,至少可以找到一個(gè)不是規(guī)則生成的最終依賴文件,獲得此文件的時(shí)間戳 然后從下到上依照規(guī)則鏈執(zhí)行目標(biāo)文件的時(shí)間戳比此文件時(shí)間戳舊的規(guī)則,直到最頂層的
48、規(guī)則 通過以上的分析過程,可以看到make的優(yōu)點(diǎn),因?yàn)?o目標(biāo)文件依賴.c源文件,源碼文件里一個(gè)簡(jiǎn)單改變都會(huì)造成那個(gè)文件被重新編譯,并根據(jù)規(guī)則鏈依次由下到上執(zhí)行編譯過程,直到最終的可執(zhí)行文件被重新連接。 例如,當(dāng)改變一個(gè)頭文件的時(shí)候,由于所有的依賴關(guān)系都在Makefile里,因此不再需要記住依賴此頭文件的所有源碼文件,make可以自動(dòng)的重新編譯所有那些因依賴這個(gè)頭文件而改變了的源碼文件,如果需要,再進(jìn)行重新連接博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile中的變量 Makefile里的變量就像一個(gè)環(huán)境變量。事實(shí)上,環(huán)境變量在make中也被解釋成make的變量。這些變量對(duì)大小寫敏感,一般
49、使用大寫宇母。幾乎可以從任何地方引用定義的變量,變量的主要作用如下: 保存文件名列表。在前面的例子里,作為依賴文件的一些目標(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渌械胤降拿蠲投几淖兞恕?/p>
50、 保存編譯器的參數(shù)。在很多源代碼編譯時(shí),gcc需要很長(zhǎng)的參數(shù)選項(xiàng),在很多情況下,所有的編譯命令使用一組相同的選項(xiàng),如果把這組選項(xiàng)使用一個(gè)變量代表,那么可以把這個(gè)變量放在所有引用編譯器的地方。當(dāng)要改變選項(xiàng)的時(shí)候,只需改變一次這個(gè)變量的內(nèi)容即可。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技變量的定義和使用 Makefile中的變量是用一個(gè)文本串在Makefile中定義的,這個(gè)文本串就是變量的值。只要在一行的開始寫下這個(gè)變量的名字,后面跟一個(gè)“”號(hào),以及要設(shè)定這個(gè)變量的值即可定義變量,下面是定義變量的語(yǔ)法:VARNAME=string 使用時(shí),把變量用括號(hào)括起來(lái),并在前面加上$符號(hào),就可以引用變量的值:
51、 $VARNAME make解釋規(guī)則時(shí),VARNAME在等式右端展開為定義它的字符串。 變量一般都在Makefile的頭部定義。按照慣例,所有的Makefile變量都應(yīng)該是大寫。如果變量的值發(fā)生變化,就只需要在一個(gè)地方修改,從而簡(jiǎn)化了Makefile的維護(hù)。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile變量舉例 現(xiàn)在利用變量把前面的Makefile重寫一遍: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:co
52、de.c code.h$ CC c code.c o code.o clean:rm f *.o 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技變量的類型 除用戶自定義的變量外,make還允許使用 環(huán)境變量 使用環(huán)境變量的方法很簡(jiǎn)單,在make啟動(dòng)時(shí),make讀取系統(tǒng)當(dāng)前已定義的環(huán)境變量,并且創(chuàng)建與之同名同值的變量,因此用戶可以像在shell中一樣在Makefile中方便的引用環(huán)境變量。 需要注意的是,如果用戶在Makefile中定義了同名的變量,用戶自定義變量將覆蓋同名的環(huán)境變量 自動(dòng)變量 預(yù)定義變量博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技GNU make 的主要預(yù)定義變量(1/2) $* 不包含擴(kuò)展
53、名的目標(biāo)文件名稱。 $+ 所有的依賴文件,以空格分開,并以出現(xiàn)的先后為序,可能包含重復(fù)的依賴文件。 $ 第一個(gè)依賴文件的名稱。 $? 所有的依賴文件,以空格分開,這些依賴文件的修改日期比目標(biāo)的創(chuàng)建日期晚。 $ 目標(biāo)的完整名稱。 $ 所有的依賴文件,以空格分開,不包含重復(fù)的依賴文件。 $% 如果目標(biāo)是歸檔成員,則該變量表示目標(biāo)的歸檔成員名稱。例如,如果目標(biāo)名稱 為 mytarget.so(image.o),則 $ 為 mytarget.so,而 $% 為 image.o。 AR 歸檔維護(hù)程序的名稱,默認(rèn)值為 ar。 ARFLAGS 歸檔維護(hù)程序的選項(xiàng)。 AS 匯編程序的名稱,默認(rèn)值為 as。 A
54、SFLAGS 匯編程序的選項(xiàng)。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技GNU make 的主要預(yù)定義變量(2/2) CC C 編譯器的名稱,默認(rèn)值為 cc。 CFLAGS C 編譯器的選項(xiàng)。 CPP C 預(yù)編譯器的名稱,默認(rèn)值為 $(CC) -E。 CPPFLAGS C 預(yù)編譯的選項(xiàng)。 CXX C+ 編譯器的名稱,默認(rèn)值為 g+。 CXXFLAGS C+ 編譯器的選項(xiàng)。 FC FORTRAN 編譯器的名稱,默認(rèn)值為 f77。 FFLAGS FORTRAN 編譯器的選項(xiàng)。博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技Makefile的隱含規(guī)則 在上面的例子中,幾個(gè)產(chǎn)生目標(biāo)文件的命令都是從“.c”的C語(yǔ)言
55、源文件和相關(guān)文件通過編譯產(chǎn)生“.o”目標(biāo)文件,這也是一般的步驟。實(shí)際上,make可以使工作更加自動(dòng)化,也就是說(shuō),make知道一些默認(rèn)的動(dòng)作,它有一些稱作隱含規(guī)則的內(nèi)置的規(guī)則,這些規(guī)則告訴make當(dāng)用戶沒有完整地給出某些命令的時(shí)候,應(yīng)該怎樣執(zhí)行。 例如,把生成prog.o和code.o的命令從規(guī)則中刪除,make將會(huì)查找隱含規(guī)則,然后會(huì)找到并執(zhí)行一個(gè)適當(dāng)?shù)拿?。由于這些命令會(huì)使用一些變量,因此可以通過改變這些變量來(lái)定制make。象在前面的例子中所定義的那樣,make使用變量CC來(lái)定義編譯器,并且傳遞變量CFLAGS(編譯器參數(shù))、CPPFLAGS(C語(yǔ)言預(yù)處理器參數(shù))、TARGET_ARCH(目
56、標(biāo)機(jī)器的結(jié)構(gòu)定義)給編譯器,然后加上參數(shù)-c,后面跟變量$(第一個(gè)依賴文件名),然后是參數(shù)-o加變量$(目標(biāo)文件名)。 綜上所述,一個(gè)C編譯的具體命令將會(huì)是:$ CC $ CFLAGS $ CPPFLAGS $ TARGET_ARCH c $ -o $博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技隱含規(guī)則舉例 在上面的例子中,利用隱含規(guī)則,可以簡(jiǎn)化為: OBJS=prog.o code.o CC=gcc test:$ OBJS $ CC o $ $ prog.o:prog.c prog.h code.h code.o:code.c code.h clean:rm f *.o 博創(chuàng)科技 嵌入互動(dòng) 200
57、6 博創(chuàng)科技make命令行選項(xiàng) 直接在 make 命令的后面鍵入目標(biāo)名可建立指定的目標(biāo),如果直接運(yùn)行 make,則建立第一個(gè)目標(biāo)。還可以用 make -f mymakefile 這樣的命令指定 make 使用特定的 makefile,而不是 默認(rèn)的 GNUmake 或 Makefile。 GNU make 命令還有一些其他選項(xiàng),下面是 GNU make 命令的常用命令行選項(xiàng)命令行選項(xiàng)含義: -C DIR 在讀取 makefile 之前改變到指定的目錄 DIR。 -f FILE 以指定的 FILE 文件作為 makefile。 -h 顯示所有的 make 選項(xiàng)。 -i 忽略所有的命令執(zhí)行錯(cuò)誤。
58、-I DIR 當(dāng)包含其他 makefile 文件時(shí),可利用該選項(xiàng)指定搜索目錄。 -n 只打印要執(zhí)行的命令,但不執(zhí)行這些命令。 -p 顯示 make 變量數(shù)據(jù)庫(kù)和隱含規(guī)則。 -s 在執(zhí)行命令時(shí)不顯示命令。 -w 在處理 makefile 之前和之后,顯示工作目錄。 -W FILE 假定文件 FILE 已經(jīng)被修改。 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技使用automake和autoconf產(chǎn)生Makefile 在開始使用Automake和autoconf之前,請(qǐng)先確認(rèn)系統(tǒng)已經(jīng)安裝以下的軟件: GNU Automake GNU Autoconf GNU m4 Perl GNU Libtool (如
59、果你需要產(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ō)明。博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技生成一個(gè)源程序 在工作目錄下建立一個(gè)新的子目錄devel,再在devel下建立一個(gè)hello的子目錄,這個(gè)目錄將作為存放 hello 這個(gè)程序及其相關(guān)文件的地方: 用編輯器寫個(gè)hello.c文件: #include int main(int argc, char* argv) prin
60、tf(Hello, GNU!n); return 0; 博創(chuàng)科技 嵌入互動(dòng) 2006 博創(chuàng)科技使用 Autoconf 及 Automake 來(lái)產(chǎn)生Makefile文件的步驟 autoscan 產(chǎn)生一個(gè)configure.in的模板,執(zhí)行 autoscan 后會(huì)產(chǎn)生一個(gè)configure.scan 的文件,可以用它做為configure.in文件的模板: 編輯configure.scan文件,如下所示,并且把文件名改成configure.in 執(zhí)行aclocal和autoconf ,分別會(huì)產(chǎn)生 aclocal.m4 及 configure 兩個(gè)文件: 編輯Make文件,內(nèi)容如下: 執(zhí)行autom
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 抵債資產(chǎn)稅務(wù)培訓(xùn)課件
- 長(zhǎng)春醫(yī)學(xué)高等??茖W(xué)?!毒坝^設(shè)計(jì)》2023-2024學(xué)年第二學(xué)期期末試卷
- 基于AI技術(shù)的在線教育資源自動(dòng)評(píng)測(cè)機(jī)制研究
- 提升學(xué)習(xí)成效教學(xué)策略與學(xué)習(xí)動(dòng)機(jī)的融合
- 無(wú)錫科技職業(yè)學(xué)院《名師成長(zhǎng)案例》2023-2024學(xué)年第二學(xué)期期末試卷
- 游戲化交互設(shè)計(jì)在商業(yè)會(huì)議中的運(yùn)用
- 遼寧冶金職業(yè)技術(shù)學(xué)院《國(guó)際投資》2023-2024學(xué)年第二學(xué)期期末試卷
- 湘潭醫(yī)衛(wèi)職業(yè)技術(shù)學(xué)院《創(chuàng)意圖像設(shè)計(jì)》2023-2024學(xué)年第二學(xué)期期末試卷
- 2024年度浙江省三支一扶之三支一扶行測(cè)自我檢測(cè)試卷B卷附答案
- 2024年度河南省護(hù)師類之社區(qū)護(hù)理主管護(hù)師考前自測(cè)題及答案
- 工程量計(jì)算書(全部)
- 經(jīng)偵總論試題
- 陜西省安康市教育聯(lián)盟2023-2024學(xué)年高一下學(xué)期期末考試數(shù)學(xué)試卷
- 2023-2024學(xué)年景德鎮(zhèn)市珠山區(qū)數(shù)學(xué)五年級(jí)第二學(xué)期期末監(jiān)測(cè)試題含解析
- 小鎮(zhèn)文旅康養(yǎng)項(xiàng)目可研報(bào)告【健康養(yǎng)老】【旅游康養(yǎng)】
- 2024廣西公需課高質(zhì)量共建“一帶一路”譜寫人類命運(yùn)共同體新篇章答案
- EHS專項(xiàng)施工EHS管理組織機(jī)構(gòu)
- 2024年南安市國(guó)有資本投資運(yùn)營(yíng)有限責(zé)任公司招聘筆試沖刺題(帶答案解析)
- T/CEC 143-2017 超高性能混凝土電桿完整
- MOOC 工程電磁場(chǎng)與波-浙江大學(xué) 中國(guó)大學(xué)慕課答案
- 清罐應(yīng)急預(yù)案
評(píng)論
0/150
提交評(píng)論