2012-02-06 29 views
5

這裏是情況,我有一個使用最新GCC(4.3.3)的C++代碼庫,但我需要鏈接到使用GCC 3.2構建的較舊庫。 3。沒有新版本的庫可用,我不能沒有它,它是封閉的源,所以它不能被重建。混合使用C++ ABI以針對傳統庫進行構建

這似乎是一個問題,因爲GCC 4.3.3和3.2.3之間存在ABI不兼容問題,所以我試圖看看我的選項是用來解決這個問題的。

一些額外的細節:

  • 我可以重現我的代碼庫與-fabi版本= 1的一切才能得到正確的ABI的版本,但是我依賴於一些較新的功能從的libstdC++版本6
  • 代碼庫之外的所有C++庫依賴都是開源的,所以我可以根據需要重建它們,除了這個庫之外。
  • 許多C庫依賴關係無法重建或難以重建。
  • 老庫似乎是依賴於一些的libstdC++版本5層的功能

到目前爲止我試過:

  • 重建所有的C++代碼和依賴庫與-fabi版本= 1和鏈接針對libstdC++版本6.這會導致C++標準庫符號中的一些未定義符號錯誤失敗。
  • 與上述相同,但在共享庫中另外鏈接了libstdC++ 5,它解決了鏈接器問題,但似乎導致在遺留庫內運行時混合兩個版本,並導致崩潰。

我看到這個頁面:http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html這似乎表明可以在應用程序中混合使用C++ ABI版本來滿足庫之間不同的依賴關係。但是,在這裏似乎並沒有很好的工作,除非我錯過了一些東西。

任何想法?

+0

如果您將舊的libstdC++靜態鏈接到共享庫,鏈接器選項'-Bsymbolic'和'--exclude-libs'應該會有所幫助。 – 2012-05-03 20:10:55

回答

3

好吧,你的解決方法是:

  • 寫了一個「C」接口,舊的C++庫,編譯3.2.3所以它會工作。
  • 現在,您可以在新編譯器中使用C接口。

你可以在C庫上編寫一些C++「包裝器」代碼,所以你將它用作C++,但是這個代碼將被構建在新的編譯器中。

+1

當然,這樣做的缺點是增加了一堆膠水代碼,但具有與任何一對C編譯器/版本一起工作的優勢。 – kibibu 2012-02-06 15:36:52

+0

這似乎是一個合理的方法。如果我創建一個共享庫,它仍然會依賴於較舊的libstdC++共享庫。我會不會有同樣的問題?或者我應該靜態鏈接舊版本? – 2012-02-06 16:17:14

+0

在做了一些更深入的挖掘之後,似乎正確的做法是將來自舊版GCC的libstdC++靜態鏈接到此共享庫中。然而,僅僅與此相關聯,我懷疑,這還不夠,因爲你將會像以前一樣有效地解決圖書館邊界上共享符號的問題。我認爲你可以通過在應用程序中使用dlopen並使用RTLD_NOW |來消除這種情況RTLD_DEEPBIND | RTLD_LOCAL。 – 2012-02-07 20:23:11