




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第第3章章Linux系統(tǒng)C語(yǔ)言開(kāi)發(fā)工具2 本章重點(diǎn)q Linux環(huán)境下C程序的編輯、編譯、運(yùn)行q gcc的編譯過(guò)程q 編譯參數(shù)-I、 -L的使用q 靜態(tài)函數(shù)庫(kù)與共享庫(kù)q make工程文件q gdb調(diào)試工具的使用3 本章導(dǎo)讀q C語(yǔ)言是Linux系統(tǒng)最常用的編程語(yǔ)言之一q Linux內(nèi)核絕大部分用C語(yǔ)言編寫q 開(kāi)發(fā)人員通過(guò)函數(shù)庫(kù)、系統(tǒng)調(diào)用實(shí)現(xiàn)系統(tǒng)服務(wù)q Linux系統(tǒng)擁有許多程序生成和分析的工具4 3.1 第一個(gè)Linux環(huán)境下的C語(yǔ)言程序q 例3.1 編寫一個(gè)簡(jiǎn)單的C語(yǔ)言程序,在屏幕上打印5行“Hello, Linux World”gcc編譯器編譯C程序的常用格式:gcc 源文件 -o 可執(zhí)行
2、文件gcc -o 可執(zhí)行文件 源文件gcc 源文件 (可執(zhí)行文件名默認(rèn)為a.out)5 3.1 第一個(gè)Linux環(huán)境下的C語(yǔ)言程序q 例3.1 編寫一個(gè)簡(jiǎn)單的C語(yǔ)言程序,在屏幕上打印5行“Hello, Linux World”(續(xù))6 3.1 第一個(gè)Linux環(huán)境下的C語(yǔ)言程序q 例3.1 編寫一個(gè)簡(jiǎn)單的C語(yǔ)言程序,在屏幕上打印5行“Hello, Linux World”(續(xù))7 3.2 編譯C語(yǔ)言程序3.2.1 gcc編譯器q gcc編譯器是Linux平臺(tái)上應(yīng)用最廣泛的C編譯器;g+編譯器用于編譯C+程序,但是g+內(nèi)部還是調(diào)用了gccq 執(zhí)行g(shù)cc命令時(shí),它將完成“預(yù)處理預(yù)處理”、“編譯編譯
3、”、“匯編匯編”、“鏈鏈接接”4個(gè)步驟,并生成可執(zhí)行代碼。q gcc命令可以接受多種文件類型,并依據(jù)用戶指定的命令行參數(shù)做出處理后綴名對(duì)應(yīng)的語(yǔ)言后綴名對(duì)應(yīng)的語(yǔ)言.cC原始程序.ii經(jīng)過(guò)預(yù)處理的C+程序.CC+原始程序.s匯編語(yǔ)言程序匯編語(yǔ)言程序.ccC+原始程序.S匯編語(yǔ)言程序.cxxC+原始程序.h預(yù)處理文件(頭文件).mObjective-C原始程序.o二進(jìn)制文件(目標(biāo)文件)二進(jìn)制文件(目標(biāo)文件).i經(jīng)過(guò)預(yù)處理的經(jīng)過(guò)預(yù)處理的C程序程序.a/.so編譯后的庫(kù)文件(無(wú)后綴)(無(wú)后綴) 一般指可執(zhí)行文件一般指可執(zhí)行文件83.2.1 gcc編譯器q gcc編譯流程如右圖所示;各種參數(shù)有助于程序員靈
4、活地控制整個(gè)編譯過(guò)程源代碼(*.c文件)預(yù)處理(預(yù)處理(Pre-processing),選項(xiàng)),選項(xiàng)-E編譯(編譯(Compiling),選項(xiàng)),選項(xiàng)-S匯編(匯編(Assembling),選項(xiàng)),選項(xiàng)-c鏈接(鏈接(Linking),選項(xiàng)),選項(xiàng)-o生成預(yù)處理過(guò)的文件.i生成匯編語(yǔ)言文件.s生成二進(jìn)制文件.o鏈接生成可執(zhí)行文件 3.2 編譯C語(yǔ)言程序9 3.2 編譯C語(yǔ)言程序3.2.1 gcc編譯器q gcc命令的使用格式:gcc options filename-listoptions常用選項(xiàng)有:-ansi 依據(jù)ANSI標(biāo)準(zhǔn)-c 不執(zhí)行鏈接步驟,編譯生成目標(biāo)文件(.o)-g 創(chuàng)建用于gdb
5、(GNU DeBugger)的符號(hào)表和調(diào)試信息-l 庫(kù)文件名 鏈接庫(kù)文件-m 類型 根據(jù)給定的CPU類型優(yōu)化代碼-o 文件名 將生成的可執(zhí)行程序保存為指定的文件-O 級(jí)別 根據(jù)指定的級(jí)別(0-3)進(jìn)行優(yōu)化;級(jí)別為0,則不做任何優(yōu)化-pg 產(chǎn)生供GNU剖析工具gprof使用的信息-S 不執(zhí)行匯編和鏈接階段,并保留編譯產(chǎn)生的匯編代碼(.s文件)10 3.2 編譯C語(yǔ)言程序3.2.1 gcc編譯器q gcc命令的使用格式:options常用選項(xiàng)有:(續(xù))-v 產(chǎn)生盡可能多的輸出信息-w 忽略警告信息-W 產(chǎn)生比默認(rèn)模式更多的警告信息q gcc的每個(gè)選項(xiàng)前需要有連字符 -q gcc不能在一個(gè)連字符后跟
6、一組選項(xiàng)例如gcc -p -g hello.c 與gcc -pg hello.c 含義不同11 3.2 編譯C語(yǔ)言程序3.2.1 gcc編譯器q 例:選項(xiàng) -c 的用法附:在多文件C/C+程序中,全局變量只能在一個(gè)文件中被定義,在其它文件中應(yīng)被聲明為“外部變量”/對(duì)全局變量a進(jìn)行了聲明/對(duì)全局函數(shù)PrintA進(jìn)行了聲明/定義了全局變量a/定義了全局函數(shù)PrintA12 3.2 編譯C語(yǔ)言程序3.2.1 gcc編譯器q 例:選項(xiàng) -c 的用法(續(xù)) 使用 -c 選項(xiàng)編譯生成目標(biāo)文件;然后鏈接目標(biāo)文件,生成可執(zhí)行文件 鏈接時(shí),鏈接器在a.o中找到變量a和函數(shù)PrintA13 3.2 編譯C語(yǔ)言程序
7、3.2.2 gcc編譯流程q gcc編譯流程如下圖所示:源代碼(*.c文件)預(yù)處理(Pre-processing)編譯(Compiling)匯編(Assembling)鏈接(Linking)可執(zhí)行文件14 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 預(yù)處理預(yù)處理/預(yù)編譯預(yù)編譯:在真正開(kāi)始對(duì)程序編譯之前,先對(duì)源程序進(jìn)行一番處理,形成臨時(shí)的源程序文件。預(yù)處理的功能主要有: 符號(hào)常量的定義和宏定義符號(hào)常量的定義和宏定義例如#define MAX_NUM 1000#define UNIVERSITY_NAME “NWSUAF”15 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q
8、 預(yù)處理預(yù)處理/預(yù)編譯預(yù)編譯:(續(xù)) 文件包含文件包含例如#include /如果不包含該頭文件,則printf語(yǔ)句出錯(cuò) 通過(guò)#include命令能夠?qū)⒈话奈募ㄒ话惴Q為頭文件)的全部?jī)?nèi)容插入到#include命令的位置,此即預(yù)處理階段需要做的事情。 復(fù)雜程序常常由多個(gè).c文件組成,這些文件可能都會(huì)使用某個(gè)函數(shù),則1. 將該函數(shù)的定義編寫在某個(gè).c文件中;2. 將函數(shù)的聲明編寫在一個(gè)頭文件中;3. 在用到該函數(shù)的.c文件中包含該頭文件16 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 例/”表示首先到當(dāng)前文件夾下找頭文件,/再到編譯器指定的文件夾下找頭文件庫(kù)函數(shù)文件主函數(shù)文件頭
9、文件未出現(xiàn)17 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 預(yù)處理預(yù)處理/預(yù)編譯預(yù)編譯: 符號(hào)常量的定義和宏定義 文件包含 條件編譯條件編譯18 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 編譯編譯: 檢查語(yǔ)法錯(cuò)誤,若無(wú)語(yǔ)法錯(cuò)誤,生成中間的目標(biāo)文件(.o或.obj文件) 多個(gè).c文件組成的程序,每個(gè).c文件都會(huì)被編譯生成一個(gè).o文件 .o文件中存放的是所對(duì)應(yīng)的.c文件中的全局變量、靜態(tài)變量的名稱、地址等,以及在.c文件中編寫的全部函數(shù)的可執(zhí)行機(jī)器指令 若a.c有語(yǔ)法錯(cuò)誤,不會(huì)影響b.c被編譯成b.o,例如19 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q
10、 編譯編譯: 若a.c有語(yǔ)法錯(cuò)誤,不會(huì)影響b.c被編譯成b.o,例如(續(xù))修正b.c之后,20 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 鏈接鏈接: 頭文件中一般只有庫(kù)函數(shù)的聲明,沒(méi)有庫(kù)函數(shù)的函數(shù)體。 庫(kù)函數(shù)的源代碼編譯器廠家不一定會(huì)提供給用戶,但是會(huì)提供庫(kù)函數(shù)經(jīng)過(guò)編譯后的中間結(jié)果。 編譯器的安裝文件夾下往往都會(huì)有一個(gè)lib文件夾,里面放著后綴是”.lib”、”.obj”的文件,這些文件中包含很多庫(kù)函數(shù)的機(jī)器指令(即實(shí)現(xiàn)方式)。 鏈接階段,編譯器會(huì)抽取庫(kù)函數(shù)的機(jī)器指令,合并到可執(zhí)行文件中去。 有些軟件廠商專門出售函數(shù)庫(kù),如高效的圖形處理函數(shù)庫(kù)、科學(xué)計(jì)算函數(shù)庫(kù)、視頻編解碼函數(shù)庫(kù)等
11、;用戶買到函數(shù)庫(kù)后,在程序中包含聲明庫(kù)函數(shù)的頭文件,且需要在鏈接選項(xiàng)中指定要鏈接哪些.lib文件或.obj文件 綜上,鏈接就是把編譯出來(lái)的多個(gè).o文件拼在一起,并抽取一系列相關(guān)庫(kù)函數(shù)的機(jī)器指令,合并形成可執(zhí)行文件。21 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 例例3.3 輸入兩個(gè)整數(shù),輸出求和后的結(jié)果。使用-E、-S、-c、-o選項(xiàng),控制gcc的編譯流程。 步驟1:編寫源代碼22 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 例例3.3(續(xù))(續(xù)) 步驟2:預(yù)處理階段 在該步驟中,編譯器將”stdio.h”文件包含進(jìn)來(lái),插入到#include 位置處。 使用 E
12、控制編譯流程:當(dāng)預(yù)處理完成后即停止編譯流程。23 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 例例3.3(續(xù))(續(xù)) 步驟2:預(yù)處理階段(續(xù)) 預(yù)處理后的程序3-3.i的部分內(nèi)容如下:/可參閱stdio.h的內(nèi)容24 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 例例3.3(續(xù))(續(xù)) 步驟3:編譯階段 首先檢查代碼的規(guī)范性、正確性;檢查無(wú)誤后,把代碼翻譯為匯編語(yǔ)言;使用參數(shù)”-S”控制編譯流程,產(chǎn)生匯編代碼。25 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 例例3.3(續(xù))(續(xù)) 步驟4:匯編階段 把編譯階段生成的”.s”文件轉(zhuǎn)成”.o”文件(二進(jìn)制代
13、碼)。用參數(shù)”-c”控制編譯流程:匯編結(jié)束后即停止編譯流程。26 3.2 編譯C語(yǔ)言程序3.2.2 gcc編譯流程(續(xù))q 例例3.3(續(xù))(續(xù)) 步驟5:鏈接階段 預(yù)處理階段已將頭文件stdio.h包含進(jìn)來(lái),其中有printf、scanf的聲明; 鏈接階段需要查找相應(yīng)的庫(kù)文件(例如/usr/lib下的libc.so.6庫(kù)文件),將printf、scanf鏈接到庫(kù)函數(shù)中,即找到printf、scanf的實(shí)現(xiàn)細(xì)節(jié); 完成鏈接后,生成可執(zhí)行程序注:gcc默認(rèn)使用動(dòng)態(tài)鏈接庫(kù)(另見(jiàn)P118頁(yè)“共享庫(kù)”的描述),即在編譯鏈接時(shí)并不把庫(kù)文件的代碼加入可執(zhí)行文件,而是在程序執(zhí)行時(shí)動(dòng)態(tài)加載鏈接庫(kù),以節(jié)省系統(tǒng)開(kāi)
14、銷。27 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)q gcc有100多個(gè)可用參數(shù),主要分為 總體參數(shù) 告警和出錯(cuò)參數(shù) 優(yōu)化參數(shù) 28 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))1. 總體參數(shù) 參數(shù)含義參數(shù)含義-c只匯編不鏈接,生成二進(jìn)制目標(biāo)文件-v顯示gcc的版本信息-S只編譯不匯編,生成匯編代碼-I dir在頭文件的搜索路徑中添加dir目錄-E只進(jìn)行預(yù)編譯-L dir在庫(kù)文件的搜索路徑列表中添加dir目錄-g在可執(zhí)行程序中包含調(diào)試信息-static鏈接靜態(tài)庫(kù)-o file把文件輸出至file中-llibrary鏈接名稱為library的庫(kù)文件29 3.2
15、編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù)) 例3.4 設(shè)計(jì)一個(gè)程序(3-4.c),把從鍵盤輸入的字符串按照原樣輸出到屏幕上,把標(biāo)準(zhǔn)輸入輸出庫(kù)文件放在自定義的頭文件(my.h)中,且該頭文件位于當(dāng)前目錄下。/自定義頭文件,包含標(biāo)準(zhǔn)輸入輸出庫(kù)/gcc在默認(rèn)的目錄”usr/include”中找不/到”my.h”文件,因此需要用”-I dir”選項(xiàng)/表示在默認(rèn)路徑/usr/include”中搜索頭文件30 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù)) 例3.4 (續(xù))/”表示首先在當(dāng)前目錄中搜索頭文件,然后再到/編譯器指定的文件夾下搜索頭文件。/無(wú)需加入”-I dir”選
16、項(xiàng)31 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))2. 警告和出錯(cuò)參數(shù) 參數(shù)含義-ansi僅支持符合 ANSI 的 C 程序-pedantic允許發(fā)出 ANSI C 標(biāo)準(zhǔn)所列的全部警告信息-pedantic-error允許發(fā)出 ANSI C 標(biāo)準(zhǔn)所列的全部錯(cuò)誤信息-w關(guān)閉所有警告-Wall允許發(fā)出gcc提供的所有有用的警告信息-werror把所有的警告信息轉(zhuǎn)化為錯(cuò)誤信息,并在警告發(fā)生時(shí)終止編譯32 3.2 編譯C語(yǔ)言程序補(bǔ)充:ANSI C和ISO C的歷史 C 的第一個(gè)標(biāo)準(zhǔn)是由ANSI(美國(guó)國(guó)家標(biāo)準(zhǔn)協(xié)會(huì))發(fā)布的。這份文檔后來(lái)被國(guó)際標(biāo)準(zhǔn)化組織(ISO)采納并且修訂。名稱ANS
17、I C被廣泛使用,也有人使用ISO C 或 Standard C。C89 1983年,為了創(chuàng)立 C 語(yǔ)言的標(biāo)準(zhǔn),美國(guó)國(guó)家標(biāo)準(zhǔn)協(xié)會(huì)(ANSI)組成了委員會(huì)(X3J11),經(jīng)過(guò)漫長(zhǎng)而艱苦的過(guò)程,該標(biāo)準(zhǔn)于1989年完成,一般簡(jiǎn)稱為C89標(biāo)準(zhǔn),也被稱作ANSI C。C90 1990年,ANSI C89標(biāo)準(zhǔn)被國(guó)際標(biāo)準(zhǔn)化組織(ISO)和國(guó)際電工委員會(huì)(IEC)采納為國(guó)際標(biāo)準(zhǔn),簡(jiǎn)稱C90標(biāo)準(zhǔn)。C89和C90通常指同一個(gè)標(biāo)準(zhǔn),C89這種說(shuō)法更常用。C99 2000年3月,國(guó)際標(biāo)準(zhǔn)化組織(ISO)和國(guó)際電工委員會(huì)(IEC)采納了第二個(gè)C語(yǔ)言標(biāo)準(zhǔn),簡(jiǎn)稱C99標(biāo)準(zhǔn)。 C11 2011年12月,國(guó)際標(biāo)準(zhǔn)化組織(ISO
18、)和國(guó)際電工委員會(huì)(IEC)采納了第三個(gè)C語(yǔ)言標(biāo)準(zhǔn),簡(jiǎn)稱C11標(biāo)準(zhǔn),它是C程序語(yǔ)言的最新標(biāo)準(zhǔn)。 33 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))p 例3.6 設(shè)計(jì)一個(gè)程序,使它包含一些非標(biāo)準(zhǔn)語(yǔ)法。熟悉gcc的警告和出錯(cuò)參數(shù)的用法。 編輯源代碼 關(guān)閉所有警告34 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))p 例3.6 設(shè)計(jì)一個(gè)程序,使它包含一些非標(biāo)準(zhǔn)語(yǔ)法。熟悉gcc的警告和出錯(cuò)參數(shù)的用法。(續(xù)) 顯示不符合ANSI C語(yǔ)法標(biāo)準(zhǔn)的警告信息。 允許發(fā)出ANSI C標(biāo)準(zhǔn)所列的全部警告信息35 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))p 例3
19、.6 設(shè)計(jì)一個(gè)程序,使它包含一些非標(biāo)準(zhǔn)語(yǔ)法。熟悉gcc的警告和出錯(cuò)參數(shù)的用法。(續(xù)) 允許發(fā)出gcc提供的所有有用的警告信息36 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))3. 優(yōu)化參數(shù) 代碼優(yōu)化指的是編譯器通過(guò)分析源代碼,找出其中尚未達(dá)到性能最優(yōu)的部分,繼而對(duì)其進(jìn)行重新組合,目的在于改善程序的執(zhí)行性能。37 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))3. 優(yōu)化參數(shù)(續(xù)) 38 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))3. 優(yōu)化參數(shù)(續(xù)) 39 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))3. 優(yōu)化參數(shù)(續(xù)) 注:
20、也可以通過(guò)-S選項(xiàng),分別生成優(yōu)化前后的匯編代碼,比較其異同。40 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))3. 優(yōu)化參數(shù)(續(xù)) gcc提供的代碼優(yōu)化功能非常強(qiáng)大,通過(guò)參數(shù)”-On”來(lái)優(yōu)化代碼,其中n代表優(yōu)化級(jí)別,如0、1、2、3、s-O0:關(guān)閉所有的優(yōu)化選項(xiàng),通常不建議這樣做-O1:最基本的優(yōu)化等級(jí),不花費(fèi)太多編譯時(shí)間,試圖生成更快、更小的代碼-O2:不增大體積、不占用太多編譯時(shí)間,試圖提高代碼性能;-O2在效率與安全性方面取得了較好的平衡,推薦使用。-O3:最危險(xiǎn)的優(yōu)化等級(jí)。增大體積、更耗內(nèi)存、延長(zhǎng)編譯時(shí)間,增加編譯失敗的可能。-Os:對(duì)于磁盤空間緊張或CPU緩存較小的
21、機(jī)器非常有用,但可能存在問(wèn)題,不推薦。綜上,優(yōu)化等級(jí)越高,程序的運(yùn)行速度越快,但是編譯時(shí)間、代碼體積可能越長(zhǎng),-O2在這些因素之間取得了較好的平衡。41 3.2 編譯C語(yǔ)言程序3.2.3 gcc編譯器的主要參數(shù)(續(xù))3. 優(yōu)化參數(shù)(續(xù)) 程序員要力求手工編寫高質(zhì)量的代碼,減少編譯器的優(yōu)化工作,甚至根本無(wú)需優(yōu)化。 程序開(kāi)發(fā)過(guò)程中不建議使用優(yōu)化參數(shù),只有當(dāng)軟件發(fā)行或開(kāi)發(fā)結(jié)束時(shí),對(duì)最終生成的代碼進(jìn)行優(yōu)化。 資源受限時(shí)(例如在一些實(shí)時(shí)嵌入式設(shè)備中內(nèi)存資源非常緊張),不建議對(duì)代碼進(jìn)行優(yōu)化 跟蹤調(diào)試時(shí),優(yōu)化可能使代碼被刪除、改寫或重組等,從而使跟蹤和調(diào)試變得異常困難,不建議使用。42 3.2 編譯C語(yǔ)言程
22、序3.2.4 函數(shù)庫(kù) 函數(shù)庫(kù)是一組預(yù)先編譯好的函數(shù)的集合,通常以靜態(tài)庫(kù)、共享庫(kù)兩種格式存在。 標(biāo)準(zhǔn)系統(tǒng)庫(kù)文件一般存放在/lib 和 /usr/lib 目錄中;對(duì)于自定義的庫(kù)文件,需要指明其所在目錄和文件名稱 庫(kù)文件總是以lib開(kāi)頭,之后的內(nèi)容指明該庫(kù)是什么庫(kù):c代表C語(yǔ)言庫(kù)m代表數(shù)學(xué)庫(kù) . 后的內(nèi)容指明庫(kù)文件的類型:.a 代表傳統(tǒng)的靜態(tài)函數(shù)庫(kù),例如libm.a為靜態(tài)數(shù)學(xué)函數(shù)庫(kù).so 代表共享的函數(shù)庫(kù)3.2.4 函數(shù)庫(kù)指明編譯器所要搜索的庫(kù)文件的兩種方式: 給出完整的路徑名給出完整的路徑名例如:gcc o hello hello.c /usr/lib/x86_64-linux-gnu/libm.
23、a表明除了搜索標(biāo)準(zhǔn)的C函數(shù)庫(kù)之外,還需搜索數(shù)學(xué)庫(kù) 使用使用 -l 、-L 選項(xiàng)選項(xiàng)例如:gcc -o hello hello.c -lm 表明搜索標(biāo)準(zhǔn)庫(kù)目錄中的libm.a(靜態(tài)庫(kù))或libm.so(動(dòng)態(tài)庫(kù))或 gcc -o hello hello.c -L /usr/lib -lm 其中,/usr/lib 可以被省略,因?yàn)樗菢?biāo)準(zhǔn)庫(kù)目錄,是系統(tǒng)默認(rèn)的搜索路徑。43 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù) 使用使用 -l 、-L 選項(xiàng)(續(xù))選項(xiàng)(續(xù))44 3.2 編譯C語(yǔ)言程序45 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)1.靜態(tài)庫(kù)函數(shù)庫(kù)的最簡(jiǎn)單的形式是一組處于“待用”狀態(tài)的目標(biāo)文件。當(dāng)程序
24、需要使用函數(shù)庫(kù)中的某個(gè)函數(shù)時(shí),程序需要包含(#include)一個(gè)聲明該函數(shù)的頭文件編譯器、鏈接器負(fù)責(zé)將程序代碼和函數(shù)庫(kù)結(jié)合在一起組成一個(gè)可執(zhí)行文件除了標(biāo)準(zhǔn)的C語(yǔ)言庫(kù),如果還需要使用其它庫(kù),則必須用-l 和 L選項(xiàng)指明若要?jiǎng)?chuàng)建和維護(hù)自己的靜態(tài)庫(kù),則需使用ar程序和gcc -c命令對(duì)所使用的函數(shù)分別進(jìn)行編譯46 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)1. 靜態(tài)庫(kù)靜態(tài)庫(kù)q 例3.8 創(chuàng)建一個(gè)小型函數(shù)庫(kù),包括以下步驟:(1)建立兩個(gè)文件pro1.c、pro2.c,它們各自包含一個(gè)函數(shù), 分別是void pro1(int), void pro2(char *)(2)應(yīng)用gcc及參數(shù)-c,分別產(chǎn)生目標(biāo)
25、文件pro1.o, pro2.o(3)建立名為lib.h的頭文件,該文件包含兩個(gè)函數(shù)pro1、pro2的函數(shù)原型/聲明(4)應(yīng)用歸檔命令ar 建立靜態(tài)鏈接庫(kù)文件libfoo.a,命令形式為: ar crv libfoo.a pro1.o pro2.o(5)最后設(shè)計(jì)主程序3-8.c,其中包含頭文件lib.h(6)使用gcc對(duì)3-8.c進(jìn)行編譯,并加入?yún)?shù)-lfoo,即可調(diào)用pro1和pro2函數(shù)47 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)1. 靜態(tài)庫(kù)靜態(tài)庫(kù)q 例3.8 (續(xù))步驟1:為兩個(gè)函數(shù)分別創(chuàng)建各自的源文件48 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)1. 靜態(tài)庫(kù)靜態(tài)庫(kù)q 例3.8 (續(xù)
26、)步驟2:分別編譯這兩個(gè)函數(shù),產(chǎn)生需要包含在庫(kù)文件中的.o文件步驟3:為庫(kù)文件創(chuàng)建一個(gè)頭文件lib.h,該頭文件聲明了庫(kù)文件中的函數(shù);該頭文件將被所有希望使用庫(kù)文件的應(yīng)用程序所包含49 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)1. 靜態(tài)庫(kù)靜態(tài)庫(kù)q 例3.8 (續(xù))步驟4:使用ar程序創(chuàng)建一個(gè)歸檔文件,即庫(kù)文件(libfoo.a),并將.o文件添加進(jìn)去步驟5:創(chuàng)建主程序3-8.c,它包含庫(kù)的頭文件,且調(diào)用庫(kù)中的一個(gè)函數(shù)50 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)1. 靜態(tài)庫(kù)靜態(tài)庫(kù)q 例3.8 (續(xù))步驟6:編譯并測(cè)試3-8.c注: “-L dir”的作用是在庫(kù)文件的搜索路徑列表中添加dir目錄
27、 上述”-L .”指示編譯器在當(dāng)前目錄下查找函數(shù)庫(kù); Linux下的庫(kù)文件命名時(shí)須以”lib”開(kāi)頭 指定鏈接庫(kù)文件需要使用”-llibxxx”參數(shù),其中”lib”可以被省略,即”-lxxx”即可 因此上述”-lfoo”指示編譯器使用名為libfoo.a的靜態(tài)函數(shù)庫(kù),或名為libfoo.so的共享函數(shù)庫(kù)(如果它存在)51 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)1. 靜態(tài)庫(kù)靜態(tài)庫(kù)q 例3.8 (續(xù))可以使用nm命令查看.o文件、函數(shù)庫(kù)(.a或.so)或可執(zhí)行文件中包含的函數(shù),例如注:創(chuàng)建可執(zhí)行程序3-8時(shí),程序只包含函數(shù)庫(kù)中它實(shí)際需要的函數(shù);雖然程序的頭文件包含了函數(shù)庫(kù)中所有函數(shù)的聲明,但并不會(huì)
28、將整個(gè)函數(shù)庫(kù)包含在最終的程序中。52 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)2. 共享庫(kù)靜態(tài)庫(kù)缺點(diǎn):當(dāng)使用同一個(gè)函數(shù)庫(kù)函數(shù)的多個(gè)程序同時(shí)運(yùn)行時(shí),內(nèi)存中有同一函數(shù)的多個(gè)拷貝,從而消耗寶貴的內(nèi)存資源以及磁盤空間。共享庫(kù)能夠克服這一缺點(diǎn),實(shí)現(xiàn)函數(shù)的動(dòng)態(tài)鏈接;當(dāng)編譯好的程序被裝載到內(nèi)存中執(zhí)行時(shí),函數(shù)引用被解析并產(chǎn)生對(duì)共享庫(kù)的調(diào)用,如果有必要,共享庫(kù)才被加載到內(nèi)存中。通過(guò)共享庫(kù),系統(tǒng)只保留一份共享庫(kù)的拷貝并供多個(gè)應(yīng)用程序同時(shí)使用,該拷貝在磁盤上也僅保存一份。53 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)2. 共享庫(kù)(續(xù))共享庫(kù)的另一個(gè)優(yōu)勢(shì)在于,共享庫(kù)的更新不影響依賴它的應(yīng)用程序的運(yùn)行。例如/usr/l
29、ib/libm.o作為庫(kù)文件的修訂版本/usr/lib/libm.so.N 的符號(hào)鏈接,當(dāng)Linux啟動(dòng)應(yīng)用程序時(shí),會(huì)考慮應(yīng)用程序所需要的函數(shù)庫(kù)版本,以防止新版本函數(shù)庫(kù)在舊的應(yīng)用程序上不能被使用。共享庫(kù)在很多方面類似于Windows中使用的動(dòng)態(tài)鏈接庫(kù),.so庫(kù)對(duì)應(yīng)于.DLL文件。在程序運(yùn)行時(shí)加載;而.a庫(kù)類似于.LIB文件,包含在可執(zhí)行程序中。54 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)2. 共享庫(kù)(續(xù))55 3.2 編譯C語(yǔ)言程序3.2.4 函數(shù)庫(kù)2. 共享庫(kù)(續(xù))p 雖然程序已包含數(shù)學(xué)函數(shù)庫(kù),但是未指定庫(kù)文件的路徑、名稱p 因此需要查找函數(shù)所在的庫(kù)文件的路徑、名稱56 3.2 編譯C語(yǔ)言
30、程序3.2.4 函數(shù)庫(kù)2.共享庫(kù)(續(xù))思考題:57 3.3 make工程文件3.3.1 make命令 C語(yǔ)言的大型軟件中常包含多個(gè)源文件、頭文件,文件之間通常彼此依賴、關(guān)系復(fù)雜。 如果修改了其中的一個(gè)文件,則必須重新編譯所有依賴它的文件。 make工程管理器是一個(gè)“自動(dòng)編譯管理器”,能夠根據(jù)文件的時(shí)間戳自動(dòng)發(fā)現(xiàn)被更新過(guò)的文件,從而減少編譯的工作量。 make工程管理器通過(guò)讀入makefile或Makefile文件來(lái)執(zhí)行大量的編譯工作,大大提高了工作效率。 makefile或Makefile的文件描述了系統(tǒng)中各個(gè)模塊之間的依賴關(guān)系;當(dāng)部分文件改變時(shí),make工具決定需要重新編譯的文件的最小集合。
31、58 3.3 make工程文件3.3.1 make命令 使用格式:make 選項(xiàng) make工程文件-d 顯示調(diào)試信息-f 文件 將指定文件(而不是默認(rèn)的makefile或Makefile)作為依賴 關(guān)系文件-n 僅顯示但不執(zhí)行makefile或Makefile文件中的編譯命令-s 執(zhí)行但不顯示任何信息59 3.3 make工程文件3.3.2 make規(guī)則 默認(rèn)的程序依賴關(guān)系文件名可以是GNUmakefile、makefile、Makefile makefile所包含的規(guī)則主要描述目標(biāo)文件(target文件,勿與.o文件混淆)由哪些依賴文件(dependency)產(chǎn)生,以及用什么命令來(lái)執(zhí)行tar
32、get目標(biāo)文件dependency依賴文件生成target目標(biāo)文件所需的編譯命令Tab鍵空格隔開(kāi)目標(biāo)文件可以是要執(zhí)行的工作60 3.3 make工程文件3.3.2 make規(guī)則 當(dāng)make命令檢查發(fā)現(xiàn),目標(biāo)文件的生成或被改動(dòng)的時(shí)間(文件的時(shí)間戳)至少比它的一個(gè)依賴文件還早的話,則make執(zhí)行相應(yīng)的命令,更新目標(biāo)文件 目標(biāo)文件(target)不一定是最后的可執(zhí)行文件,可以是任何一個(gè)中間文件或依賴文件 makefile文件通常包括:l 需要由make工具創(chuàng)建的目標(biāo)(target),通常是目標(biāo)文件或可執(zhí)行文件l 創(chuàng)建目標(biāo)所依賴的文件l 創(chuàng)建每個(gè)目標(biāo)時(shí)需要運(yùn)行的命令l 其它要執(zhí)行的動(dòng)作(如clean)
33、61 3.3 make工程文件3.3.3 編寫makefile文件例3.10 計(jì)算學(xué)生的總成績(jī)、平均成績(jī)(由自定義的函數(shù)fun_sum、fun_avg分別完成),并使用make工程管理器進(jìn)行編譯。文件名邏輯關(guān)系3-10-main.c3-10-fun_sum.c3-10-fun_avg.cChengji.h (包含fun_avg和fun_sum的函數(shù)聲明)62 3.3 make工程文件3.3.3 編寫makefile文件例3.10(續(xù)) makefile文件注:當(dāng)3-10-main.c中使用#include “chengji.h”,且chengji.h在當(dāng)前目錄下時(shí),可直接使用如下命令生成3-10-main.ogcc 3-10-main.c c否則,需要使用gcc 3-10-main.c c I dir (dir為chengji.h所在的目錄) 63 3.3 make工程文件3.3.3 編寫makefile文件例3.10 (續(xù)) 3-10-main.c 源代碼64 3.3 make工程文件3.3.3 編寫makefile文件例3.10 (續(xù)) 3-10-fun_sum.c、3-10-fun_avg.c、chengji.h 源代碼65 3.3 make工程文件指定makefile3-10作為依賴關(guān)系文件,而不是默認(rèn)的makefile或Makefile3.3.3 編寫m
溫馨提示
- 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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)用織物管理規(guī)范
- 2025屆安徽省部分省示范中學(xué)高考化學(xué)考前最后一卷預(yù)測(cè)卷含解析
- 心內(nèi)科危重病人護(hù)理常規(guī)
- 工廠環(huán)境安全主題
- 小學(xué)生生命生存生活教育
- 統(tǒng)編版(2024)語(yǔ)文一年級(jí)下冊(cè)第八單元綜合素質(zhì)測(cè)評(píng)B卷(含答案)
- 第二單元評(píng)估檢測(cè)題(單元測(cè)試)無(wú)答案六年級(jí)下冊(cè)數(shù)學(xué)冀教版
- 2025年弱粘煤項(xiàng)目合作計(jì)劃書(shū)
- 彈力小車課件
- 宿舍美甲店創(chuàng)業(yè)計(jì)劃書(shū)
- 企業(yè)廉潔風(fēng)險(xiǎn)防控課件教學(xué)
- 中醫(yī)護(hù)理三基練習(xí)題庫(kù)+答案
- 2025年護(hù)士三基考核試題及答案
- 七年級(jí)下冊(cè)2025春季歷史 教學(xué)設(shè)計(jì)《明朝對(duì)外關(guān)系》 學(xué)習(xí)資料
- 《設(shè)備管理標(biāo)準(zhǔn)化實(shí)施手冊(cè)》
- 湖南省長(zhǎng)沙市明達(dá)中學(xué)2024-2025學(xué)年九年級(jí)下學(xué)期入學(xué)考試英語(yǔ)試卷(含答案無(wú)聽(tīng)力原文及音頻)
- 汽車站建設(shè)項(xiàng)目可行性研究報(bào)告
- 《中國(guó)古典園林之美》課件
- 2024年09月上海2024交通銀行交銀金融科技校園招考筆試歷年參考題庫(kù)附帶答案詳解
- 2025年人教五四新版八年級(jí)數(shù)學(xué)上冊(cè)階段測(cè)試試卷
- 2025年廣西中馬欽州產(chǎn)業(yè)園區(qū)管委會(huì)招商服務(wù)有限公司招聘筆試參考題庫(kù)附帶答案詳解
評(píng)論
0/150
提交評(píng)論