libevent学习笔记之搭建Win10开发环境 一、环境准备 二、编译zlib(数据压缩) 三、编译openssl(加密传输) 四、编译libevent 五、VS 2017 创建基于Libevent的项目

环境/软件名 版本 描述
操作系统 Win10x64
编译工具 VS2017 Community 提供交叉编译环境
https://visualstudio.microsoft.com/zh-hans/vs/community/
perl脚本解释器 ActivePerl-5.24.3.2404-MSWin32-x64-404865.exe 编译openssl用
https://www.perl.org
nasm汇编器 nasm-2.13.03-win64 解压后配置环境变量即可
zlib 1.2.11源码 zlib-1.2.11 用于数据压缩
http://www.zlib.net/
openssl 1.1.1源码 openssl 1.1.1 用于传输传输层安全(TLS)协议(以前称为SSL)
https://www.openssl.org/source/
libevent 2.1.8源码 libevent 2.1.8 https://libevent.org/

libevent官网:libevent官网
版本:2.1.x-stable
github源码地址:github libevent
gitee源码镜像:gitee libevent

可以选择官网下载稳定版本安装包,也可以去GitHub下载最新源码,然后自行编译、安装。本文选择官网下载安装包进行安装。
注意:

  1. gitee源码镜像并非官方维护,可能存在更新不及时情况,不过国内下载速度比较快;
  2. 所有软件工具,也可以到这个网站统一下载:http://www.libevent.net/libevent_1_0.html;
  3. 除了IDE VS2017和Libevent源码,其他工具都是非必须的,可以等到需要用到时,再下载、安装;

二、编译zlib(数据压缩)

1. 运行cmd进入控制台,或编写bat批处理文件

2. 运行vs编译环境

交叉编译控制台:VS 2017的 x64_x86 交叉工具命令提示符(32位版本)

libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

  • 编译32位库版本
    "C:Program Files (x86)Microsoft Visual Studio2017CommunityVCAuxiliaryBuildvcvarsamd64_x86.bat"
  • 编译64位库版本
    "C:Program Files (x86)Microsoft Visual Studio2017CommunityVCAuxiliaryBuildvcvars64.bat"

3. 进入zlib源码目录

$ cd zlib-1.2.11

4. nmake命令编译

$ nmake -f win32/Makefile.msc

以上步骤bat批处理文件(zlib同级目录下,新建build_zlib_VS2017_32.bat):

set VS="H:Program Files (x86)Microsoft Visual Studio2017CommunityVCAuxiliaryBuildvcvarsamd64_x86.bat"
set OUT=H:libeventoutvs2017_32zlib
call %VS%
cd zlib-1.2.11
nmake /f win32Makefile.msc clean
nmake /f win32Makefile.msc
md %OUT%lib
md %OUT%in
md %OUT%include
copy /Y *.lib %OUT%lib
copy /Y *.h %OUT%include
copy /Y *.dll %OUT%in
copy /Y *.exe %OUT%in
pause

注意:VS、OUT的绝对路径,必须与软件所在实际路径一致。我的所有软件安装包(包含解压后的安装包),都放到了同一目录H:libevent。


三、编译openssl(加密传输)

1. 依赖安装

(1)安装perl脚本解释器
下载安装Windows下安装包(如ActivePerl-5.24.3.2404-MSWin32-x64-404865.exe),按提示完整安装即可。

验证方法(控制台打印版本信息):

$ perl -v

如果成功线程版本信息,与安装版本一致,则说明安装成功;否则,安装失败。

(2)安装nasm汇编器
下载完安装包(nasm-2.13.03-win64.zip)后,直接解压,然后加入PATH环境变量。

验证方法(控制台打印版本信息):

$ nasm -v

如果成功线程版本信息,与安装版本一致,则说明安装成功;否则,安装失败。

2. 编译工具:VS2017社区版本安装

下载在线安装器(vs_Community.exe)后,如果无法正常下载、安装,尝试修改网络连接DNS。
首选DNS服务器:114.114.114.114
备选DNS服务器:8.8.8.8

安装选择C++原生开发环境(非C#)

3. 下载openssl 1.1.1源码

openssl 项目源码地址:https://www.openssl.org/source/

4. 编译步骤

(1)进入CMD,或编写.BAT文件

(2)运行VS编译环境(交叉编译工具)
建议管理员权限运行

(3)进入openssl源码目录

$ cd openssl-1.1.1

(4)使用perl生成makefile文件

格式:

perl Configure {VC-WIN32 | VC-WIN64A | VC-WIN64 | VC-CE} --prefix=%OUTPATH%

编译32位程序

perl Configure VC-WIN32

编译64位程序

perl Configure VC-WIN64

指定编译后输出路径
--prefix是编译后输出路径,默认生成到C:Program Files (x86)

(5)nmake编译
编译库源码

$ nmake

编译测试程序

$ nmake test

将编译好的文件,安装到指定目录,默认C:Program Files (x86)OpenSSL,如果是在C盘,运行控制台是需要有管理员权限

以上步骤批处理文件build_openssl_vs2017_32.bat

@echo "开始编译openssl"
set VS="H:Program Files (x86)Microsoft Visual Studio2017CommunityVCAuxiliaryBuildvcvarsamd64_x86.bat"
set OUT=H:libeventoutvs2017_32openssl
call %VS%
H:
cd H:libeventopenssl-1.1.1
perl Configure VC-WIN32 --prefix=%OUT%
nmake clean
nmake
namke install
@echo "编译openssl结束"
pause

注意:VS、OUT路径与软件实际安装路径要一致


四、编译libevent

1. 依赖安装编译

  • 编译工具:VS2017社区版

  • 编译好的openssl
    libevent_openssl.lib库需要,如果不用此库可以不编译openssl

  • 编译好的zlib
    新版本libevent已经和zlib分离,但示例有用到zlib,如果不需要此示例可以不编译zlib

2. 编译步骤

(1)进入CMD,或编写批处理bat文件

(2)运行VS编译环境

(3)进入libevent源码目录

$ cd libevent-master

(4)清理之前的编译

$ nmake /f Makefile.nmake clean

(5)编译libevent
OPENSSL_DIR是openssl库的路径,之前编译openssl时指定

$ nmake /f Makefile.nmake OPENSSL_DIR=H:libeventoutvs2017_32openssl

或者,也可以修改libeventMakefile.nmake文件下的OPENSSL_DIR值,而不用在编译命令选项中指定openssl路径。

通过修改下面这行,指定openssl路径

# OPENSSL_DIR=c:openssl

修改为

OPENSSL_DIR=H:libeventoutvs2017_32openssl

注意:openssl路径(OPENSSL_DIR)必须是实际openssl库路径

(6)编译包含了libevent的库项目和示例项目(libevent est目录下),编译的示例项目由于用了zlib且openssl版本旧,所以会产生问题

3. 编译中出现的问题

(1)示例中的openssl问题
出现的问题

  • 编译错误、会显示找不到openssl的ssleay32.lib和libeay32.lib库
  • 原因: 旧版本的openssl和新版本采用不同库名
  • 解决方案
    打开test目录下的Makefile.nmake,找到
    SSLLIBS=..libeventopenssl.lib $(OPENSSLDIR)liblibeay32.lib $(OPENSSLDIR)libssleay32.lib gdi32.lib User32.lib
    修改为
    SSLLIBS=..libeventopenssl.lib $(OPENSSLDIR)liblibssl.lib $(OPENSSLDIR)liblibcrypto.lib gdi32.lib User32.lib

4. 测试编译结果

运行libevent est egress.exe
如果都显式OK,没有报错,则说明编译成功;否则,编译失败。
如果提示缺少libcrypto-1_1.dll,libssl-1_1.dll这2个文件,就从opensslin目录下拷贝到regress.exe所在路径。


五、VS 2017 创建基于Libevent的项目

1. 新建src目录

为了方便,在编译libevent输出路径./out目录下,新建src文件夹用于存放源码。

libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

2. 新建项目

在src路径下,新建C++控制台项目:first_libevent

3. 删除IDE默认创建的项目源文件

4. 确认编译输出x86程序

因为之前编译的库文件都是基于x86的

libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

5. 不使用预编译头

libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

6.引用相应头文件

#include <event2/event.h>
头文件位置
libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

VS2017 include方法
".."的数量,取决于实际项目工程文件与include文件相对位置关系

libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

7. 设置库所在路径

以lib目录为例,lib目录
libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目
VS 2017配置方法
libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

8. 引用库文件

这里添加了3个库文件 libevent.lib, zlib.lib, ws2_32.lib(Windows自带socket库文件,Windows平台socket程序需要引用)
libevent学习笔记之搭建Win10开发环境
一、环境准备
二、编译zlib(数据压缩)
三、编译openssl(加密传输)
四、编译libevent
五、VS 2017 创建基于Libevent的项目

9. 初始化Windows socket库

如果不进行这一步,运行会产生警告:应用程序没有调用WSAStartup,或者WSAStartup失败。

int main()
{
#ifdef _WIN32
       // 初始化windows自带的socket库
       WSADATA wsa;
       WSAStartup(MAKEWORD(2, 2), &wsa);
#else
       // linux
       // 忽略管道信号,发送数据给自己关闭的socket
       if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
       {
              return 1;
       }
#endif //

...

#ifdef _WIN32
       WSACleanup(); // 清理Windows端socket库
#endif //
    return 0;
}