2016-12-29 97 views
0

我爲一個庫製作Debian軟件包,我將其稱爲libmystuff。目前它的版本是4.0.0,下一個版本是4.1.0,可能會破壞API的兼容性。該項目使用CMake來構建。soname的Debian軟件包命名策略

這應該怎麼處理soname和包名?

我想將軟件包版本初始化爲4.0.0。如果我命名包libmystuff,那麼我得到一個lintian錯誤,告訴我把包的soname放在包名(package-name-doesnt-match-sonames)中。很公平。

如果我將包名稱爲libmystuff4,那麼我會得到一個名爲libmystuff4-dev_4.0.0-1ubuntu8_amd64.deb的包文件,它似乎有點多餘但可以,包是用於主版本4,軟件是版本4.0.0。但我仍然獲得了林田錯誤說,

libmystuff4: package-name-doesnt-match-sonames libmystuff4.0.0 

所以這令我感到詫異,爲什麼林田要我把所有3個部分的soname的包名稱,而不是僅僅是第一部分?

在任何情況下,所以我將包名改爲libmystuff4.0.0,現在lintian很安靜,但是我得到一個名爲libmystuff4.0.0_4.0.0-1ubuntu8_amd64.deb的包文件,它看起來超冗餘!

我該怎麼辦?

我在想也許soname應該是0,即使庫版本是4.0.0,我應該在發佈4.1.0時將soname設置爲1等。這需要修補上游CMake構建系統,這是一個可接受的方法?雖然在那種情況下,soname的其他部分怎麼樣,我只是將它們設置爲0?那麼這個軟件包將會是soname 0.0.0。

否則當他們釋放4.1.0時,我必須將soname更改爲5.0.0,這會變得非常混亂,對吧?

回答

1

簡短回答:將當前SONAME設置爲libmystuff.so.0,並且當您在4.1.0中打破ABI時,將SONAME設置爲libmystuff.so.1。您需要修補構建系統並在相關位置引入set_property(TARGET mystuff PROPERTY SOVERSION 0)

您的SONAME是而不是與您的圖書館版本相同,可能需要獨立進化。

較長答案: 庫是在有點彆扭他們有兩個分立面,可以有效地進行版本:兼容性,和二進制兼容性。這些分別是APIABI。一個庫版本可以維護API並且與源代碼兼容,同時打破ABI並且與二進制不兼容,反之亦然。

幸運的是,需要自動執行的唯一部分是運行時二進制兼容性。您可以告訴人們閱讀您的文檔,說明API在4.0.0版和4.1.0版之間破碎;您無法告訴運行時動態鏈接器來閱讀您的文檔。

因此SONAME誕生了。鏈接到庫的任何動態對象都將嵌入此字符串,它會告知動態鏈接器要加載哪些庫文件以解析符號。

因爲它是一個字符串,所以它基本上沒有任何要求 - 或者編碼的信息。運行時鏈接程序根本不會解釋它;它只關心嚴格的字符串平等。

這是Lintian警告來自哪裏 - 那裏否「soname的第一部分」;你的SONAME是字符串libmystuff.so.4.0.0。 4.0.0部分對人類有意義,而不是鏈接器。由於SONAME本質上是任意的,所以約定已經圍繞它成長了,並且慣例是libmystuff的第一個版本的SONAME應該是libmystuff.so.0,然後'.0'應該每次增加1向ABI做出向後不兼容的變更。所以第一個版本是libmystuff.so.0,第二個ABIlibmystuff.so.1,第三個ABI是libmystuff.so.2等等。

這是完全獨立的庫版本 - 例如,glibc的項目目前是在2.24版本,併產生與SONAME libc.so.6庫(並做了二十多年了)。

如果您使用項目的版本作爲SONAME,然後時間您更改版本任何使用該庫的任何內容必須重建,以便使用新的庫。一個針對版本4.0.0構建的程序將嵌入字符串libmystuff.so.4.0.0,並且不會嘗試加載libmystuff.so.4.0.1