windows下libcurl+openssl静态库编译(32位和64位静态库-不同openssl版本)

关于windows下编译libcur相关的库的文章是一大把,但是支持ssl的相关文章相对少一些,能按照对应要求编译通过的更少,编译成静态库的更少!再就是更不用说同事支持win64位系统的了,如下为我们开发过程中实际编译通过的总结,一来希望后续使用人员能够看到,为广大网友做点实际的共享,二来作为备忘录,以备后续自己使用,以防忘记或丢失。

libcur一来zlib和openssl,zlib库编译很简单,不论是动态库还是静态库,问题关键在于openssl这个库动态库和静态库的编译。很多文章编译openssl都使用的是openssl1.0.2o或一下,大多数网络文章也是给予这些老旧版本的openssl的编译进行说明,但是现在官网最新的openssl都已经是openssl1.1.0h了,这个版本与openssl1.0.2o就不太一样了,所以编译方式也不一样

注意,在项目使用libcurl过程中,我们遇到一个大坑,就是libcurl的多线程安全问题,由于用到https,即libcurl依赖openssl,如果不注意线程安全问题,会导致你的C++程序崩溃(我相信没有人说我不用多线程处理应用的),这里我要说明的重点是如何避免libcurl的https多线程问题:

(1)在post或get封装(就是从libcurl请求到收到回复整个过程的封装)里加一把大锁,锁住与libcurl相关的所有https请求

(2)使用的libcurl支持ssl用到的openssl的版本必须在1.1.x或以上(已经解决线程安全问题)

(3)如果编译的openssl版本在1.0.x以下,网络上还有一种处理方式就是设置一个回调,具体参考网络文章                         

针对第一种,就是效率问题,如果加一把大锁,我为何还用多线程处理http或https消息,交给一个线程做就可以了,但是我们一般不会这么干;第二种就是我们今天要说明的问题,必须编译openssl1.1.x以上依赖库。

好了,不如正题,开始介绍两个版本的openssl编译和libcurl编译:                                                                                                

一、静态编译(openssl1.0.2o)

1. 编译zlib
            (1)优先把找到Makefile.msc的CFLAGS  = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)这一行,改为MD改为MT

(2)使用VS2008 的 Command Prompt命令提示符工具(当然可以为任意你安装的开发环境命令行提示符工具

(3)cd到zlib的根目录,使用命令编译

nmake -f win32/Makefile.msc OBJA="inffast.obj"

扩展:编译64位
           (1)进入“Visual Studio 2015 x64 兼容工具命令提示”

(2)在打开的vs 的x64环境命令中,进入zlib库,执行如下
 

contrib\masmx64\bld_ml64.bat

最终在zlib根目录生成对应头文件和lib静态库文件。

2. 编译openssl
           (1)安装ActivePerl;
           (2)使用VS2008 的 Command Prompt命令提示符工具,cd到openssl的根目录,依次执行

(3)执行如下命令

perl Configure VC-WIN32 no-asm 

这里说明:必须加no-asm,不然nmake报错:tmp32\sha1-586.asm(1427) : error A2070:invalid instruction operands

(4)执行如下命令

ms\do_ms.bat 

此时在ms目录下会生成nt.mak文件

(5)修改nt.make中的CFLAG 为 /MT,即静态库(动态为/MD)

(6) 执行如下指令

make -f ms\nt.mak

最终生成的库文件生成在openssl根目录的out32下。

如果要继续编译,或重新编译64位的,则先做如下清理

nmake -f ms\nt.mak clean

64静态库编译步骤
           (1)执行perl Configure VC-WIN64A no-asm
           (2)执行ms\do_win64a.bat
           (3)修改ms\nt.mak编译选项为静态库MT(动态库MD)
            (4)执行nmake -f ms\nt.mak

输出在out32下面(为了区别32bit输出,请先将32bit编译out32更改为其他名称,然后在编译64位,最后将编出来的out32改为out64。

3. 编译libcurl
         

(1)zlib和openssl文件拷贝

进入libcurl目录,projects\Windows\VC9目录下新建一个文件夹例如:addfiles,并创建子目录:include,lib,并将zlib.h拷贝至include目录在include下新建子目录openssl, 将openssl.lib依赖的头文件全部拷贝至openssl目录下;将zlib.lib, ssleay32.lib, libeay32.lib拷贝到addfiles\lib目录下。

(2)编译libcurl

进入libcurl的根目录,然后进入projects\Windows\VC9目录,直接用VS2008打开工程,在菜单栏选择LIB Release - LIB OpenSSL,Win32,在工程属性中设置如下:

在libcurl属性页,C/C++ / General /additional include Directories, 添加头文件目录..\addfiles\include

在libcurl属性页,Librarian / General /additional dependencies, 添加libeay32.lib, ssleay32.lib, zlib.lib

在libcurl属性页,Librarian / General /additional library Directories, 添加目录..\addfiles\lib

(3)编译libcurl

编译玩libcurl,最终libcurl库会生成到对应目录,win64类似

 

二、静态编译(openssl1.1.0h)
           1. 编译zlib

(1)修改编译选项

优先把找到Makefile.msc的CFLAGS  = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)这一行,改为MD改为MT

(2)执行命令

使用VS2008 的 Command Prompt命令提示符工具,cd到zlib的根目录,使用命令编译

nmake -f win32/Makefile.msc OBJA="inffast.obj" 

2. 编译openssl
            (1)安装ActivePerl;

(2)静态编译

使用VS2008 的 Command Prompt命令提示符工具,cd到openssl的根目录,依次执行:

perl Configure VC-WIN32  shared no-asm no-shared --prefix="C:/openssl_lib/win32-release" --openssldir="C:/openssl_lib/win32-release/ssl" 

 注意:务必加入no-shared选项,表示只编译生成libcrypto.lib和libssl.lib,否则编译完成后的测试会失败。

(3)开始编译测试和安装


             编译:nmake

测试:nmake test(查验全部测试成功)

安装:nmake install(编译好的文件将会出现在win32-release中)

注意:(1)命令nmake clean可以清理清除编译Openssl-1.1.0f时产生的相关文件,不会清除C:/openssl-1.1.0f/win32-release目录下编译好的Openssl

 (2)64位编译需要设置为perl Configure VC-WIN64A 或 perl Configure debug-VC-WIN64A

 (3)如果上一次编译完成,下一次编译需要清理上一次编译结果然后在重新编译,清理指令:nmake clean

3. 编译libcurl
            (1)文件拷贝

projects\Windows\VC9目录下新建一个文件夹例如:addfiles,并创建子目录:include,lib,将zlib.h拷贝至include目录,在include下新建子目录openssl, 将openssl.lib依赖的头文件全部拷贝至openssl目录下,将zlib.lib, 添加libcrypto.lib, libssl.lib拷贝到addfiles\lib目录下。

(2)编译

进入libcurl的根目录,然后进入projects\Windows\VC9目录,直接用VS2008打开工程,在菜单栏选择LIB Release - LIB OpenSSL,Win32,设置编译选项如下:

在libcurl属性页,C/C++ / General /additional include Directories, 添加头文件目录..\addfiles\include
在libcurl属性页,Librarian / General /additional dependencies, 添加libcrypto.lib, libssl.lib, zlib.lib
在libcurl属性页,Librarian / General /additional library Directories, 添加目录..\addfiles\lib

最后编译生成libcurl静态库即可。

4、重点问题注意

(1)项目中调用openssl时,必须添加一个密码学库:crypt32;

#pragma comment (lib, "crypt32")


              原因:openssl库使用了windows的一个密码学库: crypt32。否则报错

1>libcrypto.lib(e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertFreeCertificateContext@4  
1>libcrypto.lib(e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertGetCertificateContextProperty@16  
1>libcrypto.lib(e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertOpenStore@20  
1>libcrypto.lib(e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertFindCertificateInStore@24  
1>libcrypto.lib(e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertEnumCertificatesInStore@8  
1>libcrypto.lib(e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertCloseStore@8  
1>libcrypto.lib(e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertDuplicateCertificateContext@4  
1>D:\code\opensslbaseapp\Release\PosCipherTest.exe : fatal error LNK1120: 7 个无法解析的外部命令  
1>  

猜你喜欢

转载自blog.csdn.net/lixiang987654321/article/details/81154613