0

我正在編寫一個包含大量可選依賴項的C++包。能夠在不使用任何這些依賴關係的情況下使用該包,並且能夠在不重新編譯該軟件的情況下添加依賴關係是很重要的。如果依賴關係不可用,我想回到一些默認行爲。濫用soversion次要修訂版以支持可選的依賴關係

每個可選的依賴對應於包的不同共享庫,我在考慮(ab)使用「soversions」來實現此功能,並使小版本0對應於後備實現。

爲了說明,假設有一個核心模塊被編譯到一個名爲「libmy_core.so」的共享庫中。我有一個可選功能(取決於「libmy_core.so」以及一些外部軟件包)編譯到共享庫「libmy_feature.so.1.1」中。但爲了確保代碼在沒有這個庫的情況下工作,我還構建了一個名爲「libmy_feature.so.1.0」的回退模塊,其中只有依賴於「libmy_core.so」。

然後,我將分發「libmy_core.so」和「libmy_feature.so.1.0」。如果用戶以後添加了可選的依賴項,「libmy_feature.so.1.1」也將被安裝(並且優先於「libmy_feature.so.1.0」)。

這是一個可行的解決方案還是有更好的解決方案?類似的方法也適用於非Linux系統,特別是OS X和Windows?

回答

3

這是一個可行的解決方案還是有更好的解決方案?

這不是一個好的解決方案。你正在爲自己和你的用戶設置依賴地獄。以下是可以工作的替代方案。它與plugin庫的想法有關。

您可以在暴露C接口的共享庫中構建可選功能。然後,您的應用程序/庫可以使用dlopen檢查共享庫的優先級,然後使用dlsym獲取該接口。如果未找到共享庫或未公開所需的接口,則應用程序/庫可以使用在應用程序/庫本身中實現的回退行爲。您必須小心您的應用程序/庫不依賴於可選庫,而只使用由dlsym返回的函數指針。

使用C接口的原因是因爲它提供了一個穩定的二進制接口。使用C++類型時,混合使用不同編譯器編譯的共享庫或使用不同的編譯器設置時,可能會得到未定義的行爲。

在Windows上,您可以使用LoadLibraryGetProcAddress執行相同操作。

+0

感謝您的評論,但我真的不認爲這回答了原來的問題,關於使用soversion。 – Joel

+0

@Joel我回答了你的問題_「有更好的解決方案嗎?」_,但如果你願意,我不介意補充說你最初的想法是錯誤的。看我的編輯。 –

+0

謝謝!你可能是正確的,使用soversion是不是要走的路。最好選擇更傳統的插件方法,並根據需要進行修改。我已經授予你賞金。 – Joel

0

我會加載可選庫dlopen然後你只需要一個庫,並可以使用dlopen返回值來檢測其他庫