




已閱讀5頁,還剩125頁未讀, 繼續免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第三章 嵌入式Linux編程環境,在Linux系統中,開發應用程序。需要掌握以下基本內容 會用Linux下的vi編輯器及底行命令 掌握Linux的編譯器的配置及編譯命令 會使用Linux的gdb調試器的相關調試命令 熟悉Linux的Make管理器的使用,學習目標,主要內容,2,3,Linux編輯器vi的使用,gcc編譯器,4,gdb調試器,6,autotools,5,Make工程管理器,1,Linux下C編程環境,一、Linux下C編程環境,Linux 下的C語言程序設計與在其他環境中的C程序設計一樣,主要涉及到編輯器、編譯鏈接器、調試器及項目管理工具。,C程序編譯過程,一、Linux下C編程環境,(1)編輯器 Linux 下的編輯器就如Windows下的word、記事本等一樣,完成對所錄入文字的編輯功能。Linux 中最常用的編輯器有Vi(Vim)和Emacs。它們功能強大,使用方便,根據自己的愛好選擇Vi 和Emacs。,(2)編譯鏈接器 編譯是指源代碼轉化生成可執行代碼的過程,編譯過程是非常復雜的,它包括詞法、語法和語義的分析、中間代碼的生成和優化、符號表的管理和出錯處理等。 在Linux中,最常用的編譯器是Gcc編譯器。它是GNU推出的功能強大、性能優越的多平臺編譯器,其執行效率與一般的編譯器相比平均效率要高20%30%,堪稱為GNU的代表作品之一。,一、Linux下C編程環境,(3)調試器 調試器并不是代碼執行的必備工具,而是專為程序員方便調試程序而用的。有編程經驗都知道,在編程的過程當中,往往調試所消耗的時間遠遠大于編寫代碼的時間。因此,有一個功能強大、使用方便的調試器是必不可少的。 gdb 是絕大多數Linux 開發人員所使用的調試器,它可以方便地設置斷點、單步跟蹤等,足以滿足開發人員的需要。,一、Linux下C編程環境,一、Linux下C編程環境,(4)項目管理器 Linux 中的項目管理器“make”有些類似于Windows 中Visual C+里的“工程”,它是一種控制編譯或者重復編譯軟件的工具,另外,它還能自動管理軟件編譯的內容、方式和時機,使程序員能夠把精力集中在代碼的編寫上而不是在源代碼的組織上。,主要內容,2,3,Linux編輯器vi的使用,gcc編譯器,4,gdb調試器,6,autotools,5,Make工程管理器,1,Linux下C編程環境,二、Linux編輯器vi的使用,vi的模式 vi的基本流程 vi模式的功能鍵,二、Linux編輯器vi的使用,1、vi模式,Linux編輯器 行編輯器(ed、ex) 行編輯器每次只能對單行進行操作,使用起來很不方便。 全屏幕編輯器(vi、emacs) 全屏幕編輯器可以對整個屏幕進行編輯,用戶編輯的文件直接顯示在屏幕上。 vi是Linux系統的第一個全屏幕交互式編輯程序。 注意:vi的升級版v im已經問世了,功能相當強大,且保持與Vi 的90%相兼容,因此,感興趣的話可以查看相關資料進行學習。,二、Linux編輯器vi的使用,1、vi模式,Linux編輯器 visual interface,可視化編輯器 vi可以執行輸出、刪除、查找、替換、塊操作等眾多文本操作,而且用戶可以根據自己的需要對其進行定制. 只是一個文本編輯器,不能排版 vi沒有菜單,只有命令 vi有三種基本工作模式,分別是:命令模式(command mode)、插入模式(insert mode)和底行模式(last line mode),三種工作模式,二、Linux編輯器vi的使用,1、vi模式,(1)命令行模式 在用vi編輯文件時,最初進入的為一般模式。在該模式中可以通過上下移動光標進行“刪除字符”或“整行刪除”等操作,也可以進行“復制”、“粘貼”等操作,但無法編輯文字。 (2)插入模式 只有在該模式下,用戶才能進行文字編輯輸入,按ESC鍵回到命令行模式。 (3)底行模式 在該模式下,光標位于屏幕的底行。用戶可以進行文件保存或退出操作,也可以設置編輯環境,如尋找字符串、列出行號等。,二、Linux編輯器vi的使用,2、vi的基本操作,(1)進入vi: 命令格式:vi 文件名,此時進入的是命令行模式,光標位于屏幕的上方。 選項“+n”,表示希望在進入vi之后,光標處于文件中第n行上, 選項“+”表示希望在進入vi之后光標處于文件最末行,二、Linux編輯器vi的使用,2、vi的基本操作,(2)插入模式: 在命令行模式下鍵入i進入到插入模式。可以看出,在屏幕底部顯示有“插入”表示插入模式,在該模式下可以輸入文字信息。,二、Linux編輯器vi的使用,2、vi的基本操作,(3)底行模式: 在插入模式中,輸入“Esc”,則當前模式轉入命令行模式。,二、Linux編輯器vi的使用,2、vi的基本操作,(4)保存文件: 1.在命令模式下,連按兩次大寫字母。 2.在末行模式下: :w vi保存當前編輯的文件,但并不退出vi,而是繼續等待用戶輸入命令。 :w :w! 把當前文件的內容保存到指定的文件newfile中,如果newfile已經存在,則覆蓋原有內容。,二、Linux編輯器vi的使用,2、vi的基本操作,(5)退出vi: 在底行模式下,有四種方法可以退出vi返回到shell: :q 系統退出vi返回到shell。在用此命令時,若編輯的文件沒有被保存,則vi在窗口的最末行給出提示信息。 :q! vi放棄所作修改而直接退到shell下。 :wq 先保存文件,然后再退出vi返回到shell。 :x 該命令的功能與命令模式下的ZZ命令功能相同,二、Linux編輯器vi的使用,2、vi的基本操作,(6)vi中的行號: 命令格式:set number 或者:set nu (設置) 命令格式:set nonumber 或者:set nonu (取消) (7)vi中進入相應的行: 命令格式:n (行號) (8)vi中查找字符: 命令格式:/name (在光標之后查找name) 命令格式:?name (在光標之前查找name),二、Linux編輯器vi的使用,3、vi的功能鍵,Vi舉例,為了快速獲得對linux平臺下應用程序設計的體驗,首先編寫經典的hello world程序。 首先,進入linux的控制臺界面。 然后,在某個目錄建立一個空的c程序文件,比如利用 touch /home/hello.c命令 然后cd到當前目錄,調用vi編輯器對這個空文件進行編輯,輸入這個程序的源代碼,(利用vi hello.c命令,進入vi編輯器,然后進入vi的編輯狀態,然后輸入程序,然后進入vi的底行狀態,進行源程序的保存和vi的退出,回到shell提示符。),二、Linux編輯器vi的使用,Vi舉例,二、Linux編輯器vi的使用,-hello.c- #include int main() printf(“Hello, Linux programming world!n“); return 0; -,主要內容,2,3,Linux編輯器vi的使用,gcc編譯器,4,gdb調試器,6,autotools,5,Make工程管理器,1,Linux下C編程環境,三、gcc編譯器,gcc編譯流程 gcc編譯操作,三、gcc編譯器,GNU CC(簡稱為Gcc)是GNU項目中符合ANSI C標準的編譯系統,能夠編譯用C、C+和Object C等語言編寫的程序。gcc不僅功能強大,而且可以編譯如C、C+、Object C、Java、Fortran、Pascal、Modula-3和Ada等多種語言。 gcc又是一個交叉平臺編譯器,它能夠在當前CPU平臺上為多種不同體系結構的硬件平臺開發軟件,因此尤其適合在嵌入式領域的開發編譯。 在Linux下,gcc一般存放在/usr/bin目錄下;其頭文件一般存放在/usr/include及其下級子目錄里;而標準的庫文件則存放在/lib或/usr/lib子目錄里。,三、gcc編譯器,gcc支持編譯源文件的后綴及其解釋。,三、gcc編譯器,1、gcc編譯流程,gcc的編譯流程分為了4個步驟,分別為: 預處理(Pre-Processing); 編譯(Compiling); 匯編(Assembling); 鏈接(Linking)。,Gcc命令依次調用gcc的預編譯器(cpp),編譯器(ccl,生成.s文件),匯編器(as,生成.o文件)和鏈接器程序(ld)。,三、gcc編譯器,1、gcc編譯流程,三、gcc編譯器,1、gcc編譯流程,(1)預處理階段,以hello.c源代碼為例:,該階段,編譯器將上述代碼中的stdio.h編譯進來,并且用戶可以使用Gcc的選項“-E” 進行查看,,在此處,選項“-o”是指目標文件,“.i”文件為已經過預處理的C 原始程序。,三、gcc編譯器,1、gcc編譯流程,由此可見,Gcc確實進行了預處理,它把“stdio.h”的內容插入到hello.i文件中。,以下列出了hello.i文件的部分內容:,三、gcc編譯器,1、gcc編譯流程,(2)編譯階段 在這個階段中,Gcc 首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤后,Gcc 把代碼翻譯成匯編語言。用戶可以使用“-S”選項來進行查看,該選項只進行編譯而不進行匯編,生成匯編代碼。,以下列出了hello.s的內容,可見Gcc已經將其轉化為匯編了。,三、gcc編譯器,三、gcc編譯器,1、gcc編譯流程,(3)匯編階段 匯編階段是把編譯階段生成的“.s”文件轉成目標文件,讀者在此可使用選項“-c”就可看到匯編代碼已轉化為“.o”的二進制目標代碼了。如下所示: (4)鏈接階段 在成功編譯之后,就進入了鏈接階段。在這里涉及到一個重要的概念:函數庫(printf函數,stdio.h)。 Gcc會到系統默認的搜索路徑“/usr/lib”下進行查找,也就是鏈接到libc.so.6庫函數中去,這樣就能實現函數“printf”了,而這也就是鏈接的作用。,三、gcc編譯器,1、gcc編譯流程,完成了鏈接之后,Gcc就可以生成可執行文件,如下所示:,運行該可執行文件,出現正確的結果如下:,多個源文件生成一個可執行文件 方法1:gcc Wall o mytest test1.c test2.c test3.c 方法2: gcc-Wall -c test1.c gcc-Wall c test2.c gcc-Wall c test3.c gcc o mytest test1.o test2.o test3.o,三、gcc編譯器,1、gcc編譯流程,補充:頭文件和函數庫,linux程序開發的頭文件 函數庫 靜態庫 共享庫,三、gcc編譯器,1、gcc編譯流程,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,一般而言,每個C+/C程序通常由頭文件(header files)和定義文件(definition files)組成。 頭文件作為一種包含功能函數、數據接口聲明的載體文件,用于保存程序的聲明(declaration),而定義文件用于保存程序的實現(implementation)。 C+/C程序的頭文件以“.h”為后綴。,(1)頭文件,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(1)頭文件,對c語言來說,頭文件一般存在于目錄/usr/inlcude下面 而對于linux操作系統的頭文件,一般存在于目錄/usr/include/sys和/usr/include/linux下。 其他程序設計系統也可能有自己單獨的目錄,比如/usr/include/X11或者/usr/include/g+等。,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(1)頭文件,Gcc的一個可選參數:I,用于在編譯階段,指定非標準位置的頭文件。 比如:gcc I /usr/*/include test.c會在指定的位置查找test.c文件所include的一些頭文件。,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(2)函數庫,定義:是一些預先編譯好的函數的集合,那些函數都是按照可再使用的原則編寫的。它們通常是一組相互關聯的用來完成某項常見工作的函數構成(比如c庫里面的標準輸入輸出函數、時間函數和數學函數等)。 庫文件的含義:就是一組處于可以“拿來就用”的狀態下的二進制目標代碼。當有程序需要用的函數庫中的某個函數的時候,就會通過include語句引用對此函數做出聲明的頭文件。 程序函數庫可以使整個程序更加模塊化,更容易重新編譯,而且更方便升級。,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(2)函數庫,編譯器和鏈接程序負責把程序代碼和庫函數結合在一起成為一個獨立的可執行程序。如果使用的不是標準的c語言運行庫而是某個擴展庫,則必須指定它的位置和名字(使用I,L和l參數)。 在鏈接階段,會搜索一些默認的目錄,比如/lib和/usr/lib等來查找需要的庫文件。,庫文件,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(2) 函數庫,庫文件,命名規則:一般是以lib打頭,然后后面接上表示函數庫功能的名字部分。比如libc、libm和libcap等。 類型:分成靜態庫和共享庫,后綴名分別是a和so(一般在系統中的/lib中,兩個版本都存在)。而在win平臺下面,分別是lib和dll。,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(2) 函數庫,庫文件,在編譯程序的時候,為了保證鏈接的正常進行,可以告訴gcc庫文件的位置(當然,標準的c庫是不需要指定的,其他的非標準庫則要指定)。 Gcc的一個可選參數:L,用于在鏈接階段,指定非標準庫文件的位置。 比如: $gcc o x11fred L/usr/openwin/lib x11fred.c lX11,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(3) 靜態庫,靜態函數庫(static libraries):是一個普通的目標文件的集合,也叫歸檔文件,一般用“.a”作為文件的后綴,比如libc.a和libX11.a等。 自己建立靜態函數庫的方法: 編寫庫函數的時候,盡量把不同類型函數實現編寫到不同的源代碼文件里面; 然后使用gcc的編譯命令對各個文件進行獨立編譯,從而得到各自的目標文件; 然后使用ar命令把各個目標文件打包在一起。,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(3) 靜態庫,1)編寫一個小函數庫,這個函數庫里面有兩個函數。分別使用兩個源代碼文件。,靜態庫:Example,-bill.c- #include void bill(char *arg) printf(“bill: you passed %sn“, arg); ,-fred.c- #include void fred(int arg) printf(“fred: you passed %dn“, arg); ,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(3) 靜態庫,靜態庫:Example 2)各自代碼如下:,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(3) 靜態庫,3)進行兩個源代碼文件的編譯 $ gcc c bill.c fred.c $ ls *.o bill.o fred.o 4)利用ar命令,把目標代碼添加到一個庫文件中去。 $ ar crv libfoo.a bill.o fred.o,靜態庫:Example,ar 命令,1、創建庫文件 通常人們使用“ar cru liba.a a.o“這樣的命令來創建一個庫并把a.o添加進去。“c“關鍵字告訴ar需要創建一個新庫文件,如果沒有指定這個標志則ar會創建一個文件,同時會給出 一個提示信息,“u“用來告訴ar如果a.o比庫中的同名成員要新,則用新的a.o替換原來的,這個參數可有可無的,可能是不同版本的ar 行為不一樣吧。實際上用“ar -r liba.a a.o“在freebsd5上面始終可以成功。 -v程序執行時顯示詳細的信息。 2、加入新成員 使用“ar -r liba.a b.o“即可以將b.o加入到liba.a中。默認的加入方式為append,即加在庫的末尾。“r“關鍵字可以有三個修飾符“a“, “b“和“i“。 “a“表示after,即將新成員加在指定成員之后。例如“ar -ra a.c liba.a b.c“表示將b.c加入liba.a并放在已有成員a.c之后; “b“表示before,即將新成員加在指定成員之前。例如“ar -rb a.c liba.a b.c“; “i“表示insert,跟“b“作用相同。,ar 命令,3、列出庫中已有成員 “ar -t liba.a“即可。如果加上“v“修飾符則會一并列出成員的日期等屬性。 4、刪除庫中成員 “ar -d liba.a a.c“表示從庫中刪除a.c成員。如果庫中沒有這個成員ar也不會給出提示。如果需要列出被刪除的成員或者成員不存在的信息,就加上“v“修飾符。 5、從庫中解出成員 “ar -x liba.a b.c“ 6、調整庫中成員的順序 使用“m“關鍵字。與“r“關鍵字一樣,它也有3個修飾符“a“,“b“, “i“。如果要將b.c移動到a.c之前,則使用“ar -mb a.c liba.a b.c“,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,(3) 靜態庫,靜態庫:Example,5)為了讓庫的使用者可以重復利用庫所提供的函數,要編寫一個頭文件,在其中聲明庫都是對外提供了哪些函數。如果另外一個程序員打算使用庫所提供的服務,則必須在頭文件中include這個頭文件。,lib.h- /* This is lib.h. It declares the functions fred and bill for users */ void bill(char *); void fred(int);,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,靜態庫:Example,(3) 靜態庫,6)編寫一個測試程序,使用庫中的一個函數。源代碼如下: program.c- #include “lib.h“ int main() bill(“Hello World“); exit(0); ,(3) 靜態庫,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,靜態庫:Example,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,靜態庫:Example,(3) 靜態庫,7)編譯和運行 第一個方法- $ gcc c program.c $ gcc o program program.o bill.o 第二個方法- $ gcc o program program.o libfoo.a 第三個方法- $gcc o program program.o L. l foo $ ./program bill: you passed Hello World $,函數庫一般分為靜態庫和動態庫兩種。 靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其后綴名一般為“.a”。 動態庫與之相反,在編譯鏈接時并沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般后綴名為“.so”,如前面所述的libc.so.6就是動態庫。Gcc在編譯時默認使用動態庫。,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,總結:函數庫和頭文件的保存位置,函數庫 /lib:系統必備共享函數庫 /usr/lib:標準共享函數庫和靜態函數庫 /usr/i486-linux-libc5/lib:libc5 兼容性函數庫 /usr/X11R6/lib:X11R6 的函數庫 /usr/local/lib:本地函數庫 頭文件 /usr/include:系統頭文件 /usr/local/include:本地頭文件,補充:頭文件和函數庫,三、gcc編譯器,1、gcc編譯流程,三、gcc編譯器,2、gcc編譯選項參數,Gcc 有超過100 個的可用選項,主要包括總體選項、告警和出錯選項、優化選項和體系結構相關選項。 總體選項,三、gcc編譯器,2、gcc編譯選項參數,在gcc中用開關-Wall控制警告信息; 使用示例命令如下:gccWall -o test3_1 test3_1.c 告警出錯選項,三、gcc編譯器,2、gcc編譯選項參數,gcc可以對代碼進行優化,它通過編譯選項“-On”來控制 優化代碼的生成,其中n是一個代表優化級別的整數。比較典型的范圍是從0變化到2或3。 優化選項,主要內容,2,3,Linux編輯器vi的使用,gcc編譯器,4,gdb調試器,6,autotools,5,Make工程管理器,1,Linux下C編程環境,四、gdb調試器,gdb使用流程 gdb基本操作命令,四、gdb調試器,調試是所有程序員都會面臨的問題。如何提高程序員的調試效率,更好更快地定位程序中的問題從而加快程序開發的進度,是大家共同面對的。 gdb(GeoDatabase,即空間數據庫)調試器是一款GNU開發組織并發布的UNIX/Linux下的程序調試工具。雖然,它沒有圖形化的友好界面,但是它強大的功能也足以與微軟的VC工具等媲美。,1、gdb調試流程,(1)打開Linux 下的編輯器Vi或者Emacs,編輯代碼; 注:在保存退出后首先使用Gcc對test.c進行編譯,注意一定要加上選項“-g”,這樣編譯出的可執行代碼中才包含調試信息,否則之后Gdb 無法載入該可執行文件。,四、gdb調試器,1、gdb調試流程,(2)啟動Gdb 進行調試。 注意,Gdb進行調試的是可執行文件,而不是如“.c”的源代碼,因此,需要先通過Gcc編譯生成可執行文件才能用Gdb進行調試。,四、gdb調試器,1、gdb調試流程,(3)(gdb)”開頭的命令行界面進行調試。 查看文件 在Gdb 中鍵入“l”(list)就可以查看所載入的文件; 設置斷點 在 Gdb 中設置斷點非常簡單,只需在“b”后加入對應的行號即可;,四、gdb調試器,另外還可以設置函數斷點和條件斷點 函數斷點,gdb中按函數設置斷點,只需把函數名列在命令“b”之后 條件斷點,gdb中設置條件斷點的格式為: b 行數或函數名 if 表達式,1、gdb調試流程,(3)(gdb)”開頭的命令行界面進行調試。 查看斷點情況 在設置完斷點之后,用戶可以鍵入“info b”來查看設置斷點情況,在Gdb 中可以設置多個斷點。,四、gdb調試器,1、gdb調試流程,(3)(gdb)”開頭的命令行界面進行調試。 運行代碼 Gdb默認從首行開始運行代碼,可鍵入“r”(run)即可(若想從程序中指定行開始運行,可在r 后面加上行號)。,四、gdb調試器,1、gdb調試流程,(3)(gdb)”開頭的命令行界面進行調試。 查看變量值 在程序停止運行之后,所要做的工作是查看斷點處的相關變量值。在Gdb 中只需鍵入“p”變量值即可,如下所示:,四、gdb調試器,1、gdb調試流程,(3)(gdb)”開頭的命令行界面進行調試。 單步運行 單步運行可以使用命令“n”(next)或“s”(step),它們之間的區別在于:若有函數調用的時候,“s”會進入該函數而“n”不會進入該函數。因此,“s”就類似于VC等工具中的 “step in”,“n”類似與VC等工具中的“step over”。它們的使用如下所示:,四、gdb調試器,1、gdb調試流程,(3)(gdb)”開頭的命令行界面進行調試。 恢復程序運行 在查看完所需變量及堆棧情況后,就可以使用命令“c”(continue)恢復程序的正常運行了。這時,它會把剩余還未執行的程序執行完,并顯示剩余程序中的執行結果。,四、gdb調試器,2、gdb基本命令,工作環境相關命令,四、gdb調試器,2、gdb基本命令,設置斷點與恢復命令,四、gdb調試器,2、gdb基本命令,查看源碼命令,四、gdb調試器,2、gdb基本命令,查看運行命令,四、gdb調試器,2、gdb基本命令,gdb中修改運行參數相關命令 gdb還可以修改運行時的參數,并使該變量按照用戶當前輸入的值繼續運行。它的設置方法為:在單步執行的過程中,鍵入命令“set 變量設定值”。這樣,在此之后,程序就會按照該設定的值運行了。,四、gdb調試器,主要內容,2,3,Linux編輯器vi的使用,gcc編譯器,4,gdb調試器,6,autotools,5,Make工程管理器,1,Linux下C編程環境,五、Make工程管理器,Makefile基本結構 Makefile變量 Makefile規則 Make管理器的使用,1、Makefile基本結構,五、Make工程管理器,所謂工程管理器,顧名思義,是指管理較多的文件的。 Make工程管理器也就是個“自動編譯管理器”,這里的“自動”是一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。 Make工具最主要也是最基本的功能就是通過Makefile文件來描述源程序之間的相互關系并自動維護編譯工作。 Makefile 文件需要按照某種語法進行編寫,文件中需要說明如何編譯各個源文件并連接生成可執行文件,并要求定義源文件之間的依賴關系。并針對每個需要更新的文件給出具體的控制命令。,1、Makefile基本結構,(1)Makefile介紹 Makefile是用于自動編譯和鏈接的,一個工程有很多文件組成,每一個文件的改變都會導致工程的重新鏈接,但是不是所有的文件都需要重新編譯,Makefile中紀錄有文件的信息,在make時會決定在鏈接的時候需要重新編譯哪些文件。 Makefile的宗旨就是:讓編譯器知道要編譯一個文件需要依賴其他的哪些文件。當那些依賴文件有了改變,編譯器會自動的發現最終的生成文件已經過時,而重新編譯相應的模塊。,五、Make工程管理器,1、Makefile基本結構,五、Make工程管理器,(2) Makefile基本結構 Makefile 是Make 讀入的惟一配置文件,在一個Makefile中通常包含如下內容: 需要由make工具創建的目標體(target),通常是目標文件或可執行文件; 要創建的目標體所依賴的文件(dependency_file); 創建每個目標體時需要運行的命令(command) 在Makefile文件中,開頭為“#”的行是注釋行。文件開頭部分的“=”賦值語句定義了一些參數或命令的縮寫。,1、Makefile基本結構,五、Make工程管理器,(3)Makefile格式,例如,有兩個文件分別為hello.c 和hello.h,創建的目標體為hello.o,執行的命令為gcc編譯指令:gcc c hello.c,那么,對應的Makefile就可以寫為:,注意:在Makefile中的每一個command前必須有“Tab”符,否則在運行make命令時會出錯。,1、Makefile基本結構,五、Make工程管理器,使用make的格式為:make target,這樣make就會自動讀入Makefile(也可以是首字母小寫makefile)并執行對應target 的command 語句,并會找到相應的依賴文件。如下所示:,可以看到,Makefile執行了“hello.o”對應的命令語句,并生成了“hello.o”目標體。,(3)Makefile格式,上面示例的Makefile在實際中是幾乎不存在的,因為它過于簡單,僅包含兩個文件和一個命令,在這種情況下完全不必要編寫Makefile而只需在Shell中直接輸入即可。 在實際中使用的Makefile往往是包含很多的文件和命令的,這也是Makefile產生的原因。,2、Makefile的變量,五、Make工程管理器,1 sunq: kang.o yul.o 2 gcc kang.o yul.o -o sunq 3 4 kang.o: kang.c kang.h 5 gcc -wall -o -g -c kang.c -o kang.o 6 yul.o: yul.c yul.h 7 gcc -wall -o -g -c yul.c -o yul.o,2、Makefile的變量,五、Make工程管理器,例如:包含很多文件和命令的makefile,rootlocalhost makefile#make sunq,2、Makefile的變量,五、Make工程管理器,為了簡化編輯和維護Makefile,make允許在Makefile中創建和使用變量。 變量是在Makefile中定義的名字,用來代替一個文本字符串,該文本字符串稱為該變量的值。 這些值可以代替目標體、依賴文件、命令以及makefile文件中其它部分。在Makefile中的變量定義有兩種方式:一種是遞歸展開方式,另一種是簡單方式。 遞歸展開方式的定義格式為:VAR=var 簡單擴展方式的定義格式為:VAR:=var Make中的變量使用均使用格式為:$(VAR) Makefile中的變量分為用戶自定義變量、預定義變量、自動變量和環境變量。,1 sunq: kang.o yul.o 2 gcc kang.o yul.o -o sunq 3 kang.o: kang.c kang.h 4 gcc -wall -o -g -c kang.c -o kang.o 5 yul.o: yul.c yul.h 6 gcc -wall -o -g -c yul.c -o yul.o,2、Makefile的變量,五、Make工程管理器,2、Makefile的變量,1OBJS = kang.o yul.o 2 CC = gcc 3 CFLAGS = -wall -o -g 4 sunq: $(OBJS) 6 $(CC) $(OBJS) -o sunq 7 kang.o: kang.c kang.h 8 $(CC) $(CFLAGS) -c kang.c -o kang.o 9 yul.o: yul.c yul.h 10 $(CC) $(CFLAGS) -c yul.c -o yul.o,2、Makefile的變量及規則,五、Make工程管理器,Makefile中常見預定義變量 預定義變量包含了常見編譯器、匯編器的名稱以及編譯選項。,2、Makefile的變量及規則,五、Make工程管理器,Makefile中常見自動變量 引入了自動變量。自動變量通常可以代表編譯語句中出現的目標文件和依賴文件等。,五、Make工程管理器,2、Makefile的變量,1 sunq: kang.o yul.o 2 gcc kang.o yul.o -o sunq 3 kang.o: kang.c kang.h 4 gcc -wall -o -g -c kang.c -o kang.o 5 yul.o: yul.c yul.h 6 gcc -wall -o -g -c yul.c -o yul.o,1 OBJS = kang.o yul.o 2 CC = gcc 3 CFLAGS = -wall -o -g 4 sunq: $(OBJS) 5 $(CC) $ -o $ 6 kang.o: kang.c kang.h 7 $(CC) $(CFLAGS) -c $ -o $ 8 yul.o: yul.c yul.h 9 $(CC) $(CFLAGS) -c $ -o $,3、Makefile的規則,五、Make工程管理器,Makefile的規則是Make進行處理的依據,它包括了目標體、依賴文件及其之間的命令語句。 一般的,Makefile中的一條語句就是一個規則。在前面的例子中,都顯示地指出了Makefile中的規則關系: 如 “gcc c hello.c o hello.o” 或 “$(CC) $(CFLAGS) -c $ -o $” 但為了簡化Makefile的編寫,make還定義了隱式規則和模式規則,3、Makefile的規則,五、Make工程管理器,隱式規則 make 工具中包含有一些內置的或隱含的規則,這些規則定義了如何從不同的依賴文件建立特定類型的目標 ,Linux系統通常支持一種基于文件擴展名即文件名后綴的隱含規則。 這種后綴規則定義了如何將一個具有特定文件名后綴的文件(例如.c文件),自動轉換成為具有另一種文件名后綴的文件(例如.o文件) Make的隱含規則指出:所有“.o”文件都可自動由“.c”文件使用命令“$(CC) $(CPPFLAGS) $(CFLAGS) -c file.c o file.o”生成。 注意:在隱式規則只能查找到相同文件名的不同后綴名文件。,3、Makefile的規則,五、Make工程管理器,隱式規則 系統中默認的常用文件擴展名及其含義為: .o 目標文件 .c C源文件 .s 匯編源文件 .f FORTRAN源文件 .y Yacc-C源語法 .l Lex源語法,3、Makefile的規則,五、Make工程管理器,隱式規則 例如: OBJS = kang.o yul.o CC = Gcc CFLAGS = -Wall -O -g sunq : $(OBJS) $(CC) $ -o $,3、Makefile的規則,五、Make工程管理器,模式規則 模式規則是用來定義相同處理規則的多個文件的。它不同于隱式規則,隱式規則僅僅能夠用make默認的變量來進行操作,而模式規則還能引入用戶自定義變量,為多個文件建立相同的規則,從而簡化Makefile的編寫。 模式規則的格式類似于普通規則,這個規則中的相關文件前必須用“%”標明。,3、Makefile的規則,五、Make工程管理器,模式規則 例如: OBJS = kang.o yul.o CC = Gcc CFLAGS = -Wall -O -g sunq : $(OBJS) $(CC) $ -o $ %.o : %.c $(CC) $(CFLAGS) -c $ -o $,例如: objects = foo.o bar.o # objects 一個變量 all: $(objects) $(objects): %.o: %.c #從$object中獲取依賴目標 “foo.c bar.c” $(CC) -c $(CFLAGS) $ -o $ # “$”表示所有的依賴目標 #集(也就是“foo.c bar.c”),“$”表示目標集(也就 #是“foo.o bar.o”) 等價于: foo.o : foo.c $(CC) -c $(CFLAGS) foo.c -o foo.o bar.o : bar.c $(CC) -c $(CFLAGS) bar.c -o bar.o,Makefile的編寫,3、Makefile的規則,五、Make工程管理器,Makefile里主要包含了五個東西:顯式規則、隱晦規則、變量定義、文件指示和注釋。 1、顯式規則。顯式規則說明了,如何生成一個或多的的目標文件。這是由Makefile的書寫者明顯指出,要生成的文件,文件的依賴文件,生成的命令。 2、隱含規則。由于我們的make有自動推導的功能,所以隱含的規則可以讓我們比較粗糙地簡略地書寫Makefile,這是由make所支持的。 3、變量的定義。在Makefile中我們要定義一系列的變量,變量一般都是字符串,這個有點你C語言中的宏,當Makefile被執行時,其中的變量都會被擴展到相應的引用位置上。,Makefile里主要包含了五個東西:顯式規則、隱晦規則、變量定義、文件指示和注釋。 4、文件指示。其包括了三個部分,一個是在一個Makefile中引用另一個Makefile,就像C語言中的include一樣;另一個是指根據某些情況指定Makefile中的有效部分,就像C語言中的預編譯#if一樣;還有就是定義一個多行的命令。有關這一部分的內容,我會在后續的部分中講述。 5、注釋。Makefile中只有行注釋,和Linux的Shell腳本一樣,其注釋是用“#”字符,這個就像C/C+中的“/”一樣。如果你要在你的Makefile中使用“#”字符,可以用反斜框進行轉義,如:“#”。 最后,還值得一提的是,在Makefile中的命令,必須要以Tab鍵開始。,3、Makefile的規則,五、Make工程管理器,4、Make管理器的使用,五、Make工程管理器,使用make管理器非常簡單,只需在make命令的后面鍵入目標名即可建立指定的目標,如果直接運行make,則建立Makefile中的第一個目標。 此外make還有豐富的命令行選項,可以完成各種不同的功能。,4、Make管理器的使用,五、Make工程管理器,make的命令行選項,4、Make管理器的使用,五、Make工程管理器,舉例說明: 第一步:先根據源程序寫一makefile文件,CC=gcc CFLAGS=-Wall hello: hello.o hello_fn.o clean: rm -f hello hello.o hello_fn.o,將輸出編譯過程: gcc -Wall -c -o hello.o hello.c gcc -Wall -c -o hello_fn.o hello_fn.c gcc hello.o hello_fn.o -o hello,4、Make管理器的使用,五、Make工程管理器,第二步:make,第三步:執行生成的可執行文件,輸入命令:,$ ./hello Hello,Embedded Linux!,4、Make管理器的使用,五、Make工程管理器,一個源文件被修改要重新生成可執行文件,簡單地再次輸入make即可。可重復執行上面三步。 最后,我們移除make生成的文件,輸入make clean:,$ make clean rm -f hello hello.o hello_fn.o,一個專業的makefile文件通常可以用于實現安裝(make install)和測試(make check)等額外的目標。,主要內容,2,3,Linux編輯器vi的使用,gcc編譯器,4,gdb調試器,6,autotools,5,Make工程管理器,1,Linux下C編程環境,六、autotools工具,autotools工具介紹 autotools使用流程 Makefile自動生成,1、autotools介紹,六、autotools工具,由于make規則的復雜性和不確定性,自己編寫Makefile是一件費時費力的事情。Makefile本身具有一定的相似性,因此利用GNU autoconf及automake這兩套工具可以協助我們自動產生Makefile文件,并且讓開發出來的軟件可以像大多數源代碼包那樣,只需運行命令“./configure”、“make”、“make install”就可以把程序安裝到系統中,對于各種源代碼包的分發和兼容性具有很好的效果。,1、autotools介紹,六、autotools工具,autotools是系列工具,讀者首先要確認系統是否裝了以下工具(可以用which命令進行查看)。 aclocal autoscan autoconf autoheader automake,1、autotools介紹,六、autotools工具,autoconf是一個用于產生可以自動配置源代碼包,生成Shell腳本的工具,它可以適應各種類Linux系統的需要。autoconf產生的配置腳本在運行時獨立于autoconf,也就是說使用這些腳本的不需要安裝autoconf。 autoconf生成的配置腳本通常名稱是configure,得到這個文件,通常需要以下的依賴文件:,(1) configure.in文件:生成configure的必需文件,需要手動編寫。 (2) aclocal.m4和acsite.m4文件:在編寫了除autoconf提供的測試外的其他測試補充的時候,才會用到這兩個文件,也需要手動編寫。 (3) acconfig.h文件:如果使用了含有#define指令的頭文件,則需要自行編寫該文件,一般都需要使用,這個時候會生成另外一個config.h.in文件,這個文件需要和軟件包一同發布。 總之,在autoconf運行完畢后,得到兩個需要和軟件包同時發布的文件: configure和config.h.in,當然config.h.in可以不存在。,1、autotools介紹,六、autotools工具,生成Makefile流程圖,六、autotools工具,步驟解釋如下: 1、由你的源文件通過autoscan命令生成configure.scan文件,然后修改configure.scan文件并重命名為configure.in 2、由aclocal命令生成aclocal.m4 3、由autoconf命令生成configure 4、編輯一個Makefile.am文件并由automake命令生成Makefile.in文件 5、運行configure命令生成Makefile,2、autotools使用流程,六、autotools工具,2、autotools使用流程,六、autotools工具,將通過一個簡單的hello.c例子來熟悉autotools生成makefile的過程。 (1)autoscan 它會在給定目錄及其子目錄樹中檢查源文件,若沒有給出目錄,就在當前目錄及其子目錄樹中進行檢查。它會搜索源文件以尋找一般的移植性問題并創建一個文件“configure.scan”,該文件就是接下來autoconf要用到的“configure.in”原型。如下所示:,2、autotools使用流程,六、autotools工具,(1)autoscan rootlocalhost automake# autoscan autom4te: configure.ac: no such file or directory autoscan: /usr/bin/autom4te failed with exit status: 1 rootlocalhost automake# ls autoscan.log conf
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度浙江省護師類之主管護師過關檢測試卷B卷附答案
- 2024年度浙江省二級造價工程師之土建建設工程計量與計價實務測試卷(含答案)
- 社會保險法律制度培訓
- 纖維濾池培訓課件
- 神經外科護理長工作總結
- 內科流動紅旗競選
- 服裝知識培訓
- 加裝電梯的面試題及答案
- 幼兒園小班社會《擦椅子》教案
- 領導面試題及答案
- 硐室爆破資料課件
- 防性侵防溺水防校園欺凌主題班會課件
- 《水熱溶劑熱合成》課件
- 建筑安全玻璃管理規定
- 保險學(第五版)習題庫答案
- 《重大火災隱患判定方法》GB 35181-2017
- 奇瑞汽車售后服務藍圖
- 《農藥經營許可培訓班》考試試卷
- 安徽省技能人才評價考評員考試題庫
- 網絡域名及域名解析PPT課件
- 浙江省2016年10月物理學業水平考試試題
評論
0/150
提交評論