2014-02-19 36 views
6

可能在任何操作系統上,都可以靜態或動態地編譯C++/C標準庫。在Windows上,我總是傾向於使用靜態構建,因爲它有助於避免安裝或未安裝在特定Windows版本,版本和Service Pack等上的不同版本的庫的「地獄」問題。靜態鏈接使軟件更具可移植性,更少依賴於什麼最終用戶使用他的操作系統(我甚至看到了一些例子,當最終用戶可以在system32的某些DLL上製作SHIFT+DEL時,他無法解釋爲什麼,或者當用戶聲稱我的應用程序包含病毒,因爲它試圖從官方動態下載鏈接的先決條件微軟網站......)因此,在Windows上,靜態鏈接通常比我的體驗中的動態鏈接更好。 但是,我是Linux新手,所以任何人都可以分享他的經驗嗎?我的問題是:如果我們忽略了動態節點允許節省內存的事實,並且我們計劃使用自動化安裝程序分發軟件(硬盤驅動器空間),那麼Linux上優先考慮什麼樣的鏈接(動態或靜態)和內存現在已經足夠便宜了,所以沒有理由犧牲幾個小時的工作時間來創建出色的便攜式安裝程序來贏取一些內存或硬盤空間)。有動態/靜態鏈接的Linux特定問題嗎?Linux:C/C++標準庫靜態與動態鏈接

+1

請[看看這裏](http://stackoverflow.com/questions/1993390/static-linking-vs-dynamic-linking)。 –

+1

通過打包來部署軟件(例如Debian或Ubuntu的'.deb'軟件包)。 –

+1

@BasileStarynkevitch每個發行版都比靜態鏈接更容易。 –

回答

6

在Linux上,您通常有一個軟件包管理器,可以確保您只安裝一個版本的庫。所以通常沒有地獄,沒有動態鏈接的問題。動態鏈接是Linux上的標準方式。

+2

由於這個確切原因,您的可執行文件不能在另一個發行版上運行。 –

+0

@MaximYegorushkin:它可能適用於提供相同包管理系統的發行版。 – TNA

+1

Linux上的理想方式是無論如何都要提供源代碼。 – TNA

3

我想說的答案取決於你如何分配軟件。

如果將軟件打包爲特定的Linux發行版並且版本通常首選動態鏈接。你知道在系統上找到哪些庫,你可以指定依賴關係。然而,如果你想將軟件作爲在任何系統上運行的Linux二進制文件(例如各種遊戲或像Matlab這樣的軟件)分發,你最終會得到相同的dll(或.so)地獄問題在Windows上。您不知道系統上哪些庫的版本。因此,您必須提供您自己的.so文件或靜態鏈接。

+1

讓我補充一點,也可以使用dl庫(使用-ldl鏈接)以編程方式加載共享庫。因此,首先在程序中檢查是否有一些必需的庫版本可用,然後加載該庫或向用戶顯示通知,並精確地告訴他缺少什麼,以便他可以彈出他的包管理器並安裝該庫。 – cmaster

+2

確實如此,但獨立分發的二進制文件可能與可能在軟件包管理器中不再可用的較舊版本的lib有潛在關聯。 – kazemakase

2

查看使用動態鏈接的全部意義在於減少可執行文件的大小和內存使用情況。如果您忽略了太少的話題。

另一方面你提到關於節省內存和磁盤空間。有必要節省磁盤空間,因爲當你想導出你的應用程序/程序,你不能把一個2Gb應用程序在互聯網上下載(for示例openCV庫大約是2.1GB)。解決方案是動態鏈接它們,只加載那些對你有用的模塊。這樣也可以實現高效的多任務處理(僅創建模塊的一個副本,並且整個程序使用相同的副本)。 獨有的:

例如,媒體播放器應用程序可能最初被運 與 支持MP3文件格式的編解碼器。如果媒體播放器是靜態鏈接的,則不可能 動態更新它以支持不同的文件格式,而不用 替換整個應用程序。動態鏈接意味着包含更新的編解碼器的新版本的 共享庫可以動態加載到運行時的內存中,該庫包含一些增強功能 和錯誤修復程序,以便在運行時將內存中的原始文件共享庫。共享庫也可以由多個應用程序共享。例如,兩個不同的媒體播放器都可以使用包含相同的 編解碼器的相同共享庫。這可能意味着運行應用程序的設備需要更少的物理內存,具體取決於動態鏈接程序的大小。

第三,在linux下一切都是動態鏈接除了whic也有它的動態版本/斌/灰,但這不應該在Linux靜態鏈接阻止你的/bin/ash.static。 當使用gcc的鏈接是默認動態。我想你應該使用「靜態」標誌來靜態鏈接庫

+0

我明白了,但是使用靜態鏈接智能鏈接器(包括MSVC++和GCC提供的鏈接器)將僅鏈接真正需要的對象文件,因此如果使用OpenCV的全部**功能,則應用程序的大小將爲2GB,否則將要小得多。 – Vitaliy

+0

@Vitaliy我剛剛注意到了這一點。請看下面的答案。在撰寫答案時,我對社區是陌生的,因此沒有足夠的信用評論,所以我回答了你的答案。 – kaushik94

0

@Vitaliy好,你帶來了這個。這裏需要注意的重要事情是,智能鏈接並且共享庫(或動態庫)的創建是互斥的,也就是說,如果啓用智能鏈接,則將創建共享庫。

智能鏈接將代碼分解爲小代碼塊並加載它們的依賴關係。 因此,如果您多次調用依賴項,則會多次加載該依賴項。 這給出了非常好的執行時間,但編譯時間非常長,特別是對於大型單元。因此存在一定的權衡。