开源库evhtp在windows下编译
Posted kswangxing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开源库evhtp在windows下编译相关的知识,希望对你有一定的参考价值。
工作需要搭建基于C++的http服务,最后选择使用evhtp。在linux下的编译参考readme即可。现在重点来说下windows下的编译过程。
代码git地址:https://github.com/criticalstack/libevhtp
编译准备
- Visual Studio 必须 笔者用的是VS2019
- Libevent2库 必须 git地址:https://github.com/libevent/libevent,libevent的windows版本编译相对简单)
- CMake 必须 网上可下载,如果网上地址太慢。到 这里 下载
- OpenSSL 可选 网上下载,也可以通过源代码编译
- pthreads 可选 VS的插件管理里面安装
- onig(regex 可选 git地址:https://github.com/kkos/oniguruma
说明:图中需要编译的库都会在源代码里面提供,必须具备 1 和 3
编译过程
按照原作者说明,采用cmake + “MSYS Makefiles“ 来进行编译,这种方式我尝试过,没有成功。最终采用”Visual Studio“的方式来编译。
-
打开代码根目录(包含CMakeLists.txt文件),创建build目录
- 通过DOS(或者其他SHELL工具)进入到代码目录,进入build目录
- 执行命令 cmake -DLIBEVENT_INCLUDE_DIR=..packageincludelibevent-2.1.11 -DONIGURUMA_INCLUDE_DIR=..packageincludeoniguruma-6.9.3 ..
- 看到提示显示创建失败,提示缺少 LIBEVENT_THREAD,这是因为libevent库编译windows版本时没有提供出这个库,具体原因未知..
- 转到根目录下的cmake文件夹下,打开options.cmake文件,将”option (EVHTP_DISABLE_EVTHR "Disable evthread support" OFF)“ 这行的 OFF 改为 ON
- 继续执行步骤3代码,会提示一些错误,大概意思就时文件已经被包含过,不过不影响,现在我们查看build目录下,发现已经有了VS的项目文件libevhtp.sln
- 双击打开libevhtp.sln,选择evhtp这个工程进行编译,会提示如下信息:”无法解析的外部符号 __imp_bind,该符号在函数 evhtp_bind_sockaddr 中被引用“等信息,这是由于未配置windows下的WS2_32.Lib库,添加再配置项里添加这个依赖
- 重新编译发现生成发现没有报错,成功生成了evhtp.dll。但这里我发现另外个问题,没有对应的lib生成。
- 查看对应的接口定义,是由EVHTP_EXPORT这个宏导出,这个宏定义在build目录下的include下的config.h的文件中。在windows下,这个宏定义为空。
#ifndef EVHTP_NEED_EXPORT # if (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER || defined __clang__ # define EVHTP_EXPORT __attribute__ ((visibility("default"))) # else # define EVHTP_EXPORT __declspec(dllimport) # endif #else # if (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER || defined __clang__ # define EVHTP_EXPORT # else # define EVHTP_EXPORT __declspec(dllexport) # endif #endif
修改后的config.h开头定义如下,重新定义一个是否导出的宏 EVHTP_NEED_EXPORT,将这宏放到预处理定义里,并删除原来的 EVHTP_EXPORT宏。重新编译后,包含evhtp.lib及evhtp.dll文件
结果测试
新建一个工程,利用evhtp库创建一个http服务器,看是否成功。代码如下:
1 // main.cpp: 主程序入口 2 // 3 #include <iostream> 4 #include "evhtp.h" 5 #include <WinSock2.h> 6 7 evhtp_t* g_htp; 8 9 #define REGISTER_HTP_CB(path, cb, arg) evhtp_set_cb(g_htp, path, cb, arg) 10 11 void HtpCallBack(evhtp_request_t* req, void* a) 12 { 13 std::cout << "recv a command" << std::endl; 14 evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "application/json", 0, 0)); 15 evbuffer_add(req->buffer_out, "hello, evhtp! success.", sizeof("hello, evhtp! success.")); 16 evhtp_send_reply(req, EVHTP_RES_OK); 17 } 18 19 int main(int argc, const char* argv[]) 20 { 21 WSADATA wsaData; 22 WSAStartup(MAKEWORD(1, 1), &wsaData); 23 24 evbase_t* evbase = event_base_new(); 25 g_htp = evhtp_new(evbase, NULL); 26 evhtp_use_threads_wexit(g_htp, NULL, NULL, 16, NULL); 27 28 REGISTER_HTP_CB("/api", HtpCallBack, nullptr); 29 30 evhtp_bind_socket(g_htp, "0.0.0.0", 8080, 1024); 31 32 event_base_loop(evbase, 0); 33 34 WSACleanup(); 35 36 return 0; 37 }
编译后,运行程序。提示 无法定位程序点输入点 evhtp_use_threads_wexit 。查找该函数定义在evhtp.c文件中,不过该函数是否编译由 EVHTP_DISABLE_EVTHR 宏来控制,在上面步骤5里面,我们将这个编译选型设置为ON,所以导致头文件中由接口定义,但是却没有实现。
修改build/include目录下的config文件中将 #define EVHTP_DISABLE_EVTHR代码注释掉,注意可能存在多行。重新编译我们的evhtp库,会提示找不到pthread.h找不到,将VS中NuGet找到pthread的库安装即可。
如果提示timespec重定义错误,在预处理宏中加上 HAVE_STRUCT_TIMESPEC 定义
编译成功运行工程,通过web页面发送请求,成功。通过ProcessExplorer工具查看,程序也是有17个线程。遇到过没编译好,只有一个线程情况。
总结
附上我编译后的源代码地址:https://github.com/kswangxing/evhtp_win
里面包含编译后代码。
编译环境:VS2019 64位
以上是关于开源库evhtp在windows下编译的主要内容,如果未能解决你的问题,请参考以下文章
windows10下编译OpenCC 1.0.5 简繁转换开源库
在Window下编译LibGeotiff(含Libtiff)