2012-04-12 26 views
3

我一直對Microsoft的CRT有許多概念問題。對於任何項目,您必須編譯所有必需的庫以鏈接到相同版本的CRT。與Microsoft相比,如何處理Linux CRunTime庫

第一個問題是當您的項目與CRT(/ MT)靜態鏈接時。然後所有的依賴庫也必須靜態鏈接自己的CRT。因此,每個庫都有自己的版本 - 例如 - malloc()。如果您去年在系統A上編譯了其中一個庫,則該CRT版本可能與您當前在另一個帶有Service Pack 3+的系統B上使用的版本不同。因此,如果您釋放庫所分配的對象,可能會遇到問題。

所以看起來動態鏈接CRT是要走的路(/ MD)。使用dll,所有庫都將獲得系統上CRT的當前實現。除了微軟的Side by Side機制,並非如此。相反,您可以獲得印在您編譯的庫上的CRT版本,並將該DLL的版本提供給該庫。所以我之前描述的完全相同的問題可能會發生。一年前您可以在一臺CRT上編譯一個系統A的庫。一年後有一個升級的新版本。您的主程序獲取帶有一個版本的CRT的DLL,該庫與另一版本的CRT獲取該DLL,可能會出現同樣的問題。

那麼你會怎麼做?我意識到跨庫內存分配是不受歡迎的。但是你可以忽略malloc的例子,並提出另一個例子。你是否已經讓每個開發人員重新編譯他們機器上的每個相關庫,以確保所有內容都使用相同的CRT?那麼對於這個版本,你重新編譯每個庫?

這在Linux上如何工作?這是我的主要興趣。有沒有提供GCC的CRT或Linux系統本身帶有CRT庫?我從來沒有見過在Makefils中顯式鏈接CRT。

在Linux上,動態庫鏈接到什麼CRT?機器上最新的一個,還是更「並排」的機制。

+0

據我所知,在Linux中重建所有項目和依賴關係通常不是問題,因爲代碼經常可用。 – Lol4t0 2012-04-12 18:00:50

+0

glibc(C庫的GNU實現,涵蓋了ISO C + POSIX +一些擴展)使用版本化符號來處理版本之間的兼容性。幾乎所有其他庫作者都不關心版本之間的這種兼容性,因爲無論如何,大多數Linux軟件都是作爲源代碼分發的,可以隨意重新編譯(通過發行版甚至最終用戶)。 – ninjalj 2012-04-12 20:06:46

+0

從技術上講,由於所述符號版本的原因,在Linux上也會發生調用不同的samefunc @@版本的不同代碼部分的問題。然而,與msvcrt不同的是,glibc目前只有一個malloc符號(malloc @@ GLIBC_2.2.5)。畢竟,自從ANSI C以來,malloc的ABI一直沒有改變,我不明白爲什麼它需要更多的功能,而且不太可能。 – 2012-04-12 20:31:27

回答

2

在Linux方面,我認爲標準庫有兩個基本部分存在問題:我們有C運行庫部分,它應該永遠都是ABI兼容的。實際上,無論在最終鏈接時鏈接哪個版本都應該沒問題,並且如果它是兼容性所需的舊版本,則可以使用二進制文件重新分發任何所需的共享庫。通常庫只是並排放在* NIX系統上。

其次,你有C++庫。這幾乎保證不會以任何方式與ABI兼容,所以您必須必須針對相同版本的C++庫重建最終二進制文件的每個單個組件。不幸的是,它不可避免地是因爲否則你可能會遇到各種不匹配。這就是爲什麼許多開源庫甚至不打擾預製庫二進制文件:每個人都需要構建自己的副本,以確保它能正確鏈接到最終的應用程序代碼中。

+0

我認爲過度簡化了Linux的情況。不要將程序鏈接到特定的major-minor libc版本(補丁版本被忽略以支持非ABI更改的更新)?事情是,在Linux平臺上從源代碼構建更多的軟件。此外,正確的圖書館下載由包管理員處理。 – 2012-04-12 19:32:25

+0

CRT和C++ STD庫是否總是動態鏈接?如果「crt.so」被鏈接,路徑中的路徑是否會被使用,或者是否存在像Windows一樣的Windows DLL Loader查看CRT版本清單並從Windows \ WinSxS獲取DLL的機制? – Budric 2012-04-12 19:33:09

+0

圖書館並不總是動態鏈接,儘管在* NIX中這是非常受歡迎的。它將'libc.so.1'鏈接到一個類似於'.so'的地方,因此它知道在運行時加載哪個'.so'(儘管允許兼容補丁)。 – 2012-04-12 19:41:52