在我正在開發的項目中,我們提供了動態加載附加功能的可能性。爲此,我們使用dlopen。如何查找庫以使用dlopen動態加載它們
爲了找到這個庫,我們有一些我們稱之爲模塊路徑的東西。在那裏,我們有一個默認路徑,其中共享庫是(其中很多是出貨)。
目前我們有兩個默認路徑:我們首先查看共享庫的構建目錄,然後查看安裝目錄。這是因爲它也應該可以在不安裝它的情況下運行應用程序(所以在這種情況下,它需要首先查看構建目錄)。
現在的問題在於,如果用戶從源代碼構建應用程序並使用make install進行安裝,默認情況下將加載她的構建目錄中的庫。這將導致崩潰。因此,只有當用戶之後刪除或重命名構建目錄時纔有效。
沒有問題:是否有一個技巧(通過C++或構建系統)知道應用程序是否安裝。問題是,功能是在一個共享庫中實現的,並且搜索模塊的實現方式也適用於與我們的庫鏈接的其他應用程序(所以我們不能依賴可執行文件的路徑)。我們使用CMake作爲構建系統。
爲了使情況更加困難,解決方案必須在Windows,Linux和Mac OS X上運行
編輯:
我進一步調查,問題更爲複雜。情況是這樣的:
- 有一個小的可執行一個
- 此外,還有一個「主」庫main.so
- 再有就是lib.so
- lib.so動態加載庫鏈接對main.so
問題是,lib.so具有在它的rpath構建目錄中的main.so的絕對路徑。感謝@MSalters的提示,我現在可以做一個破解,以確保加載正確版本的lib.so(安裝目錄中的那個),但由於它在rpath中有構建路徑,所以加載了錯誤的main .so(因此實際上在內存中有兩個main.so副本 - 這會弄亂一切)。
有沒有辦法從庫中刪除對構建路徑的引用?我嘗試了所有與rpath相關的cmake選項,但沒有成功
是不是很容易修復崩潰呢? – MSalters
問題是,加載的庫鏈接也對主庫。由於構建目錄中的路徑具有到構建目錄中的路徑的完整路徑,並且安裝的路徑中有相對路徑,因此都會加載。然後是衝突(或更具體的:singelton沒有在庫的第二個副本中初始化)。 –
(加載第二個庫)聽起來像你可以很容易地檢測到的東西。這不是你問題的答案嗎? – MSalters