歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux .o a .so .la .lo的區別及libtool相關介紹

Linux .o a .so .la .lo的區別及libtool相關介紹

日期:2017/2/28 16:21:25   编辑:Linux教程

o: 編譯的目標文件
a: 靜態庫,其實就是把若干o文件打了個包
so: 動態鏈接庫(共享庫)

lo: 使用libtool編譯出的目標文件,其實就是在o文件中添加了一些信息
la: 使用libtool編譯出的庫文件,其實是個文本文件,記錄同名動態庫和靜態庫的相關信息

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命令行。

Copyright © Linux教程網 All Rights Reserved