C語言GCC基礎(chǔ)培訓(xùn)_第1頁
C語言GCC基礎(chǔ)培訓(xùn)_第2頁
C語言GCC基礎(chǔ)培訓(xùn)_第3頁
C語言GCC基礎(chǔ)培訓(xùn)_第4頁
C語言GCC基礎(chǔ)培訓(xùn)_第5頁
已閱讀5頁,還剩71頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

會計學(xué)1C語言GCC基礎(chǔ)培訓(xùn)2gcc簡介名稱:GNUprojectCandC++CompilerGNUCompilerCollectiongcc是一個全功能的

ANSI

C

兼容編譯器,它是所有UNIX系統(tǒng)可用的C編譯器。gcc是可以在多種硬體平臺上編譯出可執(zhí)行程序的超級編譯器,其執(zhí)行效率與一般的編譯器相比平均效率要高20%~30%。第1頁/共76頁3查看版本信息第2頁/共76頁4查看安裝路徑第3頁/共76頁5相關(guān)文件類型c為后綴的文件,C語言源代碼文件;.a為后綴的文件,是由目標(biāo)文件構(gòu)成的檔案庫文件;.C,.cc或.cxx為后綴的文件,是C++源代碼文件;.h為后綴的文件,是程序所包含的頭文件;.i為后綴的文件,是已經(jīng)預(yù)處理過的C源代碼文件;.ii為后綴的文件,是已經(jīng)預(yù)處理過的C++源代碼文件;.m為后綴的文件,是Objective-C源代碼文件;.o為后綴的文件,是編譯后的目標(biāo)文件;.s為后綴的文件,是匯編語言源代碼文件;.S為后綴的文件,是經(jīng)過預(yù)編譯的匯編語言源代碼文件。第4頁/共76頁6gcc編譯的4個過程預(yù)處理(也稱預(yù)編譯,Preprocessing):命令gcc首先調(diào)用cpp進行預(yù)處理,在預(yù)處理過程中,對源代碼文件中的文件包含(include)、預(yù)編譯語句(如宏定義define等)進行分析。編譯(Compilation):接著調(diào)用cc1進行編譯,這個階段根據(jù)輸入文件生成以.o為后綴的目標(biāo)文件。匯編(Assembly):匯編過程是針對匯編語言的步驟,調(diào)用as進行工作。連接(Linking):當(dāng)所有的目標(biāo)文件都生成之后,gcc就調(diào)用ld來完成最后的關(guān)鍵性工作,這個階段就是連接第5頁/共76頁7可執(zhí)行程序的生成過程預(yù)處理(Preprocessing):分析各種預(yù)處理命令,如#define,#include,#if等;編譯(Compilation):根據(jù)輸入文件產(chǎn)生匯編語言的程序;匯編(Assembly):將匯編語言輸入,產(chǎn)生擴展名為.o的目標(biāo)文件;鏈接(Linking):以.o目標(biāo)文件,庫文件作為輸入,生成可執(zhí)行文件;源程序文件(.h,.c)經(jīng)預(yù)處理的文件(.i)匯編語言文件(.s)目標(biāo)文件(.o)可執(zhí)行程序(.out)第6頁/共76頁8培訓(xùn)大綱一、gcc簡介二、gcc編譯過程三、gcc編譯選項四、靜態(tài)/動態(tài)鏈接庫五、其它第7頁/共76頁9GCC編譯過程

典型的編譯過程

test.c–預(yù)處理test.i–編譯

test.s–匯編test.o–連接test$cattest.c(查看程序源代碼)#include<stdio.h>intmain(intargc,char*argv[]){printf("helloworld\n"); return0;}$gcc–otesttest.c(編譯連接程序)$./test(執(zhí)行test程序)第8頁/共76頁101、沒有任何選項:gcchelloworld.c 結(jié)果會在和helloworld.c相同的目錄下產(chǎn)生一個a.out的可執(zhí)行文檔。2、-o選項,指定輸出文檔名:gcc-ohelloworldhelloworld.c -o意思是Output即需要指定輸出的可執(zhí)行文檔的名稱。這里的名稱為helloworld。3、-c選項,只編譯匯編,不連接:gcc-chelloworld.c -c意思就是Compile,產(chǎn)生一個叫helloworld.o的目標(biāo)文檔4、-S選項,產(chǎn)生匯編源文檔:gcc-Shelloworld.c -S意思就是aSsemble,產(chǎn)生一個叫helloworld.s的匯編源文檔5、-E選項,預(yù)處理C源文檔:gcc-Ehelloworld.c -E意思就是prEprocess。輸出不是送到一個文檔而是標(biāo)準(zhǔn)輸出。當(dāng)然能夠?qū)λM行重定向: gcc-Ehelloworld.c>helloworld.txt第9頁/共76頁11預(yù)處理預(yù)編譯命令:

$gcc-otest.i-Etest.c或者

$cpp-otest.itest.c

這里cpp不是值cplusplus,而是theCPreprocessor執(zhí)行結(jié)果:生成預(yù)處理后的文件test.i,該文件包含了test.c需要的所有的類型和函數(shù)申明。原理:讀取c源程序,對偽指令和特殊符號進行處理。包括宏,條件編譯,包含的頭文件,以及一些特殊符號?;旧鲜且粋€替換的過程。第10頁/共76頁12#define用法#include<stdio.h>#defineAA100intmain(void){ AABBprintf(“hello\n”);}預(yù)處理命令gcc–Ehello.c–DBB=hellogcc–Ehello.c–DBB=“printf(\”hello\”);”gcc–Ehello.c–DBB(等效于-DBB=1)注釋這一行看看預(yù)處理的結(jié)果-D表示在命令行中傳入宏定義-DBB=后面是一個宏的定義,可以加雙引號。第11頁/共76頁13#define帶參數(shù)#include<stdio.h>#defineAA(a,b)a=bintmain(void){ AA(inta,1);printf(“hello\n”);}預(yù)處理命令gcc–Ehello.c展開就成了:inta=1;AA宏帶兩個參數(shù)第12頁/共76頁14#define帶參數(shù)#include<stdio.h>#ifdefAAaa#elifdefinedBBbb#elifdefinedCCcc#elseother#endifintmain(void){printf(“hello\n”);}gcc–Ehello.c–DAA=1aaintmain(void){printf(“hello\n”);}#ifdefAA等效于#ifdefinedAA表示當(dāng)定義了宏AA表示除此之外的情況表示否則定義了宏CC的情況第13頁/共76頁15#define帶參數(shù)#include<stdio.h>#ifAAaa#elifBBbb#elifCCcc#elseother#endifintmain(void){printf(“hello\n”);}#ifAA表示AA非零的情況也就是AA除了0其它數(shù)字都為真表示除此之外的情況#elifBB表示BB非零的情況#elif表示否則如果第14頁/共76頁16gcc–Ehello.c–DAA=1aaintmain(void){printf(“hello\n”);}gcc–Ehello.c–DAA=0otherintmain(void){printf(“hello\n”);}第15頁/共76頁17#的用法在函數(shù)式宏定義中,#運算符用于創(chuàng)建字符串,#運算符后面應(yīng)該跟一個形參(中間可以有空格或Tab),例如:#defineSTR(s)#schar*p=STR(helloworld)結(jié)果變成:char*p=“helloworld”第16頁/共76頁18##的用法在宏定義中可以用##運算符把前后兩個預(yù)處理Token連接成一個預(yù)處理Token,和#運算符不同,##運算符不僅限于函數(shù)式宏定義,變量式宏定義也可以用。例如:#defineFOO(a)foo##ainta=FOO(bar);intb=FOO();預(yù)處理之后變成:inta=foobar;intb=foo;第17頁/共76頁19預(yù)處理頭文件xxx.h#ifndefHEADER_FILENAME#defineHEADER_FILENAME/*bodyofheader*/#endif當(dāng)xxx.h被多次包含的時候。第18頁/共76頁20有三個頭文件和一個C文件common.hfile2.hfile3.hmain.c#ifndef__COMMON_H__#define__COMMON_H__staticinttest(void){printf(“hello\n”);}#endiffile1.h文件內(nèi)容如下:#include“common.h”file2.h文件內(nèi)容如下:#include“common.h”main.c內(nèi)容如下#include<stdio.h>#include“file1.h”#include“file2.h”intmain(void){test();}gcc–omainmain.c

如果沒有寫上紅色部分的,是什么情況。第19頁/共76頁21常用的#debug宏定義intmain(){…printf(“here%s%s%d\n”,__FILE__,__func__,__LINE__);…printf(“here%s%s%d\n”,__FILE__,__func__,__LINE__);…printf(“here%s%s%d\n”,__FILE__,__func__,__LINE__);}太多printf不好區(qū)分如何打出printf的時候也打出行號,函數(shù),文件之類的信息第20頁/共76頁22編譯編譯命令:$gcc-otest.s-Stest.i(-S編譯選項)$cc1-otest.stest.i(cc1為C語言真正編譯器)結(jié)果:生成匯編文件test.s,test.s中包含了AT&T的x86匯編代碼。作用:通過詞法和語法分析,確認(rèn)所有指令符合語法規(guī)則(否則報編譯錯),之后翻譯成對應(yīng)的中間碼,在linux中被稱為RTL(RegisterTransferLanguage),通常是平臺無關(guān)的,這個過程也被稱為編譯前端。編譯后端對RTL樹進行裁減,優(yōu)化,得到在目標(biāo)機上可執(zhí)行的匯編代碼。gcc采用as作為其匯編器,所以匯編碼是AT&T格式的,而不是Intel格式,所以在用gcc編譯嵌入式匯編時,也要采用AT&T格式。第21頁/共76頁23匯編匯編命令:

$gcc-otest.o-ctest.s$as-otest.otest.s執(zhí)行結(jié)果:

生成目標(biāo)機器指令文件test.o(可以通過objdump查看匯編指令)原理:

把匯編語言代碼翻譯成目標(biāo)機器指令,用filetest.o可以看到test.o是一個relocatable的ELF文件,通常包含.text.rodata代碼段和數(shù)據(jù)段??捎胷eadelf-rtest.o查看需要relocation的部分。第22頁/共76頁24鏈接執(zhí)行命令:

$gcc-otesttest.o執(zhí)行結(jié)果:

生成可執(zhí)行文件test(可用objdump查看)原理:

將在一個文件中引用的符號同在另外一個文件中該符號的定義鏈接起來,使得所有的這些目標(biāo)文件鏈接成為一個能被操作系統(tǒng)加載到內(nèi)存的執(zhí)行體。(如果有鏈接不到的符號定義,或者重復(fù)定義等,會報鏈接錯)。用filetest可以看到test是一個executable的ELF文件。第23頁/共76頁25培訓(xùn)大綱一、gcc簡介二、gcc編譯過程三、gcc編譯選項四、靜態(tài)/動態(tài)鏈接庫五、其它第24頁/共76頁26gcc的使用基本使用格式$gcc[選項][文件名]例://text.c#include<stdio.h>voidmain(){printf(“HelloWorld!\n”);}$gcctest.c$./a.outHelloWorld!或$gcc-otesttest.c$./testHelloWorld!第25頁/共76頁27常用選項及含義gcc常用選項選項含義-ofile將經(jīng)過gcc處理過的結(jié)果存為文件file,這個結(jié)果文件可能是預(yù)處理文件、匯編文件、目標(biāo)文件或者最終的可執(zhí)行文件。假設(shè)被處理的源文件為source.suffix,如果這個選項被省略了,那么生成的可執(zhí)行文件默認(rèn)名稱為a.out;目標(biāo)文件默認(rèn)名為source.o;匯編文件默認(rèn)名為source.s;生成的預(yù)處理文件則發(fā)送到標(biāo)準(zhǔn)輸出設(shè)備。-E不生成文件,只輸出預(yù)處理結(jié)果(輸出終端)-S只預(yù)處理和編譯,把文件編譯成為匯編代碼第26頁/共76頁28gcc的常用選項-c預(yù)處理,編譯和匯編,生成.o的obj文件

。編譯器只是由輸入的.c等源代碼文件生成.o為后綴的目標(biāo)文件。在對源文件進行查錯時,或只需產(chǎn)生目標(biāo)文件時可以使用該選項。-g[gdb]調(diào)試選項,在可執(zhí)行文件中加入調(diào)試信息,方便進行程序的調(diào)試。如果使用中括號中的選項,表示加入gdb擴展的調(diào)試信息,方便使用gdb來進行調(diào)試-pg調(diào)試選項,產(chǎn)生供gprof剖析用的可執(zhí)行文檔:gcc-pghelloworld.c-O[0、1、2、3]優(yōu)化編譯。對生成的代碼使用優(yōu)化,中括號中的部分為優(yōu)化級別,缺省的情況為2級優(yōu)化,0為不進行優(yōu)化。注意,采用更高級的優(yōu)化并不一定得到效率更高的代碼。第27頁/共76頁29gcc的常用選項-Idirname指定搜索系統(tǒng)頭文件的目錄,可以重復(fù)使用多個該選項指定多個目錄,是在預(yù)編譯過程中使用的參數(shù)。先在你所制定的目錄查找,然后再按常規(guī)的順序去找頭文件-Ldirname在dir這個目錄尋找被-l的庫,指定編譯時搜索庫的路徑-lname在連接時,裝載名字為“l(fā)ibname.a”的函數(shù)庫,該函數(shù)庫位于系統(tǒng)預(yù)設(shè)的目錄或者由-L選項確定的目錄下。例如,-lm表示連接名為“l(fā)ibm.a”的數(shù)學(xué)函數(shù)庫。-fpic或-fPIC產(chǎn)生位置無關(guān)的目標(biāo)代碼,以構(gòu)造共享庫(sharedlibrary)-static連接器將忽略動態(tài)連接庫,同時通過將靜態(tài)目標(biāo)文件直接包含到結(jié)果目標(biāo)文件完成對所有引用的解析。禁止與共享庫鏈接,若沒有,則優(yōu)先選擇共享庫鏈接-shared產(chǎn)生共享庫,在創(chuàng)建共享函數(shù)庫時使用第28頁/共76頁30gcc的常用選項-w禁止輸出警告信息-Wwarning允許產(chǎn)生warning類型的警告,warning可以是:main、unused等很多取值,最常用是-Wall,表示顯示所有警告。如果warning取值為error,其含義是將所有警告轉(zhuǎn)換為錯誤(error),即出現(xiàn)警告就停止編譯。-ansi支持ANSI/ISOC的標(biāo)準(zhǔn)語法,取消GNU的語法中與該標(biāo)準(zhǔn)有沖突的部分,但并不保證生成與ANSI兼容代碼。-Dmacro-Dmacro=value相當(dāng)于在源程序中使用#definemacro1-Umacro取消宏的定義-M生成文件關(guān)聯(lián)的信息。包含目標(biāo)文件所依賴的所有源代碼。-v查看當(dāng)前系統(tǒng)gcc的版本信息第29頁/共76頁31示例第30頁/共76頁32-Wall:允許所有有用的警告(建議總是使用該選項)/*bad.c*/#include<stdio.h>intmain(intargc,char**argv){ printf(“Twoplustwois%f\n”,4); return0;}例1:$gccbad.c–obad例2:$gcc–Wallbad.c–obad32例1:第31頁/共76頁33-o:定義輸出文件例:編譯多個源文件$gcc-Wallmain.chello.c-ohelloworld/*hello.h*/voidhello(constchar*name);/*hello.c*/#include<stdio.h>#include"hello.h"voidhello(constchar*name){ printf("Hello,%s!\n",name);}/*main.c*/#include"hello.h"intmain(intargc,char**argv){ hello("world"); return0;}33例2:第32頁/共76頁34-l:鏈接外部庫文件

庫是已經(jīng)編譯好并能被鏈接入程序的對象文件的集合。庫中提供一些最常用的系統(tǒng)函數(shù),比如象C的數(shù)學(xué)庫中求平方根函數(shù)sqrt。庫通常被存儲在擴展名為“.a”或“.so”的特殊歸檔文件中。C標(biāo)準(zhǔn)庫自身存放在“/usr/lib/libc.a”中,包含ANSI/ISOC標(biāo)準(zhǔn)指定的各個函數(shù),是默認(rèn)自動加載的庫。/*sqrt.c*/#include<stdio.h>#include<math.h>intmain(intargc,char**argv){ doubler=sqrt(3.0); printf("("Thesquarerootof3.0is%f\n",r); return0;}例:$gcc-Wallsqrt.c-osqrtccbR6Ojm.o:Infunction‘main’:ccbR6Ojm.o(.text+0x19):undefinedreferenceto‘sqrt’34例:第33頁/共76頁35-l:鏈接外部庫文件函數(shù)sqrt()并不定義在源程序中或默認(rèn)的C庫“l(fā)ibc.a”中。為了使得編譯器能把sqrt()函數(shù)鏈接到主程序“sqrt.c”,需要提供“l(fā)ibm.a”庫。例:$gcc-Wallsqrt.c/usr/lib/libm.a-osqrt/usr/lib/libm.a-lm$gcc-Wallsqrt.c-lm-osqrt編譯器選項“-lNAME”試圖鏈接標(biāo)準(zhǔn)庫目錄下的文件名為“l(fā)ibNAME.a”中的對象文件35例:第34頁/共76頁36函數(shù)庫的鏈接次序原則:包含函數(shù)定義的庫應(yīng)該出現(xiàn)在任何使用到該函數(shù)的源文件和對象文件之后例1:$gcc-Wall-lmsqrt.c-osqrt(incorrect)$gcc-Wallsqrt.c-lm-osqrt(correct)例2:$gcc-Wallsqrt.c-lglpk-lm-osqrt程序“sqrt.c”用到了GNULinearProgramming庫“l(fā)ibglpk.a”,而該庫又依次用到數(shù)學(xué)庫“l(fā)ibm.a”,那么應(yīng)當(dāng)這么編譯:36例:第35頁/共76頁37-L:設(shè)置庫文件的搜索路徑如果鏈接時用到的庫不在gcc用到的標(biāo)準(zhǔn)庫目錄中,就會報這樣的錯。/usr/local/lib//usr/lib/例:$gcc-Wall-L/tmp/libsqrt.c-lm-osqrt-L/tmp/lib37例:第36頁/共76頁38-I:設(shè)置頭文件的搜索路徑如果頭文件不在gcc用到的標(biāo)準(zhǔn)include文件路徑中,就會報這樣的錯。/usr/local/include//usr/include/例:$gcc-Wall-I/tmp/includesqrt.c-lm-osqrt-I/tmp/include38例:第37頁/共76頁39生成預(yù)處理文件命令-E選項使得gcc生成預(yù)處理文件后停止。$gcc–Ehello.c–ohello.i預(yù)處理文件hello.i的部分內(nèi)容......externvoidfunlockfile(FILE*__stream);#679"/usr/include/stdio.h"3#2"hello.c"2intmain(void){printf("hellogcc!\n");return0;}第38頁/共76頁40生成匯編文件命令$gcc–Shello.c–ohello.s匯編文件hello.s的部分內(nèi)容......main: pushl %ebp movl %esp,%ebp........ addl $16,%esp movl $0,%eax leave ret......"第39頁/共76頁41生成二進制文件生成目標(biāo)文件命令:$gcc–chello.c–ohello.o生成可執(zhí)行文件命令:$gcchello.c–ohello運行程序$./hello

hellogcc!第40頁/共76頁42培訓(xùn)大綱一、gcc簡介二、gcc編譯過程三、gcc編譯選項四、靜態(tài)/動態(tài)鏈接庫五、其它第41頁/共76頁43靜態(tài)庫與動態(tài)庫創(chuàng)建函數(shù)庫分類:靜態(tài)庫:在編譯過程中將庫函數(shù)代碼直接加入到生成的可執(zhí)行程序中,程序運行過程中不需要利用庫函數(shù)。共享庫:編譯時,只是在生成的可執(zhí)行程序中簡單指定需要使用的庫函數(shù)信息,程序運行過程中需要利用庫函數(shù)。動態(tài)庫:共享庫的一種變化形式,目前大都采用共享庫的方式。命名:靜態(tài)庫:前綴lib+庫名+.a(libm.a,libstdc++.a等)共享庫:前綴lib+庫名+.so+.版本號(libm.so.6,libc.so.6)第42頁/共76頁44創(chuàng)建靜態(tài)庫靜態(tài)函數(shù)庫是一組目標(biāo)文件(*.o)的集合創(chuàng)建步驟:

gcc-ctest1.ctest2.c (生成test1.o,test2.o) ar-crlibtest.atest1.otest2.o (生成函數(shù)庫libtest.a)ar函數(shù)說明:用途:創(chuàng)建和修改庫函數(shù),或從庫函數(shù)提取目標(biāo)文件舉例:ar-rslib-namelist-of-files(將列表中的目標(biāo)文件加入到庫中,并產(chǎn)生索引文件)ar-dslib-namelist-of-files (將列表中列出的目標(biāo)文件從庫中刪除,并產(chǎn)生索引文件)ar-xlib-namelist-of-files (不修改庫文件,從庫中提取列表中列出的目標(biāo)文件)第43頁/共76頁45創(chuàng)建靜態(tài)庫示例--源碼創(chuàng)建靜態(tài)庫的方法:arcaculation.c#include<stdio.h>intmain(void){intx=5;inty=3;printf("x+y=%3d\n",add(x,y));printf("x-y=%3d\n",minus(x,y));printf("x*y=%3d\n",multiply(x,y));printf("x%y=%3d\n",mod(x,y));return1;}add_minus.cintadd(intx,inty){intresult;result=x+y;returnresult;}intminus(intx,inty){intresult;result=x-y;returnresult;}multiply_mod.cintmultiply(intx,inty){intresult;result=x*y;returnresult;}intmod(intx,inty){intresult;result=x%y;returnresult;}第44頁/共76頁46創(chuàng)建靜態(tài)庫示例--操作命令第45頁/共76頁47一個容易忽略的順序問題

靜態(tài)庫不能先于原程序鏈接,這是因為開始時還沒有任何未定義的符號,庫中的內(nèi)容不會被鏈入,所以應(yīng)該注意將靜態(tài)庫的使用(-l選項)都寫在最后。第46頁/共76頁48創(chuàng)建、使用共享庫示例[vick@nec]$gcc-fPIC-cadd_minus.c[vick@nec]$gcc-fpic-cmultiply_mod.c[vick@nec]$gcc-shared-fpic-olibalg.soadd_minus.omultiply_mod.o[vick@nec]$gcc-ocacul-lalgcaculation.c/usr/bin/ld:cannotfind-lalgcollect2:ldreturned1exitstatus[vick@nec]$gcc-ocacul-L.-lalgcaculation.c[vick@nec]$./cacul./cacul:errorwhileloadingsharedlibraries:libalg.so:cannotopensharedobjectfile:Nosuchfileordirectory第47頁/共76頁49創(chuàng)建共享庫步驟創(chuàng)建共享庫

gcc-c-fPICtest1.c gcc-c-fPICtest2.c gcc-shared-fPIC-olibtest.sotest1.otest2.o編譯使用了共享庫的程序

gcc-omain–Ldir-ltestmain.c第48頁/共76頁50共享庫系統(tǒng)自動動態(tài)加載問題1.拷貝動態(tài)庫文件到/lib或/usr/lib去

$cplibalg.so/usr/libor$cplibalg.so/lib2.改變環(huán)境變量LD_LIBRARY_PATH $LD_LIBRARY_PATH=$PWD$exportLD_LIBRARY_PATH第49頁/共76頁51應(yīng)用程序自身完成動態(tài)加載

可以在自己的程序中使用dlopen()。該函數(shù)將打開一個新庫,并把它裝入內(nèi)存。

dlopen()在dlfcn.h中定義,并在dl庫中實現(xiàn)。第50頁/共76頁52應(yīng)用程序自身完成動態(tài)加載示例#include<stdio.h>#include<dlfcn.h>intmain(void){intx=5;inty=3;void*handle;int(*dl_add)(int,int);int(*dl_mod)(int,int);

handle=dlopen("/usr/lib/libalg.so",RTLD_LAZY);dl_add=dlsym(handle,"add");dl_mod=dlsym(handle,"mod");printf("x+y=%3d\n",dl_add(x,y));printf("x%y=%3d\n",dl_mod(x,y));dlclose(handle);return1;}第51頁/共76頁53檢查庫依賴關(guān)系函數(shù)庫之間的相互引用ldd的使用:用于查看庫函數(shù)之間的依賴性[vick@necgcc-lab]$cd/usr/lib[vick@neclib]$lddlibtiff.solibjpeg.so.62=>/usr/lib/libjpeg.so.62(0x4004c000)libz.so.1=>/usr/lib/libz.so.1(0x4006b000)libc.so.6=>/lib/i686/libc.so.6(0x40079000)/lib/ld-linux.so.2=>/lib/ld-linux.so.2(0x80000000)第52頁/共76頁54動態(tài)庫路徑搜索的先后順序編譯目標(biāo)代碼時指定的動態(tài)庫搜索路徑;環(huán)境變量LD_LIBRARY_PATH指定的動態(tài)庫搜索路徑;配置文件/etc/ld.so.conf中指定的動態(tài)庫搜索路徑;默認(rèn)的動態(tài)庫搜索路徑/lib;默認(rèn)的動態(tài)庫搜索路徑/usr/lib.

第53頁/共76頁55總結(jié):動態(tài)共享庫的好處1.動態(tài)共享庫是共享的,節(jié)省了物理開銷。2.庫版本更新容易,運行時調(diào)用,庫更新后不用重新鏈接。3.允許用戶在運行時再確定調(diào)用哪個庫。使得在程序中添加或者刪除一個模塊時,都不需要在編譯時指定庫。注意,如果動態(tài)共享庫無法加載,可能是路徑的問題,或是依賴的問題。第54頁/共76頁56培訓(xùn)大綱一、gcc簡介二、gcc編譯過程三、gcc編譯選項四、靜態(tài)/動態(tài)鏈接庫五、其它第55頁/共76頁57GNUC擴展簡介gcc使用longlong數(shù)據(jù)類型提供64位存儲單元。內(nèi)聯(lián)函數(shù):要求內(nèi)聯(lián)函數(shù)足夠短小,使得能夠在代碼中展開,同時編譯器檢查函數(shù)類型。要使用-O選項。-finline-functions.使用attribute關(guān)鍵字指明代碼相關(guān)信息方便優(yōu)化。gcc對case做了擴展。case語句可以對應(yīng)一個范圍,在case關(guān)鍵字后列出范圍的兩個邊界值,用“空格省略號空格”分隔。第56頁/共76頁58多個文件的C程序為了方便代碼重用,通常將主函數(shù)和其他函數(shù)放在不同文件中的方法。每個函數(shù)都有函數(shù)聲明(函數(shù)頭)和函數(shù)實現(xiàn)(函數(shù)體)兩部分組成。函數(shù)頭一般放在頭文件中(*.h)中,而函數(shù)的定義文件放在實現(xiàn)文件(*.c、*.cpp)中第57頁/共76頁59編譯多個文件greeting.h#ifndef_GREETING_H#define_GREETING_Hvoidgreeting(char*name);#endifgreeting.c#include<stdio.h>#include"greeting.h"voidgreeting(char*name){printf("Hello%s!\r\n",name);}my_app.c#include<stdio.h>#include"greeting.h"#defineN10intmain(void){charname[N];printf("YourName,Please:");scanf("%s",name);greeting(name);return0;}第58頁/共76頁60假設(shè)3個文件保存在同一個目錄下面,如果還使用:命令:$gccmy_app.c–omy_app會編譯通過嗎?greeting.h./greeting.cmy_app.c第59頁/共76頁61編譯多個文件目錄結(jié)構(gòu)(1)編譯命令$gccmy_app.cgreeting.c

–omy_app目錄結(jié)構(gòu)(2)編譯方式(1)$ gccmy_app.cfunctions/greeting.c–omy_app-Ifunctions

greeting.h./greeting.cmy_app.cgreeting.h./greeting.cmy_app.cfunctions第60頁/共76頁62編譯多個文件目錄結(jié)構(gòu)(2)編譯方式(2)分步編譯命令:1、$gcc-cmy_app.c-Ifunctions2、$gcc-cfunctions/greeting.c3、$gccmy_app.ogreeting.o–omy_app思路:編譯每一個.c文件,得到.o的目標(biāo)文件;將每一個.o的目標(biāo)文件鏈接成一個可執(zhí)行的文件;第61頁/共76頁63aroptionoptioncCreateafileoptiondDeleteafilefromthearchiveoptionpPrintalistoffilesinthearchiveoptionqAppendfilestothearchiveoptionrInsertnewfilesinthearchivebyreplacingifafilealreadyexistsinthearchiveoptiontDisplayingcontentsofanarchiveoptionxExtractingfilesfromanarchive第62頁/共76頁64ranlibUtilityThe“ranlib”commandisusedtocreateindexentriesinsideanarchivefile.示例:

$ranlibstatic-lib-name等價于$ar–sstatic-lib-name第63頁/共76頁65nmUtilityusedtolistsymbolsusedinanobjectfile.示例:

$nm-slibcommon.a $nm-sa.out另外:

–aoptionwiththenmcommandalsoshowsthedebugsymbols.第64頁/共76頁66objdumpUtility-fDisplayingHeaderInformation-hDisplayingSectionHeaders-dDisassemblingaFile-aDisplayingInformationaboutLibraryFiles第65頁/共76頁67sizeUtilityThesizeutilitydisplayssizesofeachsectioninanobjectfile.示例:

[root@boota]#sizea.out text

data

bss

dec

hex

filename 1015

232

24

1271

4f7

a.out

第66頁/共76頁68lddUtility Thelddutilityisveryusefulinfindingoutthedependenciesofanexecutableonsharedlibraries.示例:

[root@boota]#ldda.out libc.so.6=>/lib/i686/libc.so.6(0x4002c000) /lib/ld-linux.so.2=>/lib/ld-linux.so.2(0x40000000) [root@boota]#第67頁/共76頁69建立自己的GCC編譯環(huán)境一個系統(tǒng)上如何同時存在并使用多個版本的GCC編譯器?建立目標(biāo)目錄:在gcc源代碼同一級目錄下(與源目錄${srcdir}是同級目錄)%mkdirgcc-build%cdgcc-build配置環(huán)境:%../gcc-3.4.0/configure--prefix=/usr/local/gcc-3.4.0--enable-threads=posix--disable-checking--enable--long-long--host=i386-redhat-linux--with-system-zl

溫馨提示

  • 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)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論