簡體   English   中英

STL和發布/調試庫混亂

[英]STL and release/debug library mess

我正在使用第三方。 我正在使用它的共享庫版本,因為庫很大(~60MB)並且被多個應用程序使用。

有沒有辦法在應用程序啟動時發現庫的發布/調試版本分別用於我的應用程序的發布/調試版本?

更長的描述

暴露C ++接口的庫。 其中一個API方法返回std::vector<std::string>

我在調試模式下編譯應用程序時的問題,應該使用庫的調試版本。 同樣的發布。 如果使用了不正確的庫版本,應用程序將崩潰。

根據gcc(參見http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html

但是對於可以使用調試模式或發布模式basic_string對象的混合模式標准庫,事情會變得更復雜

PS 1

看起來Timbo的提議是一種可能的解決方案 - 使用不同的soname來調試和發布庫。 那么,應該將什么傳遞給./configure腳本來更改庫的名字?

PS 2

我的問題不是在鏈接時,而是在運行時。

PS 3

是一個問題,展示了我面臨的問題。

此處引用的調試模式與應用程序的調試或發布版本無關 STL調試模式使用-D_GLIBCXX_DEBUG激活,是一種特殊的檢查模式。

第三方庫實際上不太可能使用STL檢查模式進行編譯,但如果是,則很可能會很快提及您的代碼也應該使用-D_GLIBCXX_DEBUG進行編譯。

如果第三方庫沒有使用檢查STL構建,那么無論您是在進行優化還是調試構建,它都與您的代碼兼容。

由於您聲明與第3方庫的優化構建鏈接的代碼的調試版本導致崩潰,因此該崩潰很可能是由代碼中的錯誤(或可能是第3方庫中的錯誤)引起的。

Valgrind和GDB是你的朋友。

我相信您誤讀了您提供的鏈接上的文檔。 特別是,您誤解了其目的 - 該部分名為“目標”,並描述了C ++調試庫的一些假設設計以及這些設計的后果,以便解釋所做出的實際設計選擇。 在您引用的行之后的文本位描述了由假設實現產生的混亂,該實現具有針對釋放模式和調試模式字符串的單獨設計。 它繼續說:

因此,我們無法輕松地為std :: basic_string類模板提供安全的迭代器,因為它存在於整個C ++標准庫中。

(或者,重述一下,提供一個特殊的“調試”版本的字符串迭代器是不可能的。)

...

通過libstdc ++調試模式的設計,我們無法有效地隱藏用戶的調試和釋放模式字符串之間的差異。 未能隱藏差異可能會導致不可預測的行為,因此我們選擇僅執行不需要ABI更改的basic_string更改。 對用戶的影響預計會很小,因為有簡單的替代方案(例如__gnu_debug :: basic_string),並且我們從混合調​​試和發布編譯的翻譯單元的能力中獲得的可用性好處是巨大的。

換句話說,GCC的libstdc ++中的調試和發布模式的設計已經拒絕了這個假設的實現,並對字符串進行了單獨的設計,特別是為了允許您擔心如何避免的類型的跨模式鏈接。

因此,如果沒有-D_GLIBCXX_DEBUG (或者如果由於某種原因,您可以使用它),並且將它與應用程序的任一模式相關聯,那么編譯庫時應該沒有問題。 如果你確實有問題,那是因為某個地方出現了錯誤。 [但請看下面的編輯! 這是特定於std::string ,而不是其他容器!]

編輯:在接受了這個答案之后,我在std :: vector <std :: string>崩潰時回答了后續問題,並意識到這個答案的結論是不正確的。 GCC的libstdc ++使用字符串來巧妙地支持“Per-use recompilation”(其中給定容器對象的所有使用必須使用相同的標志進行編譯,但是在程序中使用相同的容器類不需要使用相同的方法編譯flags),但這與提供所需交叉鏈接能力的完整“單元編譯”不同。 特別是,文檔說明了這種交聯能力,

我們認為,如果我們打算提供安全的迭代器,保持程序語義不變,並且在發布模式下不會降低性能,那么這種重新編譯水平實際上是不可能的....

因此,如果您在庫接口上傳遞容器, 需要兩個單獨的庫。 老實說,對於這種情況,我發現最簡單的解決方案就是將兩個庫安裝到不同的目錄中(每個變體一個 - 並且您希望兩者都與主庫目錄分開)。 或者,您可以重命名調試庫文件,然后手動安裝它。

作為進一步的建議 - 你可能不經常在調試模式下運行它。 可能只需要將調試版本靜態編譯並鏈接到您的應用程序中,因此您不必擔心安裝多個動態庫並在運行時保持它們直接。

為DLL的調試版和發行版提供不同的名稱,並通過庫依賴關系鏈接正確的名稱。 您的應用程序然后將不會啟動,除非它找到正確的DLL。

這是您應該在構建系統中進行的檢查。 在您的構建腳本中,

  • 如果您正在構建發布版本,則鏈接到發布庫。
  • 如果你正在構建調試,那么鏈接到調試庫。

例如,如果您正在使用make:

release: $(OBJ)
    $(CC) $(CXXFLAGS_RELEASE) $(foreach LIB,$(LIBS_RELEASE),-l$(LIB))
debug: $(OBJ)
    $(CC) $(CXXFLAGS_DEBUG) $(foreach LIB,$(LIBS_DEBUG),-l$(LIB))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM