1. 程式人生 > >VS2008中編譯和使用OpenSSL

VS2008中編譯和使用OpenSSL

一、編譯OpenSSL

在編譯OpenSSL前,需要正確安裝Perl,因為在編譯OpenSSL時需要使用到該程式。

下載最新版本的Perl:http://downloads.activestate.com/ActivePerl/Windows/5.8/ActivePerl-5.8.8.822-MSWin32-x86-280952.zip。然後安裝之。

下載最新版本的OpenSSL:http://www.openssl.org/source/openssl-0.9.8g.tar.gz

然後將原始碼釋放的c:\openssl-0.9.8g目錄中。

首先將VS2008的nmake的環境變數加入的cmd中:

在cmd中執行 *:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat


進入openssl原始碼目錄。
cd c:\openssl-0.9.8.g

執行configure:
perl Configure VC-WIN32 --prefix=c:/openssl

建立Makefile檔案:
ms\do_ms

編譯動態庫:
nmake -f ms\ntdll.mak
編譯靜態庫:
nmake -f ms\nt.mak

測試動態庫:
nmake -f ms\ntdll.mak test
測試靜態庫:
nmake -f ms\nt.mak test

安裝動態庫:
nmake -f ms\ntdll.mak install
安裝靜態庫:
nmake -f ms\nt.mak install

清除上次動態庫的編譯,以便重新編譯:
nmake -f ms\ntdll.mak clean
清除上次靜態庫的編譯,以便重新編譯:
nmake -f ms\nt.mak clean

1. 準備:

1.1 安裝perl環境, 下載地址: http://dlsw.baidu.com/sw-search-sp/soft/4a/14792/ActivePerl_5.16.2.3010812913.msi
1.2 下載nasm.exe和ndisasm.exe, 地址: http://dldx.csdn.net/fd.php?i=639621962335100&s=3ad4555faf530935e0d6fed04f37fd21



2. 編譯

2.1 參考INSTALL.W64檔案, To build for Win64/x64: (在dos下執行以下命令)---編譯出錯,未成功
cd E:\program\opensource\openssl-1.0.1h(openssl原始碼目錄)
perl Configure VC-WIN64A
ms\do_win64a----這裡有錯誤
nmake -f ms\ntdll.mak
cd out32dll
..\ms\test


2.2 參考INSTALL.W32檔案, Visual C++:---編譯成功,安裝成功
perl Configure VC-WIN32 --prefix=D:\opensource\openssl// prefix指定安裝位置
ms\do_nasm// 使用匯編語言檔案和NASM
nmake -f ms\ntdll.mak// 將會生成dll檔案或可執行檔案,在目錄out32dll下


2.2.2: 如果想測試下,可以執行: nmake -f ms\ntdll.mak test


3: 安裝
將OpenSSL安裝到指定的路徑: nmake -f ms\ntdll.mak install



注意:

因為要執行nmake命令,但是這個檔案所在路徑並沒有註冊到Path環境變數下,所以最好在"Visual Studio 2008命令提示"視窗中操作以上命令.

-------------------------------------------------------------------------

我的系統是win7 64位, 我本來想參考INSTALL.W64檔案來編譯的,但是中途出錯了,出錯的檔案是ms\uptable.asm,有個"..imagebase"未定義,最終放棄。

最後參考INSTALL.W32檔案,成功了!

1.下載 ActivePerl-5.8.0.806-MSWin32-x86 並安裝

開始安裝:完全可以參照斑竹的文章或openssl目錄下的install forw in32

1) > perl Configure VC-WIN32
: 如不成功會有明顯提示
2) > ms\do_ms

3)轉到C:\Program Files\Microsoft Visual Studio\VC98\bin目錄(預設安裝時)下
執行 vcvars32.bat 以配置環境變數。

4)跳到openssl目錄下
執行> nmake -f ms\ntdll.mak
:如果編譯成功,最後的輸出都在out32dll目錄下 : 包括可執行檔案 、兩個dll和兩個lib檔案。
: 最終編譯出來的結果都存放在out32dll子目錄下,常用的檔案包括libeay32.lib,libeay32.dll,ssleay32.lib,ssleay32.dll以及openssl.exe。中間生成的obj檔案都在tmp32dll子目錄下,可以把它們刪掉。 5.執行 nmake -f ms\ntdll.mak test。檢查上一步安裝編譯是否成功。 然後在C:\openssl目錄下建立bin, include, lib三個資料夾。bin目錄下包括openssl.exe(), ssleay.dll(),libeay.dll(),lib目錄下包括兩個lib資料夾,即ssleay32.lib,libeay.lib,分別是ssleay.dll、libeay.dll動態連結庫對應的lib檔案。include目錄包括了openssl開發設計的標頭檔案。

安裝步驟:
1、執行cmd,切換到openssl目錄,perl Configure VC-WIN32
如不成功會有明顯提示
2、下面三個命令選一個就行了
     ms\do_ms 推薦使用這種方式 另外兩種方式 如果使用也必須保證本機有編譯器才能使用。
    :ms\do_masm (預設vc 自帶的編譯器;也也以自己下載安裝,我用的這個,因為我用其他的沒成)
    :ms\do_nasm (需要自己下載)
3、vcvars32.bat 以配置環境變數。
4、nmake -f ms\ntdll.mak 如果編譯成功,最後的輸出都在out32dll目錄下:包括可執行檔案、兩個dll和兩個lib檔案: libeay32.dll, libeay32.lib, ssleay32.dll, ssleay32.lib(我編譯的時候出現了這個錯誤
    'ml' 不是內部或外部命令,也不是可執行的程式
     或批處理檔案。
     NMAKE : fatal error U1077: 'ml' : return code '0x1'
     Stop.
    大家應該一看就知道問題所在,解決很容易,把VC下的ml.exe複製到當前目錄即可)

程式設計初步:
1、 開啟VC-Tools-Options-Directores,在Include files中增加【openssl-0.9.8】\inc32目錄;在Libray files中增加【openssl-0.9.8】\out32dll
2、 在源程式中包含以下三個標頭檔案並加入LIB:

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#pragma comment(lib, "libeay32.lib")

#pragma comment(lib, "ssleay32.lib")


以上是最簡單的安裝方式,但是不能使用靜態庫,必須帶著DLL檔案才行,下面有另外一種安裝方式:

   
    將原始碼釋放在c:\openssl-0.9.8g目錄中。
   
    進入openssl原始碼目錄。
    cd c:\openssl-0.9.8.g
   
    以下為參照該目錄下的檔案INSTALL.W32的執行過程:

    執行configure:
    perl Configure VC-WIN32 --prefix=c:/openssl

    建立Makefile檔案:
    ms\do_ms
   
    編譯動態庫:
    nmake -f ms\ntdll.mak
    編譯靜態庫:
    nmake -f ms\nt.mak

    清除上次動態庫的編譯,以便重新編譯:
    nmake -f ms\ntdll.mak clean
    清除上次靜態庫的編譯,以便重新編譯:
    nmake -f ms\nt.mak clean

使用靜態庫,只需在Libray files中修改【openssl-0.9.8】\out32dll 為【openssl-0.9.8】\out32

我遇到的一個問題,到網上找到了答案,記錄如下:

--------------------Configuration: b64 - Win32 Release--------------------
Compiling...
b64.c
Linking...
MSVCRT.lib(MSVCRT.dll) : error LNK2005: __isctype already defined in LIBCMT.lib(isctype.obj)
MSVCRT.lib(MSVCRT.dll) : error LNK2005: _fclose already defined in LIBCMT.lib(fclose.obj)
MSVCRT.lib(MSVCRT.dll) : error LNK2005: __errno already defined in LIBCMT.lib(dosmap.obj)
MSVCRT.lib(MSVCRT.dll) : error LNK2005: _fflush already defined in LIBCMT.lib(fflush.obj)
MSVCRT.lib(MSVCRT.dll) : error LNK2005: _strncpy already defined in LIBCMT.lib(strncpy.obj)
MSVCRT.lib(MSVCRT.dll) : error LNK2005: _strchr already defined in LIBCMT.lib(strchr.obj)
LINK : warning LNK4098: defaultlib "MSVCRT" conflicts with use of other libs; use /NODEFAULTLIB:library
Release/b64.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

b64.exe - 7 error(s), 1 warning(s)

從錯誤資訊可以看出是msvcrt.lib和libcmt.lib庫中重複定義了__isctype等符號。為什麼會出現這樣的問題呢?這就要從這兩個庫的作用說起了。

msvcrt.lib是VC中的Multithreaded DLL 版本的C執行時庫,而libcmt.lib是Multithreaded的執行時庫。在同一個專案中,所有的原始檔必須連結相同的C執行時庫。如果某一檔案用了Multithreaded DLL版本,而其他檔案用了Single-Threaded或者Multithreaded版本的庫,也就是說用了不同的庫,就會導致這個警告的出現。

告警資訊的意思我們明白之後,就要找造成這個問題的原因了。在專案設定中我們可以看到當前專案使用的是Multithreaded非DLL版本的執行時庫,這說明專案中還有其他檔案用到了不是這個版本的執行時庫。很顯然,就是openssl的靜態庫。檢視openssl中ms下的nt.mak,我們可以發現靜態庫版本中openssl使用編譯開關/MD進行編譯的,也就是說openssl靜態庫是預設用的Multithreaded DLL 版本的C執行時庫。

原因找到了。那麼解決方法,很明顯有兩個。總之就是將兩個專案的執行時庫統一。

簡單的方式就是將專案的動態庫修改為使用Multithreaded DLL 版本的C執行時庫即可。某些情況下你的專案可能不能改變當前的執行時庫,你可以將openssl的nt.mak中的/MD開關修改為/MT然後重新編譯openssl靜態庫就可以了。