2010-11-19 47 views
2

我有一個軟件庫,我用來創建.a文件,使人們可以安裝它們,並連接它們:g++ foo.o -L/path/to -llibrary將我的代碼打包爲庫時應該創建.a還是.so?

但現在我經常遇到只有.so文件是可用的第三方庫(而不是的.a),並且您只需鏈接它們而不使用-l開關,例如g++ foo.o /path/to/liblibrary.so

這些解決方案有什麼區別?我應該更喜歡爲我的圖書館的用戶創建.so文件嗎?在

http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

+4

請參閱[靜態和共享庫之間的區別C ](http://stackoverflow.com/questions/2649334/difference-between-static-and-shared-library-in-c)。 – 2010-11-19 19:06:39

+2

有時創建兩種類型的庫都是適當的。 – aschepler 2010-11-19 19:07:28

+0

這取決於你想要的。 – 2010-11-19 19:08:36

回答

9

靜態的,共享的動態和可加載庫的

1

很好的概述通常,libfoo.a是一個靜態庫,和libfoo.so是一個共享庫。對於靜態或共享,您可以使用相同的-L/-l鏈接器選項。或者你可以用靜態或共享來命名lib的完整路徑。通常庫都是靜態的和共享的,爲應用程序開發人員提供他們想要的選擇。

靜態庫需要的所有代碼都是最終可執行文件的一部分。這顯然使它更大,但它也意味着它是獨立的。一旦編譯完成,你就可以在沒有lib的情況下運行你的應用程序。

來自共享庫的代碼不是可執行文件的一部分。只有一些鉤子使得可執行文件知道它需要的lib的名字。爲了運行您的應用程序,共享庫必須存在於lib搜索路徑中(例如$LD_LIBRARY_PATH)。

如果您有兩個共享相同代碼的應用程序,它們可以分別鏈接到共享庫以保持二進制大小。如果你想升級應用程序的某些部分而不重建整個事物,那麼共享庫也是很好的選擇。

1

有些功能並沒有真正從我迄今爲止看到的評論中調出。

靜態鏈接(.A /的.lib),這些編譯單元之間
共享內存一般是可以的,因爲他們應該(?會)都可以使用相同的運行時間。

靜態鏈接意味着你避免'地獄',但成本是重新編譯,以利用任何改變。靜態鏈接到共享庫(.so)可能導致奇怪的結果,如果你有多於1個這樣的共享庫被最終可執行文件使用 - 全局變量可能存在多次,使用哪一個,當它們被初始化時會導致完全不同地獄。

該庫將成爲已發貨產品的一部分,但是會被混淆且無法直接使用。

共享/動態庫(.so/.DLL)這些編譯單元之間
共享存儲器可以是有害的,因爲它們可以選擇使用不同的運行時。這可能意味着你提供了不同的基於調試/發行版或單/多線程的共享/動態庫...

共享庫(.so)不太容易'dll hell'動態庫(.dll)因爲它們包含了非常具體的版本控制選項。

編譯反對。所以將捕獲內部的文件(難以僞造)版本的信息,讓你得到相當具體的.so使用。使用.lib/.dll進行編譯僅提供基本文件名,任何版本控制都由開發人員管理(使用命名或手動加載庫並手動檢查版本詳細信息)

庫必須隨最終產品(其他人可以拿起並使用它)

0

但現在我經常遇到第三方庫,只有.so文件可用[...],你只需鏈接它們,而不需要-l開關,例如g ++ foo.o /path/to/liblibrary.so。

JFYI,如果您鏈​​接到其不具有SONAME套餐(readelf -a liblibrary.so比較)的共享庫,你會最終把liblibrary.so的指定路徑到你的目標對象(可執行文件或其他共享庫),而這通常是不受歡迎的,因爲用戶對於將程序放置在何處及其相關文件有自己的想法。優選的方法是使用-L /路徑/到-llibrary,或許與-Wl,-rpath一起,/不管/路徑/到如果這是最後路徑(例如路徑功能的決定是由Linux發行例如由)。

我應該更喜歡爲我的圖書館的用戶創建.so文件嗎?

如果您分發源代碼,用戶將作出特定的選擇。

+0

不,即使我分發源代碼,我也會在提供Makefile後做出選擇。用戶幾乎不必爲自己下載的源代碼tarball編寫自己的構建腳本或Makefiles。 – Frank 2010-11-30 05:37:13

相關問題