用cmake在windows下编译libevent很简单,但是Github上通过release下载的没有包含cmake脚本
GitHub地址:https://github.com/libevent/libevent/releases
1.在GitHub上下载源码,我方才下载的是libevent-2.1.8-stable
libevent-2.1.8-stable:
├─compat
│ └─sys
├─include
│ └─event2
├─m4
├─sample
├─test
└─WIN32-Code
└─nmake
└─event22.使用nmake命令编译
我们发现源码根目录下有个文件叫“Makefile.nmake”,这是对应微软编译器nmake的脚本,和GCC的makefile一样的功能。
然后我们在开始菜单找到“适用于 VS 2017 的 x64 本机工具命令提示”(这里需要安装了Visual Studio)
在源码根路径下执行命令:
nmake /f Makefile.nmake得到编译日志输出:
cl /IWIN32-Code /IWIN32-Code/nmake /Iinclude /Icompat /DHAVE_CONFIG_H /I. /Ox /W3 /wd4996 /nologo /c event.c buffer.c bufferevent.c bufferevent_sock.c bufferevent_pair.c listener.c evmap.c log.c evutil.c strlcpy.c signal.c bufferevent_filter.c evthread.c bufferevent_ratelim.c evutil_rand.c evutil_time.c win32select.c evthread_win32.c buffer_iocp.c event_iocp.c bufferevent_async.c
event.c
buffer.c
buffer.c(3107): warning C4244: “函数”: 从“__int64”转换到“unsigned int”,可能丢失数据
bufferevent.c
bufferevent_sock.c
bufferevent_sock.c(267): warning C4244: “函数”: 从“intptr_t”转换到“int”,可能丢失数据
bufferevent_pair.c
listener.c
evmap.c
log.c
evutil.c
strlcpy.c
signal.c
bufferevent_filter.c
evthread.c
bufferevent_ratelim.c
evutil_rand.c
evutil_time.c
evutil_time.c(537): warning C4244: “=”: 从“__int64”转换到“long”,可能丢失数据
evutil_time.c(542): warning C4244: “=”: 从“time_t”转换到“long”,可能丢失数据
win32select.c
evthread_win32.c
buffer_iocp.c
event_iocp.c
正在生成代码...
正在编译...
bufferevent_async.c
正在生成代码...
lib /nologo event.obj buffer.obj bufferevent.obj bufferevent_sock.obj bufferevent_pair.obj listener.obj evmap.obj log.obj evutil.obj strlcpy.obj signal.obj bufferevent_filter.obj evthread.obj bufferevent_ratelim.obj evutil_rand.obj evutil_time.obj win32select.obj evthread_win32.obj buffer_iocp.obj event_iocp.obj bufferevent_async.obj /out:libevent_core.lib
cl /IWIN32-Code /IWIN32-Code/nmake /Iinclude /Icompat /DHAVE_CONFIG_H /I. /Ox /W3 /wd4996 /nologo /c event_tagging.c http.c evdns.c evrpc.c
event_tagging.c
http.c
evdns.c
evrpc.c
正在生成代码...
lib /nologo event_tagging.obj http.obj evdns.obj evrpc.obj /out:libevent_extras.lib
lib /nologo event.obj buffer.obj bufferevent.obj bufferevent_sock.obj bufferevent_pair.obj listener.obj evmap.obj log.obj evutil.obj strlcpy.obj signal.obj bufferevent_filter.obj evthread.obj bufferevent_ratelim.obj evutil_rand.obj evutil_time.obj event_tagging.obj http.obj evdns.obj evrpc.obj win32select.obj evthread_win32.obj buffer_iocp.obj event_iocp.obj bufferevent_async.obj /out:libevent.lib
cd test
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\HostX64\x64\nmake.exe" /F Makefile.nmake回到libevent的源码根目录,我们发现已经有了3个目的输出库文件
libevent.lib
libevent_core.lib
libevent_extras.lib到这里源码编译是成功的,已经得到了需要的3个libevent库,这个和在linux下或者CMake工具编译得到的库完全一致。但是在界面上还能看见几行报错日志:
NMAKE : fatal error U1073: 不知道如何生成“print-winsock-errors.obj”
Stop.
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\HostX64\x64\nmake.exe"”: 返回代码“0x2”
Stop.回去阅读编译脚本文件Makefile.nmake,我们分析一下编译什么的时候出错了
# WATCH OUT! This makefile is a work in progress. -*- makefile -*-
#
# I'm not very knowledgeable about MSVC and nmake beyond their most basic
# aspects. If anything here looks wrong to you, please let me know.
# If OPENSSL_DIR is not set, builds without OpenSSL support. If you want
# OpenSSL support, you can set the OPENSSL_DIR variable to where you
# installed OpenSSL. This can be done in the environment:
# set OPENSSL_DIR=c:\openssl
# Or on the nmake command line:
# nmake OPENSSL_DIR=C:\openssl -f Makefile.nmake
# Or by uncommenting the following line here in the makefile...
# OPENSSL_DIR=c:\openssl
!IFDEF OPENSSL_DIR
SSL_CFLAGS=/I$(OPENSSL_DIR)\include /DEVENT__HAVE_OPENSSL
!ELSE
SSL_CFLAGS=
!ENDIF
# 这里上方5行脚本,定义了要不要编译支持ssl的libevent的条件,以用于下面的 CFLAGS
# Needed for correctness
CFLAGS=/IWIN32-Code /IWIN32-Code/nmake /Iinclude /Icompat /DHAVE_CONFIG_H /I. $(SSL_CFLAGS)
# For optimization and warnings
CFLAGS=$(CFLAGS) /Ox /W3 /wd4996 /nologo
# XXXX have a debug mode
LIBFLAGS=/nologo
CORE_OBJS=event.obj buffer.obj bufferevent.obj bufferevent_sock.obj \
bufferevent_pair.obj listener.obj evmap.obj log.obj evutil.obj \
strlcpy.obj signal.obj bufferevent_filter.obj evthread.obj \
bufferevent_ratelim.obj evutil_rand.obj evutil_time.obj
WIN_OBJS=win32select.obj evthread_win32.obj buffer_iocp.obj \
event_iocp.obj bufferevent_async.obj
EXTRA_OBJS=event_tagging.obj http.obj evdns.obj evrpc.obj
!IFDEF OPENSSL_DIR
SSL_OBJS=bufferevent_openssl.obj
SSL_LIBS=libevent_openssl.lib
!ELSE
SSL_OBJS=
SSL_LIBS=
!ENDIF
ALL_OBJS=$(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS) $(SSL_OBJS)
STATIC_LIBS=libevent_core.lib libevent_extras.lib libevent.lib $(SSL_LIBS)
# 这里能看见有2个大的编译工程,一个用于编译静态库static_libs,一个用于编译测试代码tests
all: static_libs tests
# 从这里开始是静态库的编译脚本
static_libs: $(STATIC_LIBS)
libevent_core.lib: $(CORE_OBJS) $(WIN_OBJS)
lib $(LIBFLAGS) $(CORE_OBJS) $(WIN_OBJS) /out:libevent_core.lib
libevent_extras.lib: $(EXTRA_OBJS)
lib $(LIBFLAGS) $(EXTRA_OBJS) /out:libevent_extras.lib
libevent.lib: $(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS)
lib $(LIBFLAGS) $(CORE_OBJS) $(EXTRA_OBJS) $(WIN_OBJS) /out:libevent.lib
libevent_openssl.lib: $(SSL_OBJS)
lib $(LIBFLAGS) $(SSL_OBJS) /out:libevent_openssl.lib
# 静态库的编译脚本到这里结束,一共有4个编译任务,ssl的不一定执行,取决于上面所述的编译条件
# 这就是为何我上面有3次 “正在生成代码...” 的输出(得到了库文件),一次异常报错的原因(测试报错)
# 下面是清理编译输出的命令,易懂
clean:
del $(ALL_OBJS)
del $(STATIC_LIBS)
cd test
$(MAKE) /F Makefile.nmake clean
cd ..
# 这里是测试代码的编译命令 (就是它导致了最终的报错)
tests:
cd test
!IFDEF OPENSSL_DIR
$(MAKE) OPENSSL_DIR=$(OPENSSL_DIR) /F Makefile.nmake
!ELSE
$(MAKE) /F Makefile.nmake
!ENDIF
cd ..由此我们知道了这个脚本的真正用法:
全量编译:nmake /f Makefile.nmake [all] //all可以省略,默认是all
库编译: nmake /f Makefile.nmake static_libs
测试编译:nmake /f Makefile.nmake tests
清理输出:nmake /f Makefile.nmake clean版权声明:本文为u011507599原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。