Thrift&SSL编程#04#libevent编译篇

关于Thrift和OpenSSL的安全通信,上篇我们描述了zlib的编译方法,本文编译libevent库。

  • 01#编译OpenSSL库;
  • 02#编译Boost库;
  • 03#编译zlib库;
  • 04#编译libevent库
  • 05#编译Thrift库;
  • 06#生成客户端和服务端通信所用的数字证书;
  • 07#编写基于Linux系统的测试代码(单向验证:客户端验证服务端);
  • 08#编写基于Windows系统的测试代码(单向验证:客户端验证服务端);
  • 09#编写基于Linux系统的测试代码(双向验证:客户端验证服务端+服务端验证客户端);
  • 10#编写基于Windows系统的测试代码(双向验证:客户端验证服务端+服务端验证客户端);
  • 11#自定义数字证书的验证策略;

下载libevent

libevent的官方网站列表:
官网网站:https://libevent.org
历史版本:https://libevent.org/old-releases.html

本系列演示用的版本V2.1.12的下载地址如下:
https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz

Windows环境,使用OpenSSL静态库的编译方法

1/4) 下载libevent代码并解压

libevent下载完毕并解压后,如下图所示:

2/4) 修改libevent的CMakeLists.txt文件

因使用OpenSSL静态库编译,而原生CMakeLists.txt文件中缺少对Crypt32.lib的引用,编译时报错。

所以我们先修改CMakeLists.txt文件,增加如下内容:

1
SET(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Crypt32.lib")

3/4) 编译libevent代码

在Windows上我们使用cmake+visual studio 2017编译libevent库,如下命令:

1
2
3
4
5
6
7
8
9
# 编译static+release库,使用如下命令:
cmake -S . -B build -A x64 -DOPENSSL_ROOT_DIR=../openssl-1.1.1w/static -DCMAKE_INSTALL_PREFIX=../build -DEVENT__LIBRARY_TYPE=static
cmake --build build --config Release
cmake --install build --config Release

# 编译shared+release库,使用如下命令:
cmake -S . -B build -A x64 -DOPENSSL_ROOT_DIR=../openssl-1.1.1w/static -DCMAKE_INSTALL_PREFIX=../build -DEVENT__LIBRARY_TYPE=shared
cmake --build build --config Release
cmake --install build --config Release

使用cmake配置,如下图所示:

使用cmake编译,如下图所示:

使用cmake安装,如下图所示:

至此,libevent的static+release版本库已编译完成。我们看下安装后的文件:

使用OpenSSL动态库编译

1/4) 下载libevent代码并解压

libevent下载完毕并解压后,如下图所示:

2/4) 编译libevent代码

在Windows上我们使用cmake+visual studio 2017编译libevent库,如下命令:

1
2
3
4
5
6
7
8
9
# 编译static+release库,使用如下命令:
cmake -S . -B build -A x64 -DOPENSSL_ROOT_DIR=../openssl-1.1.1w/shared -DCMAKE_INSTALL_PREFIX=../build -DEVENT__LIBRARY_TYPE=static
cmake --build build --config Release
cmake --install build --config Release

# 编译shared+release库,使用如下命令:
cmake -S . -B build -A x64 -DOPENSSL_ROOT_DIR=../openssl-1.1.1w/shared -DCMAKE_INSTALL_PREFIX=../build -DEVENT__LIBRARY_TYPE=shared
cmake --build build --config Release
cmake --install build --config Release

使用cmake配置,如下图所示:

使用cmake编译,如下图所示:

使用cmake安装,如下图所示:

至此,libevent的static+release版本库已编译完成。我们看下安装后的文件:

编译中遇到的问题

在使用如下命令使用OpenSSL静态库编译时,会出现“无法解析的外部符号”的错误提示:

1
2
cmake -S . -B build -A x64 -DOPENSSL_ROOT_DIR=../openssl-1.1.1w/static -DCMAKE_INSTALL_PREFIX=../build -DEVENT__LIBRARY_TYPE=static
cmake --build build --config Release

错误信息和错误信息截图如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
libcrypto.lib(e_capi.obj) : error LNK2019: 无法解析的外部符号 __imp_CertOpenStore,该符号在函数 capi_open_store 中被引用 [D:\libevent\libev
ent-2.1.12-stable\build\event_openssl_shared.vcxproj]
libcrypto.lib(e_capi.obj) : error LNK2019: 无法解析的外部符号 __imp_CertCloseStore,该符号在函数 capi_find_key 中被引用 [D:\libevent\libeve
nt-2.1.12-stable\build\event_openssl_shared.vcxproj]
libcrypto.lib(e_capi.obj) : error LNK2019: 无法解析的外部符号 __imp_CertEnumCertificatesInStore,该符号在函数 capi_find_cert 中被引用 [D:\l
ibevent\libevent-2.1.12-stable\build\event_openssl_shared.vcxproj]
libcrypto.lib(e_capi.obj) : error LNK2019: 无法解析的外部符号 __imp_CertFindCertificateInStore,该符号在函数 capi_find_cert 中被引用 [D:\li
bevent\libevent-2.1.12-stable\build\event_openssl_shared.vcxproj]
libcrypto.lib(e_capi.obj) : error LNK2019: 无法解析的外部符号 __imp_CertDuplicateCertificateContext,该符号在函数 capi_load_ssl_client_
cert 中被引用 [D:\libevent\libevent-2.1.12-stable\build\event_openssl_shared.vcxproj]
libcrypto.lib(e_capi.obj) : error LNK2019: 无法解析的外部符号 __imp_CertFreeCertificateContext,该符号在函数 capi_dsa_free 中被引用 [D:\lib
event\libevent-2.1.12-stable\build\event_openssl_shared.vcxproj]
libcrypto.lib(e_capi.obj) : error LNK2019: 无法解析的外部符号 __imp_CertGetCertificateContextProperty,该符号在函数 capi_cert_get_fname
中被引用 [D:\libevent\libevent-2.1.12-stable\build\event_openssl_shared.vcxproj]
D:\libevent\libevent-2.1.12-stable\build\bin\Release\event_openssl.dll : fatal error LNK1120: 7 个无法解析的外部命令 [D:\libevent
\libevent-2.1.12-stable\build\event_openssl_shared.vcxproj]

综上述错误,CertCloseStore、CertOpenStore等函数均来自于Crypt32.lib库,但libevent的CMakeLists.txt文件中并未直接引用该库。

欲解决上述编译问题,需修改libevent的CMakeLists.txt文件,在文件明确引用Crypt32.lib。

第一种修改CMakeLists.txt文件的方法,如下:

如下图所示,我们在libevent的CMakeLists.txt文件中增加如下内容:

1
SET(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Crypt32.lib")

第二种修改CMakeLists.txt文件的方法,如下:

如下图所示,我们在libevent的CMakeLists.txt文件中追加 Crypt32.lib :

使用上述任一方法修改CMakeLists.txt文件后,使用如下命令即可成功编译:

1
2
3
cmake -S . -B build -A x64 -DOPENSSL_ROOT_DIR=../openssl-1.1.1w/static -DCMAKE_INSTALL_PREFIX=../build -DEVENT__LIBRARY_TYPE=static
cmake --build build --config Release
cmake --install build --config Release