• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-145  評論-173  文章-70  trackbacks-0

            GCC(gcc) 的不斷發(fā)展完善使許多商業(yè)編譯器都相形見絀, GCC GNU 創(chuàng)始人 Richard Stallman首創(chuàng),是 GNU 的標(biāo)志產(chǎn)品,由于 UNIX 平臺的高度可移植性, GCC 幾乎在各種常見的 UNIX 平臺上都有,即使是 Win32/DOS 也有 GCC 的移植。 比如說 SUN Solaris 操作系統(tǒng)配置的編譯器就是GNU GCC 。

            GNU 軟件包括 C 編譯器 GCC C++ 編譯器 G++ ,匯編器 AS ,鏈接器 LD ,二進(jìn)制轉(zhuǎn)換工具(OBJCOPY OBJDUMP) ,調(diào)試工具 (GDB , GDBSERVER , KGDB) 和基于不同硬件平臺的開發(fā)庫。

            GNU GCC 支持下用戶可以使用流行的 C/C++ 語言開發(fā)應(yīng)用程序,滿足生成高效率運(yùn)行代碼、易掌握的編程語言的用戶需求。

            這些工具都是按 GPL 版權(quán)聲明發(fā)布,任何人可以從網(wǎng)上獲取全部的源代碼,無需使用任何費(fèi)用。關(guān)于 GNU 和公共許可證協(xié)議的詳細(xì)資料, 讀者可以參看 GNU 網(wǎng)站的介紹,

            http://www.gnu.org/home.html。

            GNU 開發(fā)工具都是采用命令行的方式,用戶掌握起來相對比較困難,不如基于 Windows 系統(tǒng)的開發(fā)工具好用,但是 GNU 工具的復(fù)雜性是由于它更貼近編譯器和操作系統(tǒng)的底層,并提供了更大的靈活性。一旦學(xué)習(xí)和掌握了相關(guān)工具后,就了解了系統(tǒng)設(shè)計(jì)的基礎(chǔ)知識。

            運(yùn)行于 Linux 操作系統(tǒng)下的自由軟件 GNU gcc 編譯器,不僅可以編譯 Linux 操作系統(tǒng)下運(yùn)行的應(yīng)用程序,還可以編譯 Linux 內(nèi)核本身,甚至可以作交叉編譯,編譯運(yùn)行于其它 CPU 上的程序。所以,在進(jìn)行嵌入式系統(tǒng)應(yīng)用程序開發(fā)時,這些工具得到了日益廣泛的應(yīng)用。

            GCC GNU 組織的免費(fèi) C 編譯器, Linux 的很多發(fā)布缺省安裝的就是這種。很多流行的自由軟件源代碼基本都能在 GCC 編譯器下編譯運(yùn)行。 所以掌握 GCC 編譯器的使用無論是對于編譯系統(tǒng)內(nèi)核還是自己的應(yīng)用程序都是大有好處的。

            下面通過一個具體的例子,學(xué)習(xí)如何使用 GCC 編譯器。

            Linux 操作系統(tǒng)中,對一個用標(biāo)準(zhǔn) C 語言寫的源程序進(jìn)行編譯,要使用 GNU gcc 編譯器。

            例如下面一個非常簡單的 Hello 源程序 (hello.c)

            /*******************************************************

            * Institute of Automation, Chinese Academy of Sciences

            * File Name hello.c

            * Description introduce how to compile a source file with gcc

            * Author Xueyuan Nie

            * Date

            *******************************************************/

            void main()

            {

            printf("Hello the world\n") ;

            }

            要編譯這個程序,我們只要在 Linux bash 提示符下輸入命令:

            $ gcc -o hello hello.c

            gcc 編譯器就會生成一個 hello 的可執(zhí)行文件。在 hello.c 的當(dāng)前目錄下執(zhí)行 ./hello 就可以看到程序的輸出結(jié)果,在屏幕上打印出 “ Hello the world ” 的字符串來。

            命令行中 gcc 表示是用 gcc 來編譯源程序;

            -o outputfilename 選項(xiàng)表示要求編譯器生成文件名為 outputfilename 的可執(zhí)行文件,如果不指定 -o 選項(xiàng),則缺省文件名是 a.out 。在這里生成指定文件名為 hello 的可執(zhí)行文件,而 hello.c 是我們的源程序文件。

            gcc 是一個多目標(biāo)的工具。 gcc 最基本的用法是:

            gcc [options] file...

            其中的 option 是以 - 開始的各種選項(xiàng), file 是相關(guān)的文件名。在使用 gcc 的時候,必須要給出必要的選項(xiàng)和文件名。 gcc 的整個編譯過程,實(shí)質(zhì)上是分四步進(jìn)行的,每一步完成一個特定的工作,

            這四步分別是:預(yù)處理,編譯,匯編和鏈接。它具體完成哪一步,是由 gcc 后面的開關(guān)選項(xiàng)和文件類型決定的。

            清楚的區(qū)別編譯和連接是很重要的。編譯器使用源文件編譯產(chǎn)生某種形式的目標(biāo)文件 (objectfiles) 。在這個過程中,外部的符號引用并沒有被解釋或替換,然后我們使用鏈接器來鏈接這些目標(biāo)文件和一些標(biāo)準(zhǔn)的頭文件,最后生成一個可執(zhí)行文件。在這個過程中,一個目標(biāo)文件中對別的文件中的符號的引用被解釋,并報(bào)告不能被解釋的引用,一般是以錯誤信息的形式報(bào)告出來。

            gcc 編譯器有許多選項(xiàng),但對于普通用戶來說只要知道其中常用的幾個就夠了。在這里為讀者列出幾個最常用的選項(xiàng):

            -o 選項(xiàng)表示要求編譯器生成指定文件名的可執(zhí)行文件;

            -c 選項(xiàng)表示只要求編譯器進(jìn)行編譯,而不要進(jìn)行鏈接,生成以源文件的文件名命名但把其后綴由 .c .cc 變成 .o 的目標(biāo)文件;

            -g 選項(xiàng)要求編譯器在編譯的時候提供以后對程序進(jìn)行調(diào)試的信息;

            -E 選項(xiàng)表示編譯器對源文件只進(jìn)行預(yù)處理就停止,而不做編譯,匯編和鏈接;

            -S 選項(xiàng)表示編譯器只進(jìn)行編譯,而不做匯編和鏈接;

            -O 選項(xiàng)是編譯器對程序提供的編譯優(yōu)化選項(xiàng),在編譯的時候使用該選項(xiàng),可以使生成的執(zhí)行文件的執(zhí)行效率提高;

            -Wall 選項(xiàng)指定產(chǎn)生全部的警告信息。

            如果你的源代碼中包含有某些函數(shù),則在編譯的時候要鏈接確定的庫,比如代碼中包含了某些數(shù)學(xué)函數(shù),在 Linux 下,為了使用數(shù)學(xué)函數(shù),必須和數(shù)學(xué)庫鏈接,為此要加入 -lm 選項(xiàng)。也許有讀者會問,前面那個例子使用 printf 函數(shù)的時候?yàn)楹螞]有鏈接庫呢?在 gcc 中對于一些常用函數(shù)的實(shí)現(xiàn), gcc 編譯器會自動去鏈接一些常用庫,這樣用戶就沒有必要自己去指定了。有時候在編譯程序的時候還要指定庫的路徑,這個時候要用到編譯器的 -L 選項(xiàng)指定路徑。比如說我們有一個庫在/home/hoyt/mylib 下,這樣我們編譯的時候還要加上 -L/home/hoyt/mylib 。對于一些標(biāo)準(zhǔn)庫來說,沒有必要指出路徑。只要它們在起缺省庫的路徑下就可以了, gcc 在鏈接的時候會自動找到那些庫的。

            GNU 編譯器生成的目標(biāo)文件缺省格式為 elf(executive linked file) 格式,這是 Linux 系統(tǒng)所采用的可執(zhí)行鏈接文件的通用文件格式。 elf 格式由若干段 (section) 組成,如果沒有特別指明,由標(biāo)準(zhǔn) c 源代碼生成的目標(biāo)文件中包含以下段: .text( 正文段 ) 包含程序的指令代碼, .data( 數(shù)據(jù)段 ) 包含固定的數(shù)據(jù),如常量,字符串等, .bss( 未初始化數(shù)據(jù)段 ) 包含未初始化的變量和數(shù)組等。

            讀者若想知道更多的選項(xiàng)及其用法,可以查看 gcc 的幫助文檔,那里有許多對其它選項(xiàng)的詳細(xì)說明。

            當(dāng)改變了源文件 hello.c 后,需要重新編譯它:

            $ gcc -c hello.c

            然后重新鏈接生成:

            $ gcc o hello.o

            對于本例,因?yàn)橹缓幸粋€源文件,所以當(dāng)改動了源碼后,進(jìn)行重新的編譯鏈接的過程顯得并不是太繁瑣,但是,如果在一個工程中包含了若干的源碼文件,而這些源碼文件中的某個或某幾個又被其他源碼文件包含,那么,如果一個文件被改動,則包含它的那些源文件都要進(jìn)行重新編譯鏈接,工作量是可想而知的。幸運(yùn)的是, GNU 提供了使這個步驟變得簡單的工具,就是下面要介紹給大家的 GNU Make 工具。

            GNU Make

            make 是負(fù)責(zé)從項(xiàng)目的源代碼中生成最終可執(zhí)行文件和其他非源代碼文件的工具。 make 命令本身可帶有四種參數(shù):標(biāo)志、宏定義、描述文件名和目標(biāo)文件名。

            其標(biāo)準(zhǔn)形式為:

            make [flags] [macro definitions] [targets]

            Unix 系統(tǒng)下標(biāo)志位 flags 選項(xiàng)及其含義為:

            -f file 指定 file 文件為描述文件,如果 file 參數(shù)為 '-' 符,那么描述文件指向標(biāo)準(zhǔn)輸入。如果沒有 '-f' 參數(shù),則系統(tǒng)將默認(rèn)當(dāng)前目錄下名為 makefile 或者名為 Makefile 的文件為描述文件。在Linux 中, GNU make 工具在當(dāng)前工作目錄中按照 GNUmakefile 、 makefile 、 Makefile 的順序搜索makefile 文件。

            -i 忽略命令執(zhí)行返回的出錯信息。

            -s 沉默模式,在執(zhí)行之前不輸出相應(yīng)的命令行信息。

            -r 禁止使用隱含規(guī)則。

            -n 非執(zhí)行模式,輸出所有執(zhí)行命令,但并不執(zhí)行。

            -t 更新目標(biāo)文件。

            -q make 操作將根據(jù)目標(biāo)文件是否已經(jīng)更新返回 "0" 或非 "0" 的狀態(tài)信息。

            -p 輸出所有宏定義和目標(biāo)文件描述。

            -d Debug 模式,輸出有關(guān)文件和檢測時間的詳細(xì)信息。

            Linux make 標(biāo)志位的常用選項(xiàng)與 Unix 系統(tǒng)中稍有不同,下面只列出了不同部分:

            -c dir 在讀取 makefile 之前改變到指定的目錄 dir

            -I dir 當(dāng)包含其他 makefile 文件時,利用該選項(xiàng)指定搜索目錄。

            -h help 文擋,顯示所有的 make 選項(xiàng)。

            -w 在處理 makefile 之前和之后,都顯示工作目錄。

            通過命令行參數(shù)中的 target ,可指定 make 要編譯的目標(biāo),并且允許同時定義編譯多個目標(biāo),操作時按照從左向右的順序依次編譯 target 選項(xiàng)中指定的目標(biāo)文件。如果命令行中沒有指定目標(biāo),則系統(tǒng)默認(rèn) target 指向描述文件中第一個目標(biāo)文件。

            make 如何實(shí)現(xiàn)對源代碼的操作是通過一個被稱之為 makefile 的文件來完成的,在下面的小節(jié)里,主要向讀者介紹一下 makefile 的相關(guān)知識。

            makefile 基本結(jié)構(gòu)

            GNU Make 的主要工作是讀一個文本文件 makefile 。 makefile 是用 bash 語言寫的, bash 語言是很像 BASIC 語言的一種命令解釋語言。這個文件里主要描述了有關(guān)哪些目標(biāo)文件是從哪些依賴文件中產(chǎn)生的,是用何種命令來進(jìn)行這個產(chǎn)生過程的。有了這些信息, make 會檢查磁盤的文件,如果目標(biāo)文件的日期 ( 即該文件生成或最后修改的日期 ) 至少比它的一個依賴文件日期早的話, make 就會執(zhí)行相應(yīng)的命令,以更新目標(biāo)文件。

            makefile 一般被稱為 “makefile” 或 “Makefile” 。還可以在 make 的命令行中指定別的文件名。如果沒有特別指定的話, make 就會尋找 “makefile” 或 “Makefile” ,所以為了簡單起見,建議讀者使用這兩名字。如果要使用其他文件作為 makefile ,則可利用類似下面的 make 命令選項(xiàng)指定 makefile 文件:

            $ make -f makefilename

            一個 makefile 主要含有一系列的規(guī)則,如下:

            目標(biāo)文件名: 依賴文件名

            (tab ) 命令

            第一行稱之為規(guī)則,第二行是執(zhí)行規(guī)則的命令,必須要以 tab 鍵開始。

            下面舉一個簡單的 makefile 的例子。

            executable : main.o io.o

            gcc main.o io.o -o executable

            main.o : main.c

            gcc -Wall -O -g -c main.c -o main.o

            io.o : io.c

            gcc -Wall -O -g -c io.c -o io.o

            這是一個最簡單的 makefile , make 從第一條規(guī)則開始, executable makefile 最終要生成的目標(biāo)文件。給出的規(guī)則說明 executable 依賴于兩個目標(biāo)文件 main.o io.o ,只要 executable 比它依賴的文件中的任何一個舊的話,下一行的命令就會被執(zhí)行。但是,在檢查文件 main.o io.o 的日期之前,它會往下查找那些把 main.o io.o 做為目標(biāo)文件的規(guī)則。 make 先找到了關(guān)于 main.o 的規(guī)則,該目標(biāo)文件的依賴文件是 main.c 。 makefile 后面的文件中再也找不到生成這個依賴文件的規(guī)則了。此時, make 開始檢查磁盤上這個依賴文件的日期,如果這個文件的日期比 main.o 日期新的話,那么這個規(guī)則下面的命令 gcc -c main.c o main.o 就會執(zhí)行,以更新文件 main.o 。同樣 make 對文件 io.o 做類似的檢查,它的依賴文件是 io.c ,對 io.o 的處理和 main.o 類似。現(xiàn)在, 再回到第一個規(guī)則處,如果剛才兩個規(guī)則中的任何一個被執(zhí)行,最終的目標(biāo)文件executable 都需要重建 ( 因?yàn)?span> executable 所依賴的其中一個 .o 文件就會比它新 ) ,因此鏈接命令就會被執(zhí)行。

            有了 makefile ,對任何一個源文件進(jìn)行修改后,所有依賴于該文件的目標(biāo)文件都會被重新編譯 ( 因?yàn)?span> .o 文件依賴于 .c 文件 ) ,進(jìn)而最終可執(zhí)行文件會被重新鏈接 ( 因?yàn)樗蕾嚨?span> .o 文件被改變了 ) ,再也不用手工去一個個修改了。

            posted on 2009-12-05 00:45 deercoder 閱讀(1506) 評論(0)  編輯 收藏 引用 所屬分類: C/C++
            久久久久久狠狠丁香| 久久久久久人妻无码| 国产精品va久久久久久久| 精品久久久久中文字幕日本| 国产午夜久久影院| 久久天天躁狠狠躁夜夜不卡| 久久99精品九九九久久婷婷| 国产精品久久久久久久久| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区| 青青青青久久精品国产| 亚洲七七久久精品中文国产 | 国内精品伊人久久久久影院对白| 久久精品国产亚洲Aⅴ香蕉 | 久久91精品国产91久| 久久不见久久见免费视频7| 国产午夜精品久久久久九九电影| 波多野结衣久久| 青青草原综合久久| 久久99国产乱子伦精品免费| 久久高清一级毛片| 国产一区二区三区久久| 久久久午夜精品福利内容| 久久精品三级视频| 国产精品久久久久久福利漫画| 久久久久av无码免费网| 欧美午夜精品久久久久久浪潮| 99久久国语露脸精品国产| 亚洲狠狠婷婷综合久久久久| 要久久爱在线免费观看| 国产成人香蕉久久久久| 99久久综合国产精品二区| 久久久一本精品99久久精品88| 精品久久亚洲中文无码| 国产精品亚洲综合久久| 人妻中文久久久久| 性欧美大战久久久久久久| 久久精品成人免费国产片小草| 久久精品国产色蜜蜜麻豆| 久久无码人妻精品一区二区三区| 色综合久久综精品| 欧美粉嫩小泬久久久久久久 |