新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Linux下C編程基礎之:gcc編譯器

        Linux下C編程基礎之:gcc編譯器

        作者: 時間:2013-09-13 來源:網絡 收藏

        本文引用地址:http://www.104case.com/article/257151.htm

        (4)鏈接階段。

        在成功編譯之后,就進入了鏈接階段。這里涉及一個重要的概念:

        讀者可以重新查看這個小程序,在這個程序中并沒有定義“printf”的函數實現,且在預編譯中包含進的“stdio.h”中也只有該函數的聲明,而沒有定義函數的實現,那么,是在哪里實現“printf”函數的呢?最后的答案是:系統把這些函數的實現都放到名為libc.so.6的庫文件中去了,在沒有特別指定時,gcc會到系統默認的搜索路徑“/usr/lib”下進行查找,也就是鏈接到libc.so.6中去,這樣就能調用函數“printf”了,而這也正是鏈接的作用。

        有靜態庫和動態庫兩種。靜態庫是指編譯鏈接時,將庫文件的代碼全部加入可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其后綴名通常為“.a”。動態庫與之相反,在編譯鏈接時并沒有將庫文件的代碼加入可執行文件中,而是在程序執行時加載庫,這樣可以節省系統的開銷。一般動態庫的后綴名為“.so”,如前面所述的libc.so.6就是動態庫。gcc在編譯時默認使用動態庫。

        完成了鏈接之后,gcc就可以生成可執行文件,如下所示。

        [root@localhostgcc]#gcchello.o–ohello

        運行該可執行文件,出現的正確結果如下。

        [root@localhostgcc]#./hello

        Hello!Thisisourembeddedworld!

        3.3.2gcc編譯選項分析

        gcc有超過100個可用選項,主要包括總體選項、告警和出錯選項、優化選項和體系結構相關選項。以下對每一類中最常用的選項進行講解。

        (1)常用選項。

        gcc的常用選項如表3.7所示,很多在前面的示例中已經有所涉及。

        表3.7 gcc常用選項列表

        選項

        含義

        -c

        只編譯不鏈接,生成目標文件“.o”

        -S

        只編譯不匯編,生成匯編代碼

        -E

        只進行預編譯,不做其他處理

        -g

        在可執行程序中包含標準調試信息

        -ofile

        將file文件指定為輸出文件

        -v

        打印出編譯器內部編譯各過程的命令行信息和編譯器的版本

        -Idir

        在頭文件的搜索路徑列表中添加dir目錄

        前一小節已經講解了“-c”、“-E”、“-o”、“-S”選項的使用方法,在此主要講解另外2個非常常用的庫依賴選項“-Idir”。

        n “-Idir”

        正如上表中所述,“-Idir”選項可以在頭文件的搜索路徑列表中添加dir目錄。由于中頭文件都默認放到了“/usr/include/”目錄下,因此,當用戶希望添加放置在其他位置的頭文件時,就可以通過“-Idir”選項來指定,這樣,gcc就會到相應的位置查找對應的目錄。

        比如在“/root/workplace/gcc”下有兩個文件:

        /*hello1.c*/

        #includemy.h>

        intmain()

        {

        printf(Hello!!n);

        return0;

        }

        /*my.h*/

        #includestdio.h>

        這樣,就可在gcc命令行中加入“-I”選項:

        [root@localhostgcc]gcchello1.c–I/root/workplace/gcc/-ohello1

        這樣,gcc就能夠執行出正確結果。

        小知識

        在include語句中,“>”表示在標準路徑中搜索頭文件,““””表示在本目錄中搜索。故在上例中,可把hello1.c的“#includemy.h>”改為“#include“my.h””,就不需要加上“-I”選項了。

        (2)庫選項。

        gcc庫選項如表3.8所示。

        表3.8 gcc庫選項列表

        選項

        含義

        -static

        進行靜態編譯,即鏈接靜態庫,禁止使用動態庫

        -shared

        1.可以生成動態庫文件

        2.進行動態編譯,盡可能地鏈接動態庫,只有當沒有動態庫時才會鏈接同名的靜態庫(默認選項,即可省略)

        -Ldir

        在庫文件的搜索路徑列表中添加dir目錄

        -lname

        鏈接稱為libname.a(靜態庫)或者libname.so(動態庫)的庫文件。若兩個庫都存在,則根據編譯方式(-static還是-shared)而進行鏈接

        -fPIC(或-fpic)

        生成使用相對地址的位置無關的目標代碼(PositionIndependentCode)。然后通常使用gcc的-static選項從該PIC目標文件生成動態庫文件

        我們通常需要將一些常用的公共函數編譯并集成到二進制文件(的ELF格式文件),以便其他程序可重復地使用該文件中的函數,此時將這種文件叫做函數庫,使用函數庫不僅能夠節省很多內存和存儲器的空間資源,而且更重要的是大大降低開發難度和開銷,提高開發效率并增強程序的結構性。實際上,在中的每個程序都會鏈接到一個或者多個庫。比如使用C函數的程序會鏈接到C運行時庫,Qt應用程序會鏈接到Qt支持的相關圖形庫等。

        函數庫有靜態庫和動態庫兩種,靜態庫是一系列的目標文件(.o文件)的歸檔文件(文件名格式為libname.a),如果在編譯某個程序時鏈接靜態庫,則鏈接器將會搜索靜態庫,從中提取出它所需要的目標文件并直接復制到該程序的可執行二進制文件(ELF格式文件)之中;動態庫(文件名格式為libname.so[.主版本號.次版本號.發行號])在程序編譯時并不會被鏈接到目標代碼中,而是在程序運行時才被載入。

        下面舉一個簡單的例子,講解如何怎么創建和使用這兩種函數庫。

        首先創建unsgn_pow.c文件,它包含unsgn_pow()函數的定義,具體代碼如下所示。

        /*unsgn_pow.c:庫程序*/

        unsignedlonglongunsgn_pow(unsignedintx,unsignedinty)

        {

        unsignedlonglongres=1;

        if(y==0)

        {

        res=1;

        }

        elseif(y==1)

        {

        res=x;

        }

        else

        {

        res=x*unsgn_pow(x,y-1);

        }

        returnres;

        }

        然后創建pow_test.c文件,它會調用unsgn_pow()函數。

        /*pow_test.c*/

        #includestdio.h>

        #includestdlib.h>

        intmain(intargc,char*argv[])

        {

        unsignedintx,y;

        unsignedlonglongres;

        if((argc3)||(sscanf(argv[1],%u,x)!=1)

        ||(sscanf(argv[2],%u,y))!=1)

        {

        printf(Usage:powbaseexponentn);

        exit(1);

        }

        res=unsgn_pow(x,y);

        printf(%u^%u=%un,x,y,res);

        exit(0);

        }

        linux操作系統文章專題:linux操作系統詳解(linux不再難懂)

        linux相關文章:linux教程


        c++相關文章:c++教程




        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 宁陕县| 北海市| 兰溪市| 昌乐县| 屯留县| 正定县| 延寿县| 长岛县| 集安市| 外汇| 黑水县| 金堂县| 洮南市| 炉霍县| 金湖县| 岳普湖县| 沙田区| 大余县| 米泉市| 郸城县| 玛曲县| 务川| 北宁市| 蓝山县| 赤水市| 平陆县| 潜山县| 龙游县| 原阳县| 双鸭山市| 波密县| 定安县| 渝中区| 南靖县| 公安县| 浦江县| 磴口县| 沅江市| 南京市| 海原县| 长宁县|