2017-07-20 23 views
2

我開發了一個C程序,需要一些動態庫,最值得注意的是libmysqlclient.so,我打算在某些遠程主機上運行。看起來好像我有以下分配選項:在linux下發佈一個帶庫依賴的c程序的選項

  1. 編譯程序靜態。
  2. 在遠程主機上安裝所需的依賴關係
  3. 分配程序的依賴關係。

第一個選項是有問題的,因爲我在運行時需要glibc-version(因爲我現在使用glibc和libnss)。

我不確定第二個選擇:是否有一種機制,檢查安裝的庫版本是否足以讓程序運行(在libxyz.so.VERSION旁邊)。我可以在啓動時檢查ABI兼容性嗎?

關於最後一個選項:我是否將所有共享庫與二進制文件分發,或者只是可能未安裝的共享庫(例如libmysqlclient,而不是libm)。

除了這個,我可能會遇到ABI兼容性問題,如果我使用一個不同的二進制編譯器,然後依賴建立與(例如二進制clang,庫gcc)?

+0

構建指定正確依賴關係的包('.deb','.rpm'),因此包管理器將自動安裝它們。 –

回答

3

版本檢查是特定於發行版的。通常,您可以使用目標分發的打包工具將應用程序打包在.deb.rpm文件中,然後將其發送給用戶。這意味着您必須爲每個受支持的發佈版本構建一次應用程序,但實際上沒有辦法解決這個問題,因爲不同版本的libmysqlclient版本略有不同。這些分發構建工具自動生成一些依賴版本信息,而在其他情況下,需要一些手動幫助。

作爲一個起點,最好查看一下分佈式打包,尋找依賴於MySQL/MariaDB客戶端庫的東西並複製它。 Debian中的inspircd可能就是一個很好的例子。

通過構建您想要支持的最舊的分發版本,可以減少需要創建和測試的構建量。但有些注意事項適用;分佈在它們提供的向後兼容性程度上有所不同。

分配程序的依賴關係是非常成問題的,因爲流行的庫如libmysqlclient也由基本操作系統提供,如果您使用LD_LIBRARY_PATH來注入自己的版本,這可能會無意中擴展到其他程序(例如,你從自己的程序啓動的那些)。即使您使用DT_RUNPATH(通過-rpath鏈接器選項),後面的風險仍然存在,儘管它有所減少。

另一種選擇是靜態鏈接特定於應用程序的支持庫,並動態鏈接基本操作系統庫。 (這是一些軟件集合所做的)。但是,libmysqlclient似乎並不是一個很好的選擇,因爲可能會期望它的功能集與發行版相同(關於TLS庫和可用的配置選項) ,並與靜態鏈接,這是很難實現的。

+0

您可以在'$ ORIGIN'中使用'rpath'讓您的應用程序首先在相對應用程序目錄的路徑中查找庫,這是分發所有依賴項的一個選項,結果應該安裝在/ opt下面的某處。 - 但我總是更喜歡發行套餐格式的套餐。 –

+0

如果您從操作系統中執行任何操作,包括名稱服務開關('getpwnam'和朋友)執行的隱式'dlopen',這仍然會導致問題。當然,後者不應該使用'libmysqlclient',但你永遠不會知道...... –

+0

好吧,只要你不分配任何你需要的東西,而不是你的'dlopen()',你應該沒問題,是一些實際使用它的Linux軟件包。正如我所說,我不太喜歡這個解決方案,它只是爲了完整。 –

相關問題