2013-03-24 49 views
17

我使用的是Intel的C++編譯器,它在Linux上依賴於GNU提供的libc.so和libstdC++。so。鏈接/運行時不同GCC版本的風險?

這是我的問題。要訪問一些最新的C++ 11功能,我需要使用GCC 4.7或更高版本附帶的libstdC++。但我堅持使用CentOS 6.4。

在CentOS 6.4上,GCC的本地版本是4.4。但是使用名爲「SCL」的RedHat和名爲「devtoolset-1.1」的軟件包,我可以在「/ opt」下安裝GCC 4.7。

我以上述方式設置了使用GCC 4.7,我可以使用更新的C++ 11功能。

所以,這裏是我的問題:如果用戶運行我的程序只有libc.so/libstdC++。的GCC 4.4版本,所以在庫路徑中,是否有風險,我的程序會有錯誤, 4.4和4.7版本的這些庫?

如果存在潛在的問題,我可以通過靜態鏈接GCC 4.7版本的libc和libstdC++來解決它嗎?或者,如果/當我的代碼動態加載的其他庫選擇由系統範圍的GCC 4.4包提供的較舊的libc/libstdC++時,是否設置了自己的其他問題?

回答

16

正如Praetorian在下面的評論中指出的那樣,使用devtoolset實際上解決了我最初在這個答案中描述的問題。我已經糾正了答案。

是否存在由於這些庫的4.4版和4.7版之間的某些不匹配而導致程序出現錯誤的風險?

是的。鏈接到一個更新的libstdC++。然後嘗試運行和更舊的版本是100%不支持。如果程序中的任何對象或它使用的任何庫都使用GCC 4.7 編譯並鏈接到libstdC++,所以從4.7開始,那麼您需要在運行時使用4.7(或更新版本)的libstdC++。它可能甚至不會運行,但如果它確實存在,則可能會由於不兼容而導致無聲的錯誤。但是這不是你的問題,因爲你沒有鏈接到GCC 4.7的libstdC++。所以,見下文。

我可以通過靜態鏈接GCC 4.7版本的libc和libstdC++來解決它嗎?

1)您只需要爲libstdC++執行此操作,因爲沒有「GCC 4.7的libc版本」這樣的事情。 Glibc是一個與GCC完全分離的項目。當你使用GCC 4.7時,你沒有使用不同的libc,你仍然使用來自CentOS 6.4的系統libc。 (請注意,glibc維護人員強烈建議靜態鏈接glibc,並且在靜態鏈接時glibc的某些功能將不起作用。)

2)靜態鏈接libstdC++將解決此問題,但你不需要,因爲這就是Red Hat Developer Toolset(devtoolset)爲你做的。 devtoolset的重點在於,它允許您使用更新的GCC和更新的libstdC++,但不會在較新的libstdC++庫上創建任何運行時依賴關係。已編譯的可執行文件只需要系統版本的libstdC++。因此,它始終存在於RHEL/CentOS上,即使沒有安裝devtoolset的系統也是如此。 (devtoolset所做的是將所有新的libstdC++特性打包到一個靜態庫中,稱爲libstdc++_nonshared.a,這樣所有的塊都不會出現在系統libstdC++中。所以得到靜態鏈接,其他一切都來自系統libstdC++。so)。

如果你沒有使用devtoolset,那麼另一個選擇,而不是靜態鏈接libstdC++將是運送新的libstdC++。所以你的代碼,並確保它首先被發現(例如通過鏈接你的代碼與引用更新的libstdC++。so)。但是devtoolset不是必需的。

或者,如果/當我的代碼動態加載的其他庫選擇由系統範圍的GCC 4.4包提供的較舊的libc/libstdC++時,是否設置了自己的其他問題?

使用devtoolset時不會出現這樣的問題,因爲您總是使用較舊的libstdC++,所以永遠不會有衝突。

+0

謝謝。所以,確實如此簡單,就是確保在GCC 4.7中的libstdC++。so在我的LD_LIBRARY_PATH之前存在於任何其他版本的libstdC++之前,因此,在運行鍼對libstdC++構建的程序時, 如果我的程序使用的其他.so文件之一對libstdC++具有動態鏈接依賴關係,那麼這不會引起問題。但是,其他共享對象是針對早期版本的GCC構建的嗎? (它不一定是世界末日,如果是這樣的話,因爲我的程序對其他庫有很少(直接)依賴關係。) – 2013-03-24 20:39:42

+0

不,它會正常工作。 libstdC++。因此是向後兼容的,所以4.7版本中的'libstdC++。so.6.0.17'可以被4.7或更高版本編譯的任何東西使用(無論如何回到GCC 3.4.0),但它不兼容**,所以4.4中的'libstdC++。so.6.0.13'不能被4.7編譯的東西使用 – 2013-03-24 21:35:04

+0

NB目前對於libstdC++版本之間的C++ 11功能沒有兼容性保證,所以如果代碼加載的其他庫使用C++ 11功能,那麼它們也應該使用4.7進行重新編譯,但是如果它們只使用C++ 03功能那麼更新的libstdC++。這樣可以正常工作。 – 2013-03-24 21:38:15