linux使用libtool

來源:互聯網
上載者:User

1 libtool的工作原理
libtool 是一個通用庫支援指令碼,將使用動態庫的複雜性隱藏在統一、可移植的介面中;使用libtool的標準方法,可以在不同平台上建立並調用動態庫。可以認為libtool是gcc的一個抽象,其封裝了gcc(或者其他的編譯器),使用者無需知道細節,只要告訴libtool需要編譯哪些庫即可,libtool將處理庫的依賴等細節。libtool只與尾碼名為lo、la為的libtool檔案打交道。
libtool主要的一個作用是在編譯大型軟體的過程中解決了庫的依賴問題;將繁重的庫依賴關係的維護工作承擔下來,從而釋放了程式員的人力資源。libtool提供統一的介面,隱藏了不同平台間庫的名稱的差異等細節,產生一個抽象的尾碼名為la高層庫libxx.la(其實是個文字檔),並將該庫對其它庫的依賴關係,都寫在該la的檔案中。該檔案中的dependency_libs記錄該庫依賴的所有庫(其中有些是以.la檔案的形式加入的);libdir則指出了庫的安裝位置;library_names記錄了共用庫的名字;old_library記錄了靜態庫的名字。
當編譯過程到link階段的時候,如果有下面的命令:
$libtool --mode=link gcc -o myprog -rpath /usr/lib –L/usr/lib –la
libtool會到/usr/lib路徑下去尋找liba.la,然後從中讀取實際的共用庫的名字(library_names中記錄了該名字,比如liba.so)和路徑(lib_dir中記錄了,比如libdir=’/usr/lib’),返回諸如/usr/lib/liba.so的參數給激發出的gcc命令列。
如果liba.so依賴於庫/usr/lib/libb.so,則在liba.la中將會有dependency_libs=’-L/usr/lib -lb’或者dependency_libs=’/usr/lib/libb.la’的行,如果是前者,其將直接把“-L/usr/lib –lb”當作參數傳給gcc命令列;如果是後者,libtool將從/usr/lib/libb.la中讀取實際的libb.so的庫名稱和路徑,然後組合成參數“/usr/lib/libb.so”傳遞給gcc命令列。
當要產生的檔案是諸如libmylib.la的時候,比如:
$libtool --mode=link gcc -o libmylib.la -rpath /usr/lib –L/usr/lib –la
其依賴的庫的搜尋基本類似,只是在這個時候會根據相應的規則產生相應的共用庫和靜態庫。
注意:libtool在連結的時候只會涉及到尾碼名為la的libtool檔案;實際的庫檔案名稱和庫安裝路徑以及依賴關係是從該檔案中讀取的。
2 為何使用 -Wl,--rpath-link -Wl,DIR?
使用libtool解決編譯問題看上去沒什麼問題:庫的名稱、路徑、依賴都得到了很好的解決。但下結論不要那麼著急,一個顯而易見的問題就是:並不是所有的庫都是用libtool編譯的。
比如上面那個例子,
$libtool --mode=link gcc -o myprog -rpath /usr/lib –L/usr/lib –la
如果liba.so不是使用libtool工具產生的,則libtool此時根本找不到liba.la檔案(不存在該檔案)。這種情況下,libtool只會把“–L/usr/lib –la”當作參數傳遞給gcc命令列。
考慮以下情況:要從myprog.o檔案編譯產生myprog,其依賴於庫liba.so(使用libtool產生),liba.so又依賴於libb.so(libb.so的產生不使用libtool),而且由於某種原因,a對b的依賴並沒有寫入到liba.la中,那麼如果用以下命令編譯:
$libtool --mode=link gcc -o myprog -rpath /usr/lib –L/usr/lib –la
激發出的gcc命令列類似於下面:
  gcc –o myprog /usr/lib/liba.so 
由於liba.so依賴於libb.so(這種依賴可以用readelf讀liba.so的ELF檔案看到),而上面的命令列中,並沒有出現libb.so,於是,可能會出現問題。
  說“可能”,是因為如果在本地編譯的情況下,gcc在命令列中找不到一個庫(比如上面的liba.so)依賴的其它庫(比如libb.so),連結器會按照某種策略到某些路徑下面去尋找需要的共用庫:
1. 所有由'-rpath-link'選項指定的搜尋路徑.
2. 所有由'-rpath'指定的搜尋路徑. '-rpath'跟'-rpath_link'的不同之處在於,由'-rpath'指定的路徑被包含在可執行檔中,並在運行時使用, 而'-rpath-link'選項僅僅在串連時起作用. 
3. 在一個ELF系統中, 如果'-rpath'和'rpath-link'選項沒有被使用, 會搜尋環境變數'LD_RUN_PATH'的內容.它也只對本地連接器起作用.
4. 在SunOS上, '-rpath'選項不使用, 只搜尋所有由'-L'指定的目錄.
5. 對於一個本地連接器,環境變數'LD_LIBRARY_PATH'的內容被搜尋.
6. 對於一個本地ELF連接器,共用庫中的`DT_RUNPATH'和`DT_RPATH'操作符會被需要它的共用庫搜尋. 如果'DT_RUNPATH'存在了, 那'DT_RPATH'就會被忽略.
7. 預設目錄, 常規的,如'/lib'和'/usr/lib'.
8. 對於ELF系統上的本地連接器, 如果檔案'/etc/ld.so.conf'存在, 這個檔案中有的目錄會被搜尋.
從以上可以看出,在使用本地工具鏈進行本地編譯情況下,只要庫存在於某個位置,gcc總能通過如上策略找到需要的共用庫。但在交叉編譯下,上述八種策略,可以使用的僅僅有兩個:-rpath-link,-rpath。這兩個選項在上述八種策略當中優先順序最高,當指定這兩個選項時,如果連結需要的共用庫找不到,連結器會優先到這兩個選項指定的路徑下去搜尋需要的共用庫。通過上面的描述可以看到:-rpath指定的路徑將被寫到可執行檔中;-rpath-link則不會;我們當然不希望交叉編譯情況下使用的路徑資訊被寫進最終的可執行檔,所以我們選擇使用選項-rpath-link。
  gcc的選項“-Wl,--rpath-link –Wl,DIR”會把-rpath-link選項及路徑資訊傳遞給連結器。回到上面那個例子,如果命令列中沒有出現libb.so,但gcc指定了“-Wl,--rpath-則鏈link –Wl,DIR”,接器找不到libb.so的時候,會首先到後面-rpath-link指定的路徑去尋找其依賴的庫。此處我們使用的編譯命令的樣本是使用unicore平台的工具鏈。
$ unicore32-linux-gcc –o myprog /usr/lib/liba.so /
-Wl,--rpath-link -Wl,/home/UNITY_float/install/usr/lib
這樣,編譯器會首先到“/home/UNITY_float/install/usr/lib”下面去搜尋libb.so
  libtool如何把選項“-Wl,--rpath-link –Wl,DIR”傳遞給gcc?libtool中有一個變數“hardcode_libdir_flag_spec”,該變數本來是傳遞“-rpath”選項的,但我們可以修改它,添加我們需要的路徑,傳遞給unicore32-linux-gcc。
  “hardcode_libdir_flag_spec”原來的定義如下:
hardcode_libdir_flag_spec="/${wl}--rpath /${wl}/$libdir"
我們修改後的定義如下:
hardcode_libdir_flag_spec="/${wl}—rpath-link /${wl}/$libdir /
-Wl,--rpath-link -Wl,/home/UNITY_float/install/usr/lib /
  -Wl,--rpath-link -Wl,/home/UNITY_float/install/usr/X11R6/lib "
這樣,當libtool在“--mode=link”的模式下,就會把選項“-Wl,--rpath-link –Wl,DIR”傳遞給gcc編譯器了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.