使用靜態庫鏈接程序


轉載:http://www.708luo.com/?p=21

先關注兩個gcc編譯選項:

-c 編譯且匯編,但是不鏈接

-S 只編譯,不匯編也不鏈接

-c選項產出的就是經常看到的.o文件,也是一般用來創建靜態庫的文件。

 

用如下的命令可以將多個.o文件打包為一個靜態庫文件:ar crs libtest.a src/test1.o src/test2.o

 

現在完成了靜態庫創建工作,我們怎么在鏈接一個可執行程序的時候使用這個靜態庫呢?

有三種方式:

1. gcc -o test main.c libtest.a

2. gcc -o test main.c –ltest –L./

3. gcc -o test main.c -Xlinker “-(" libtest.a -Xlinker “-)"

其中一、二其實是同一種使用方式,第三種方式稍有不同,這個不同之處是什么呢?

第三種方式其實是多傳了兩個參數給鏈接器:”-(”和”-)”。傳這個兩個參數有什么作用嗎?

 

上面的使用中還看不出來傳給鏈接器的兩個參數的作用。

但是假設我們需要用到兩個靜態庫:libtest1.a和libtest2.a,其中libtest2.a中又使用了libtest1.a中的接口

那么我們可以這樣使用:(原來三種使用方式中的1、2其實是一種,后面只列出其中之一)

1. gcc –o test main.c libtest2.a libtest1.a

2. gcc -o test main.c -Xlinker “-(" libtest1.a libtest2.a -Xlinker “-)"

需要注意的是:第一種使用方式中靜態庫出現的順序,libtest2.a必須在libtest1.a之前,否則會有"undefined reference to ***”的鏈接錯誤,其中***就是libtest2.a中使用的libtest1.a的接口。

如果libtest1.a在前,為什么會有鏈接錯誤呢?

原因是gcc在鏈接的時候,對於多個靜態庫或者.o文件是從前往后依次處理的,如果當前的靜態庫或.o文件中沒有使用的符號,則往后繼續尋找,而不會再往前查找。

下面是man gcc看到的說明:

-l library
           Search the library named library when linking.  (The second alternative with the library as a separate argument is
           only for POSIX compliance and is not recommended.)

           It makes a difference where in the command you write this option; the linker searches and processes libraries and
           object files in the order they are specified.  Thus, foo.o -lz bar.o searches library z after file foo.o but before
           bar.o.  If bar.o refers to functions in z, those functions may not be loaded.

所以在使用一些依賴關系比較復雜的靜態庫時,我們可能會看到這樣的使用方式:gcc –o test main.c libtest1.a libtest2.a libtest1.a。在鏈接序列中,一個靜態庫可能出現多次,以解決一些循環依賴。

 

那么如果是gcc -o test main.c -Xlinker “-(" libtest1.a libtest2.a -Xlinker “-)"的使用方式,還需要考慮順序么?

答案是不需要。

因為Xlinker選項是將參數傳給鏈接器,而man ld我們可以看到這樣一段說明:

-( archives -)
       --start-group archives --end-group
           The archives should be a list of archive files.  They may be either explicit file names, or -l options.

           The specified archives are searched repeatedly until no new undefined references are created.  Normally, an archive is
           searched  only  once  in the order that it is specified on the command line.  If a symbol in that archive is needed to
           resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the  linker
           would not be able to resolve that reference.  By grouping the archives, they all be searched repeatedly until all pos-
           sible references are resolved.

           Using this option has a significant performance cost.  It is best to use it only when there are  unavoidable  circular
           references between two or more archives.

鏈接器在處理”-(”和”-)”之間的靜態庫時,是會重復查找這些靜態庫的,所以就解決了靜態庫查找順序問題。不過,man里面也說明了,這種方式比人工提供了鏈接順序的方式效率會低很多。


免責聲明!

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



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