Windows下编译libevent

用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
        └─event2

2.使用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



你可能感兴趣的:(开发环境配置)