試談Linux環(huán)境下程序編譯_第1頁
試談Linux環(huán)境下程序編譯_第2頁
試談Linux環(huán)境下程序編譯_第3頁
試談Linux環(huán)境下程序編譯_第4頁
試談Linux環(huán)境下程序編譯_第5頁
已閱讀5頁,還剩29頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

Linux環(huán)境下程序開發(fā)基礎(chǔ)3/16/2023Linux環(huán)境下程序編譯Linux環(huán)境下

程序編譯23/16/2023Linux與CLinux與C是天然的結(jié)合,從它們的誕生開始就有密切的聯(lián)系:Linux的前身Unix在用C語言改寫之后才為世界所廣泛接受;而C語言也是在Unix編寫、傳播的過程中發(fā)展和流行起來的Linux平臺為C語言提供的編譯工具是gcc。Gcc除了處理一般的C語言程序,還支持C++、ObjectiveC等一些語言。曙光4000A提供了PGIC/C++compiler—pgcc/pgCCLinux系統(tǒng)與其他系統(tǒng)類似,C語言程序的運(yùn)行過程分為三步:編寫源代碼用編譯工具編譯連接,生成可執(zhí)行文件運(yùn)行該可執(zhí)行文件33/16/2023一個簡單的例子—hello.c用vi編寫源文件:#include<stdio.h>voidmain(){printf(“helloworld.\n”);}用gcc編譯gcchello.c運(yùn)行a.out43/16/2023GCC簡介gcc(GNUCCompiler)是GNU推出的功能強(qiáng)大、性能優(yōu)越的多平臺編譯器,是GNU的代表作品之一。gcc編譯器能將C、C++語言源程序、匯程式化序和目標(biāo)程序編譯、連接成可執(zhí)行文件,如果沒有給出可執(zhí)行文件的名字,gcc將生成一個名為a.out的文件。在Linux系統(tǒng)中,可執(zhí)行文件沒有統(tǒng)一的后綴,系統(tǒng)從文件的屬性來區(qū)分可執(zhí)行文件和不可執(zhí)行文件。而gcc則通過后綴來區(qū)別輸入文件的類別,下面我們來介紹gcc常用的一些后綴。.c為后綴的文件,C語言源代碼文件.a為后綴的文件,是由目標(biāo)文件構(gòu)成的檔案庫文件.C,.cc或.cxx為后綴的文件,是C++源代碼文件.h為后綴的文件,是程序所包含的頭文件.o為后綴的文件,是編譯后的目標(biāo)文件gcc最基本的用法是∶gcc[options][filenames]其中options就是編譯器所需要的參數(shù),filenames給出相關(guān)的文件名稱53/16/2023GCC常用編譯參數(shù)-c:只編譯,不連接成為可執(zhí)行文件,編譯器只是由輸入的.c等源代碼文件生成.o為后綴的目標(biāo)文件,通常用于編譯不包含主程序的子程序文件。-ooutput_filename:確定輸出文件的名稱為output_filename,同時這個名稱不能和源文件同名。如果不給出這個選項(xiàng),gcc就給出預(yù)設(shè)的可執(zhí)行文件a.out。-g:產(chǎn)生符號調(diào)試工具(GNU的gdb)所必要的符號資訊,要想對源代碼進(jìn)行調(diào)試,我們就必須加入這個選項(xiàng)。-O:對程序進(jìn)行優(yōu)化編譯、連接,采用這個選項(xiàng),整個源代碼會在編譯、連接過程中進(jìn)行優(yōu)化處理,這樣產(chǎn)生的可執(zhí)行文件的執(zhí)行效率可以提高,但是,編譯、連接的速度就相應(yīng)地要慢一些。-O2:比-O更好的優(yōu)化編譯、連接,當(dāng)然整個編譯、連接過程會更慢。63/16/2023GCC常用編譯參數(shù)-Idirname:將dirname所指出的目錄加入到程序頭文件目錄列表中,是在預(yù)編譯過程中使用的參數(shù)。C程序中的頭文件包含兩種情況:A)#include<stdio.h>B)#include“myinc.h”其中,A類使用尖括號(<>),B類使用雙引號(“”)。對于A類,預(yù)處理程序cpp在系統(tǒng)預(yù)設(shè)包含文件目錄(如/usr/include)中搜尋相應(yīng)的文件,而對于B類,cpp在當(dāng)前目錄中搜尋頭文件,這個選項(xiàng)的作用是告訴cpp,如果在當(dāng)前目錄中沒有找到需要的文件,就到指定的dirname目錄中去尋找。在程序設(shè)計(jì)中,如果我們需要的這種包含文件分別分布在不同的目錄中,就需要逐個使用-I選項(xiàng)給出搜索路徑。73/16/2023GCC常用編譯參數(shù)-Ldirname:將dirname所指出的目錄加入到程序函數(shù)檔案庫文件的目錄列表中,是在連接過程中使用的參數(shù)。在預(yù)設(shè)狀態(tài)下,連接程序ld在系統(tǒng)的預(yù)設(shè)路徑中(如/usr/lib)尋找所需要的檔案庫文件,這個選項(xiàng)告訴連接程序,首先到-L指定的目錄中去尋找,然后到系統(tǒng)預(yù)設(shè)路徑中尋找,如果函數(shù)庫存放在多個目錄下,就需要依次使用這個選項(xiàng),給出相應(yīng)的存放目錄。-lname:在連接時,裝載名字為“l(fā)ibname.a”的函數(shù)庫,該函數(shù)庫位于系統(tǒng)預(yù)設(shè)的目錄或者由-L選項(xiàng)確定的目錄下。例如,-lm表示連接名為“l(fā)ibm.a”的數(shù)學(xué)函數(shù)庫。

上面我們簡要介紹了gcc編譯器最常用的功能和主要參數(shù)選項(xiàng),更為詳盡的資料可以參看Linux系統(tǒng)的聯(lián)機(jī)幫助。83/16/2023GCC應(yīng)用舉例1.gcchello.c 生成a.out2.gcc–ohellohelo.c 生成hello3.gcc–O–ohellohello.c 生成hello4.gcc–O2–ohellohello.c 生成hello5.gcc–chello.c 生成hello.ogcc–ohellohello.o 生成hello6.gcc–chello1.c 生成hello1.ogcc–chello2.c 生成hello2.ogcc–ohellohello1.ohello2.o生成hello7.gcc–otesttest1.o–lm–I/home/czn/include93/16/2023Make簡介在開發(fā)大系統(tǒng)時,經(jīng)常要將程序劃分為許多模塊。各個模塊之間存在著各種各樣的依賴關(guān)系,在Linux中通常使用Makefile來管理。由于各個模塊間不可避免存在關(guān)聯(lián),所以當(dāng)一個模塊改動后,其他模塊也許會有所更新,當(dāng)然對小系統(tǒng)來說,手工編譯連接是沒問題,但是如果是一個大系統(tǒng),存在很多個模塊,那么手工編譯的方法就不適用了。為此,在Linux系統(tǒng)中,專門提供了一個make命令來自動維護(hù)目標(biāo)文件。與手工編譯和連接相比,make命令的優(yōu)點(diǎn)在于他只更新修改過的文件,而對沒修改的文件則置之不理,并且make命令不會漏掉一個需要更新的文件。103/16/2023一個簡單的例子先舉一個例子:a.cb.c兩個程序a.c

externvoidp(char*);

main()

{

p("helloworld");

}b.c

voidp(char*str)

{

printf("%s\n",str);

}Makefile

hello:a.c

b.c

gcc

a.c

b.c-ohello注意這里是一個Tab執(zhí)行make

gcc

a.c

b.c-ohello產(chǎn)生一個叫hello的可執(zhí)行程序113/16/2023書寫makefile文件Makefile時由規(guī)則來組成的,每一條規(guī)則都有三部分組成:目標(biāo)(object),依賴(dependency)和命令(command).在上面的例子中,Makefile只有一條規(guī)則,其目標(biāo)為hello,期依賴為a.cb.c,其命令為gcca.cb.c-ohello.依賴可以是另一條規(guī)則的目標(biāo),也可以是文件.每一條規(guī)則被這樣處理.如目標(biāo)是一個文件是:當(dāng)它的依賴是文件時,如果依賴的時間比目標(biāo)要新,則運(yùn)行規(guī)則所包含的命令來更新目標(biāo);如果依賴是另一個目標(biāo)則用同樣的方法先來處理這個目標(biāo).如目標(biāo)不是一個存在的文件時,則一定執(zhí)行.123/16/2023一個簡單的makefile文件例如:Makefile

hello:a.ob.o

gcca.ob.o-ohello

a.o:a.c

gcc–ca.cb.o:b.c

gcc–cb.c當(dāng)運(yùn)行make時,可以接一目標(biāo)名(eg:makehello)作為參數(shù),表示要處理改目標(biāo)。如沒有參數(shù),則處理第一個目標(biāo)。對上述例子執(zhí)行make,則是處理hello這個目標(biāo)。hello依賴于文件目標(biāo)a.o和b.o,則先去處理a.o,調(diào)用gcc–ca.c來更新a.o,之后更新b.o,最后調(diào)用gcca.cb.o-ohello來更新hello.133/16/2023Make中的宏(macro)在make中是用宏,要先定義,然后在makefile中引用。宏的定義格式為:宏名=宏的值(宏名一般習(xí)慣用大寫字母)例:CC=gcchello:a.ob.o

$(CC)a.ob.o-ohelloa.o:a.c

$(CC)–ca.cb.o:b.c

$(CC)–cb.c143/16/2023系統(tǒng)定義的宏還有一些設(shè)定好的內(nèi)部變量,它們根據(jù)每一個規(guī)則內(nèi)容定義。$@當(dāng)前規(guī)則的目的文件名$<依靠列表中的第一個依靠文件$^整個依靠的列表(除掉了里面所有重復(fù)的文件名)。$?依賴中所有新于目標(biāo)的以用變量做許多其它的事情,特別是當(dāng)你把它們和函數(shù)混合使用的時候。如果需要更進(jìn)一步的了解,請參考GNUMake手冊。('manmake','manmakefile')153/16/2023修改原先的makefileCC=gccCFLAGS=-O2OBJS=a.ob.ohello:$(OBJS) $(CC)$^-o$@a.o:a.c $(CC)$(CFLAGS)-c$<b.o:b.c $(CC)$(CFLAGS)-c$<clean: rm–f*.ohello163/16/2023隱含規(guī)則請注意在上面的例子里,幾個產(chǎn)生.o文件的命令都是一樣的,都是從.c文件和相關(guān)文件里產(chǎn)生.o文件,這是一個標(biāo)準(zhǔn)的步驟。其實(shí)make已經(jīng)知道怎么做—它有一些叫做隱含規(guī)則的內(nèi)置的規(guī)則,這些規(guī)則告訴它當(dāng)你沒有給出某些命令的時候,應(yīng)該怎么辦。如果你把生成a.o和b.o的命令從它們的規(guī)則中刪除,make將會查找它的隱含規(guī)則,然后會找到一個適當(dāng)?shù)拿?。它的命令會使用一些變量,因此你可以按照你的想法來設(shè)定它:它使用變量CC做為編譯器,并且傳遞變量CFLAGS,CPPFLAGS,TARGET_ARCH,然后它加入‘-c’,后面跟變量$<,然后是‘-o’跟變量$@。一個C編譯的具體命令將會是:$(CC)$(CFLAGS)$(CPPFLAGS)$(TARGET_ARCH)-c$<-o$@當(dāng)然你可以按照你自己的需要來定義這些變量。173/16/2023用戶環(huán)境變量的設(shè)定183/16/2023LINUX中BASH環(huán)境變量的設(shè)定順序登錄Linux后,BASH要讀取幾個文件,這些文件(啟動腳本文件)用來定義BASH環(huán)境,如果希望建立標(biāo)準(zhǔn)的別名,或者希望設(shè)置各種shell變量,就應(yīng)該在bash啟動文件中進(jìn)行設(shè)置。和Bash的環(huán)境設(shè)定有關(guān)的文件有

(1)/etc/profile(主要)/etc/profile.d/*.sh(主要)

(2)$HOME/.bash_profile(主要)

(3)$HOME/.bash_login

(4)$HOME/.profile

$HOME/.bash_logout(主要)

(5)$HOME/.bashrc(主要)

/etc/bashrc193/16/2023LINUX中BASH環(huán)境變量的設(shè)定順序登入(login)交互式時(從字符終端或XWindow登錄)先執(zhí)行/etc/profile(包括/etc/profile.d/*.sh)2.接著bash會檢查使用者的自家目錄中,是否有.bash_profile或者.bash_login或者.profile,若有,則會執(zhí)行其中一個,執(zhí)行順序?yàn)椋?bash_profile最優(yōu)先.bash_login其次.profile最后(執(zhí)行最先碰到的一個,前面的設(shè)定會被后面的覆蓋)3.啟動后讀取.bashrc203/16/2023LINUX中BASH環(huán)境變量的設(shè)定順序非登錄交互式(從其它shell或者bash啟動一個新的shell)

bash會檢查使用者的自家目錄中是否有.bashrc,若有則予以執(zhí)行,這是唯一的啟動文件.非交互式(即運(yùn)行SHELL腳本)上述所有腳本都不執(zhí)行,如果定義了環(huán)境變量ENV,則ENV的值作為啟動腳本文件名首先執(zhí)行。在前兩種情況下,如果定義了環(huán)境變量ENV,則首先讀取ENV指定的文件,然后按順序讀取前述腳本文件。登出(exit/logout)時bash會檢查使用者自家目錄中是否有.bash_logout,若有,則bash會執(zhí)行其中的指令213/16/2023LINUX中BASH環(huán)境變量的設(shè)定順序各文件用途說明/etc/profile由root所控制,用來設(shè)定適合全體使用者的shell環(huán)境2.若使用者自己覺得/etc/profile的設(shè)定,并不合意,可以修改自家目錄中的.bash_profile3..bash_login及.profile是為了方便那些從Bourneshell移轉(zhuǎn)過來的用戶,只要將Bourneshell主要的啟動檔.profile移到自家目錄中,放棄使用.bash_profile及.bash_login即可繼續(xù)沿用以前的設(shè)定環(huán)境223/16/2023LINUX中BASH環(huán)境變量的設(shè)定順序各文件用途說明4..bashrc則是用來設(shè)定subshell的環(huán)境的,之所以要有這個.bashrc是為避免subshell產(chǎn)生時,又重覆將/etc/profile執(zhí)行一次.我們發(fā)現(xiàn).bashrc中已預(yù)先會去執(zhí)行/etc/bashrc的指令,這表示,或許root會將產(chǎn)生subshell時的環(huán)境設(shè)好了,使用者只要沿用/etc/bashrc的內(nèi)容,應(yīng)該不會有任何問題.5..bash_logout是使用者登出主機(jī)之前,會去執(zhí)行的設(shè)定檔,如果使用者希望在他登出系統(tǒng)之后,能幫他自動處理一些瑣事,比如:清除臨時文件,清除屏幕等,可以在這個檔案中加以設(shè)定.233/16/2023使用庫243/16/2023使用編程庫編程庫兩個主要優(yōu)點(diǎn)實(shí)現(xiàn)代碼重用提供數(shù)百行經(jīng)過測試和調(diào)試的工具代碼命名和編號約定以lib開頭(gcc會在-l選項(xiàng)所指定的文件名前自動插入lib)文件名以.a(archive)結(jié)尾的庫都是靜態(tài)庫文件名以.so(sharedobject)結(jié)尾的庫都是共享庫如libdl.a是一個靜態(tài)庫而libc.so是一個共享庫253/16/2023使用編程庫編號約定一般格式為library_name.major_num.minor_num.patch_num如libgdbm.so.2.0.0,library_name為libgdbm.so,major_num是2,minor_num是0,patch_num是0當(dāng)庫有新的變化和以前不能兼容時需要增加major_num當(dāng)庫有新的變化又能和以前版本兼容時只改變minor_num為修正庫中錯誤進(jìn)行的改動只會改變patch_num兩類特殊的庫以_g結(jié)尾的庫(調(diào)試庫)以_p結(jié)尾的庫(代碼剖析庫profiling)如libform_g.a和libform_p.a,他們是基本庫libform.a的特殊版本263/16/2023庫操作工具nm命令nm列出編入目標(biāo)文件或者二進(jìn)制文件的所有符號可以查看程序調(diào)用了什么函數(shù)或者查看給定的庫或者目標(biāo)文件是否提供了所需的函數(shù)nm[options]file常用options:-c|--demangle將符號名轉(zhuǎn)換為用戶級的名字,在讓C++函數(shù)名可讀方面特別有用-s|--print-armap當(dāng)用于.a文件時,輸出把符號名映射到定義該符號的模塊或成員名的索引-u|--undefined-only只顯示未定義的符號(在被檢查的文件外部定義的符號)273/16/2023庫操作工具ar用來操縱高度結(jié)構(gòu)化的庫文件(靜態(tài)庫),最常用來創(chuàng)建靜態(tài)庫創(chuàng)建和維護(hù)符號名的交叉索引表,如函數(shù)和變量名到定義它們的成員之間的交叉索引表ar{dmpqrtx}[member]archivefiles....常用選項(xiàng)–c-s-r–q-r:向存檔文件插入files,替換已有的任何同名成員。新成員添加到存檔文件的末尾。-s:創(chuàng)建或升級從符號到定義他們的成員之間的交叉索引映射表ranlib–vfile等價于ar–sfile283/16/2023庫操作工具lddldd命令列出為使程序正常運(yùn)行所需的共享庫用法ldd[options]file常用選項(xiàng):-d執(zhí)行重定位并報(bào)告所有丟失的函數(shù)-r執(zhí)行對函數(shù)和數(shù)據(jù)對象的重定位并報(bào)告丟失的任何函數(shù)或數(shù)據(jù)對象。293/16/2023庫操作工具ldconfig用法ldconfig[options]libsldconfig決定位于目錄/usr/lib(lib64)和/lib(lib64)下的共享庫所需的運(yùn)行的鏈接,這些鏈接在命令行上的庫被保存在/etc/ld.so.conf中常用選項(xiàng)-p僅打印出文件/etc/ld.so.cache的內(nèi)容,此文件是ld.so所知道的共享庫的當(dāng)前列表-v更新/etc/ld.so.cache的內(nèi)容,列出每個庫的版本號,掃描的目錄和所有創(chuàng)建和更新的鏈接。303/16/2023環(huán)境變量和配置文件動態(tài)鏈接器/加載器ld.so使用的兩個環(huán)境變量$LD_LIBRARY_PATH一個由冒號分割的目錄清單,在這些目錄下可以搜索運(yùn)行時的共享庫可以用這個環(huán)境變量告訴ld.so在哪兒找到?jīng)]有保存在標(biāo)準(zhǔn)位置的庫;這點(diǎn)跟$PATH類似第二個環(huán)境變量是$LD_PRELOAD,一個由空格分割的、附加的、用戶指定共享庫,

溫馨提示

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

評論

0/150

提交評論