2013-04-18 107 views
7

我有一個autotools C項目。如何編譯與libcrypto.so.0.9.8和libcryto.so.1.0.0兼容的二進制文件?

如何編譯與libcrypto.so.0.9.8和libcryto.so.1.0.0兼容的二進制文件? (即Ubuntu 9.10和12.04)

根據我在其上構建的操作系統的時代,二進制文件需要一個版本或另一個版本。

有沒有辦法讓它不在意,或者是libcryto版本之間的差異不可逾越?

+1

據我所知,從我自己的經驗來看,如果您不使用1.0功能(如時間戳),它將正常工作。你所要做的就是依賴libssl-dev。但是,自從soname發生了變化,意味着界面發生了變化,您必須對其進行測試...... – Felipe

+0

@Felipe - 不,主要版本號更改是問題的核心,可執行文件需要0.9.8或1.0.0 ,具體取決於它所在的操作系統版本。即libcrypt.so符號鏈接指向構建時的任何位置。 – fadedbee

+0

啊,我想我明白了。你將程序編譯到某處(0.9.8或1.0.0),然後,你必須將它運行到其他地方(再次運行在0.9.8或1.0.0中)。您的構建環境與運行時環境不同,它們都可以變化,正確嗎? – Felipe

回答

3

在我看來,你想使用一些函數libcrypto.so.0.9.8和一些來自libcryto.so.1.0.0。如果大多數功能都是從1.0.0開始要求的或者是首選的,那麼請使用libcrypto.so.1.0.0。

而且您可能需要libcrypto.so.0.9.8中的某些功能,或者您可能有其他充分的理由來使用libcrypto.so.0.9.8。

在我看來,如果你從這兩個庫鏈接,你會得到鏈接器錯誤(重複的符號,因爲這兩個庫都包含相同的符號)。

如果你需要使用0.9.8,那麼使用dlopen動態加載它,並獲得你想用於dlsym的函數回調。

void * handle; 
/*reqd_callback is the callback of required function.*/ 
reqd_callback cb; 

handle = dlopen ("libcrypto.so.0.9.8", RTLD_LAZY); 
cb  = (reqd_callback)dlsym(handle, "reqd_function"); 
//Call the cb 
cb (parameters); 

//Close the library. 
dlclose(handle); 

我想,這可能會解決你的目的:

這可以如下實現。如果首選項相反,則在鏈接和程序加載中反轉庫。

+0

謝謝,我已經在你的答案之前實現了這一點,但你得到的賞金:-)我首先嚐試libcrypto.so,然後libcrypto.so.1.0.0,然後libcrypto.so.0.9.8,最後libcrypto。 so.0.9.8e(RHEL 5)。我只需要在我遇到的所有版本中都有一些散列函數。這使我在RHEL/CentOS/Debian/Ubuntu/Fedora上的兼容性超過5年(基於Etch構建)。我有理智的檢查動態鏈接功能的代碼,以防萬一它們在未來版本的libcrypto中發生變化。附: http://www.virtsync.com – fadedbee

2

您可以製作一個軟鏈接,它將「指向」libcrypto.so.0.9.8或libcryto.so.1.0.0。 給它一個通用的名稱,然後使用它,然後無論版本的庫鏈接「指向」,將被拿起?在應用安裝中,您將軟鏈接設置爲指向可用的庫版本。如果lib向後兼容足夠的話,你的軟件可能會被測試到1.0.0,也就是說,你不依賴1.0.0中的不是0.9.8的東西,你可以。

2

您可以重建ssl-0.9.8(不包含1.x,因爲它包含了一些不適用於舊版本的東西),並更改makefile中最後一個共享庫鏈接的行並嵌入SONAME

與SONAME重新編譯它從libssl.so.0.9.8改爲libssl.so.0

它看起來像:-Wl,-soname,libssl.so.0.9.8 它更改爲:-Wl,-soname,libssl.so.0

現在

當你編譯針對這個庫,根據它構建的二進制文件將查找libssl.so.0(其中, h包含在兩個版本中作爲符號鏈接)

+0

RHEL 5.X沒有libcrypto.so符號鏈接。它只有libcrypto.so.6和libcrypto.so.0.9.8e iirc。 – fadedbee

+0

我真的很喜歡這個答案的早期版本。如果不是RHEL 5缺少libcrypto.so符號鏈接,我會接受它。 – fadedbee

+0

我沒有提到libcrypto,因爲原來的問題是關於ssl的。儘管如此,如果你這樣做並直接鏈接到'-lssl',而不是''-lcrypto'(讓它在運行時動態地找到它們),那麼objdump -x將只顯示需要ssl的soname,並且由於crypto是依賴項,它將基於所需的任何已安裝的libssl動態加載,該libssl具有libssl.so.0的符號鏈接 – technosaurus