gcc -l:手動添加鏈接庫


鏈接器把多個二進制的目標文件(object file)鏈接成一個單獨的可執行文件。在鏈接過程中,它必須把符號(變量名、函數名等一些列標識符)用對應的數據的內存地址(變量地址、函數地址等)替代,以完成程序中多個模塊的外部引用。

而且,鏈接器也必須將程序中所用到的所有C標准庫函數加入其中。對於鏈接器而言,鏈接庫不過是一個具有許多目標文件的集合,它們在一個文件中以方便處理。

當把程序鏈接到一個鏈接庫時,只會鏈接程序所用到的函數的目標文件。在已編譯的目標文件之外,如果創建自己的鏈接庫,可以使用 ar 命令。

標准庫的大部分函數通常放在文件 libc.a 中(文件名后綴.a代表“achieve”,譯為“獲取”),或者放在用於共享的動態鏈接文件 libc.so 中(文件名后綴.so代表“share object”,譯為“共享對象”)。這些鏈接庫一般位於 /lib/ 或 /usr/lib/,或者位於 GCC 默認搜索的其他目錄。

當使用 GCC 編譯和鏈接程序時,GCC 默認會鏈接 libc.a 或者 libc.so,但是對於其他的庫(例如非標准庫、第三方庫等),就需要手動添加。

令人驚訝的是,標准頭文件 <math.h> 對應的數學庫默認也不會被鏈接,如果沒有手動將它添加進來,就會發生函數未定義錯誤。

GCC 的-l選項可以讓我們手動添加鏈接庫。下面我們編寫一個數學程序 main.c,並使用到了 cos() 函數,它位於 <math.h> 頭文件。

    #include <stdio.h>      /* printf */
    #include <math.h>       /* cos */
    #define PI 3.14159265
    int main ()
    {
        double param, result;
        param = 60.0;
        result = cos ( param * PI / 180.0 );
        printf ("The cosine of %f degrees is %f.\n", param, result );
        return 0;
    }

 為了編譯這個 main.c,必須使用-l選項,以鏈接數學庫:

$ gcc main.c -o main.out -lm

 數學庫的文件名是 libm.a。前綴lib和后綴.a是標准的,m是基本名稱,GCC 會在-l選項后緊跟着的基本名稱的基礎上自動添加這些前綴、后綴,本例中,基本名稱為 m。

在支持動態鏈接的系統上,GCC 自動使用在 Darwin 上的共享鏈接庫 libm.so 或 libm.dylib。

鏈接其它目錄中的庫

通常,GCC 會自動在標准庫目錄中搜索文件,例如 /usr/lib,如果想鏈接其它目錄中的庫,就得特別指明。有三種方式可以鏈接在 GCC 搜索路徑以外的鏈接庫,下面我們分別講解。

1) 把鏈接庫作為一般的目標文件,為 GCC 指定該鏈接庫的完整路徑與文件名。

例如,如果鏈接庫名為 libm.a,並且位於 /usr/lib 目錄,那么下面的命令會讓 GCC 編譯 main.c,然后將 libm.a 鏈接到 main.o:

$ gcc main.c -o main.out /usr/lib/libm.a

 2) 使用-L選項,為 GCC 增加另一個搜索鏈接庫的目錄:

$ gcc main.c -o main.out -L/usr/lib -lm

 可以使用多個-L選項,或者在一個-L選項內使用冒號分割的路徑列表。

3) 把包括所需鏈接庫的目錄加到環境變量 LIBRARYPATH 中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM