VS2015编译levelDB
Leveldb是一个google实现的非常高效的kv数据库,非常适合嵌入到程序中。如果有简单的key-value数据库需求,而又想使用一个数据库服务的话,levelDB是非常合适的。(BerkeleyDB和forestdb也不错)。
本文不适用于VS2013及更低版本。
1、下载level源码
直接使用git克隆一个即可
git clone https://github.com/google/leveldb.git
2、切换到windows分支
进入leveldb目录,执行下面操作
git checkout origin/windows
现在的leveldb版本是1.19但是Windows版本为1.17。
3、源码修改
切换到windows分支后,还需要修改两处地方。
1、修改db/c.cc文件
打开db/c.cc文件,将第八行位置修改如下
#ifndef WIN32
#include <unistd.h>
#endif
2、修改port/port.h文件
在如下代码(17、18行)
#elif defined(LEVELDB_PLATFORM_ANDROID)
# include "port/port_android.h"
后面添加
#elif defined(LEVELDB_PLATFORM_WINDOWS)
# include "port/port_win.h"
3、修改port/port_win.h文件
将第四行的宏定义给注释掉
#define snprintf _snprintf // 注释掉此句
因为VS2015中已经实现了snprintf的定义,所以不需要这个了。
如果不去掉,编译的时候将出现以下错误。
cl -c -nologo -Zc:wchar_t -FS -Zc:strictStrings -Zc:throwingNew -Zi -MDd -GR -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -EHsc -DLEVELDB_PLATFORM_WINDOWS -DOS_WIN -DWIN32 -DWIN64 -DNDEBUG -D_CRT_SECURE_NO_WARNINGS -I. -I.include -IC:Boostincludeoost-1_62 -Fobuildobj @C:UsersoAppDataLocalTemp
m35AF.tmp
port_win.cc
C:Program Files (x86)Windows Kits10include10.0.14393.0ucrtstdio.h(1925): warning C4005: 'snprintf': macro redefinition
D:work_codeDataServices3rdLevelDBport/port_win.h(34): note: see previous definition of 'snprintf'
C:Program Files (x86)Windows Kits10include10.0.14393.0ucrtstdio.h(1927): fatal error C1189: #error: Macro definition of snprintf conflicts with Standard Library function declaration
3、添加Makefile.vc文件
直接拷贝下面的内容,在leveldb目录下创建Makefile.vc文件,粘贴过去。
注意,需要修改下面INCPATH和LIBS两处,需要修改为正确的boost库路径。
下面的SOURCES中的.dbdb_bench.cc、.util estutil.cc、.utilwin_logger.cc
以及OBJECTS中的$(OBJECTS_DIR)db_bench.obj、$(OBJECTS_DIR) estutil.obj、$(OBJECTS_DIR)win_logger.obj实际上是不需要的,可以移除。但是放在这里也没有什么关系,可以留着。
如果需要启用Snappy压缩,那么还需要在DEFINES处添加-DSNAPPY,同时还需要在INCPATH和LIBS处指定libsnappy的include和库文件路径。
#############################################################################
MAKEFILE = Makefile
####### 编译器,工具和选项设置
CC = cl
CXX = cl
DEFINES = -DLEVELDB_PLATFORM_WINDOWS -DOS_WIN -DWIN32 -DWIN64 -DNDEBUG -D_CRT_SECURE_NO_WARNINGS
# 如果需要编译debug版本,只需要将上面的 -DNDEBUG 去掉即可
CXXFLAGS = -nologo -Zc:wchar_t -FS -Zc:strictStrings -Zc:throwingNew
-Zi -MT -O2 -GR -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577
-EHsc $(DEFINES)
# 如果需要编译debug版本,可以将上面的 -O2 去掉,-W3改为-W1
# -MT表示使用运行时库的多线程静态版本,可以根据需要改为-MTd/-MD/-MDd
INCPATH = -I. -I.include -IC:Boostincludeoost-1_62
LINKER = lib
# 如果要生成dll,上面的改为 link
LFLAGS = /NOLOGO /MACHINE:X64
# 如果要生成32位版本,上的X64改为X86
# 如果是生成dll,上面还应该添加 /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /DLL /SUBSYSTEM:WINDOWS /MANIFEST:embed
LIBS = /LIBPATH:C:Boostlib64-msvc-14.0
IDC = idc
IDL = midl
ZIP = zip -r -9
COPY = copy /y
COPY_FILE = copy /y
COPY_DIR = xcopy /s /q /y /i
DEL_FILE = del
DEL_DIR = rmdir
MOVE = move
CHK_DIR_EXISTS= if not exist
MKDIR = mkdir
INSTALL_FILE = copy /y
INSTALL_PROGRAM = copy /y
INSTALL_DIR = xcopy /s /q /y /i
####### 输出目录设置
OBJECTS_DIR = buildobj
####### 文件列表
SOURCES = .dbuilder.cc
.dbc.cc
.dbdbformat.cc
.dbdb_bench.cc
.dbdb_impl.cc
.dbdb_iter.cc
.dbfilename.cc
.dblog_reader.cc
.dblog_writer.cc
.dbmemtable.cc
.db
epair.cc
.db able_cache.cc
.dbversion_edit.cc
.dbversion_set.cc
.dbwrite_batch.cc
.portport_win.cc
. ablelock.cc
. ablelock_builder.cc
. ableformat.cc
. ableiterator.cc
. ablemerger.cc
. able able.cc
. able able_builder.cc
. able wo_level_iterator.cc
.utilarena.cc
.utilcache.cc
.utilcoding.cc
.utilcomparator.cc
.utilcrc32c.cc
.utilenv.cc
.utilenv_boost.cc
.utilhash.cc
.utilhistogram.cc
.utillogging.cc
.utiloptions.cc
.utilstatus.cc
.util estutil.cc
.utilwin_logger.cc
OBJECTS = $(OBJECTS_DIR)uilder.obj
$(OBJECTS_DIR)c.obj
$(OBJECTS_DIR)dbformat.obj
$(OBJECTS_DIR)db_bench.obj
$(OBJECTS_DIR)db_impl.obj
$(OBJECTS_DIR)db_iter.obj
$(OBJECTS_DIR)filename.obj
$(OBJECTS_DIR)log_reader.obj
$(OBJECTS_DIR)log_writer.obj
$(OBJECTS_DIR)memtable.obj
$(OBJECTS_DIR)
epair.obj
$(OBJECTS_DIR) able_cache.obj
$(OBJECTS_DIR)version_edit.obj
$(OBJECTS_DIR)version_set.obj
$(OBJECTS_DIR)write_batch.obj
$(OBJECTS_DIR)port_win.obj
$(OBJECTS_DIR)lock.obj
$(OBJECTS_DIR)lock_builder.obj
$(OBJECTS_DIR)format.obj
$(OBJECTS_DIR)iterator.obj
$(OBJECTS_DIR)merger.obj
$(OBJECTS_DIR) able.obj
$(OBJECTS_DIR) able_builder.obj
$(OBJECTS_DIR) wo_level_iterator.obj
$(OBJECTS_DIR)arena.obj
$(OBJECTS_DIR)cache.obj
$(OBJECTS_DIR)coding.obj
$(OBJECTS_DIR)comparator.obj
$(OBJECTS_DIR)crc32c.obj
$(OBJECTS_DIR)env.obj
$(OBJECTS_DIR)env_boost.obj
$(OBJECTS_DIR)hash.obj
$(OBJECTS_DIR)histogram.obj
$(OBJECTS_DIR)logging.obj
$(OBJECTS_DIR)options.obj
$(OBJECTS_DIR)status.obj
$(OBJECTS_DIR) estutil.obj
$(OBJECTS_DIR)win_logger.obj
DESTDIR = build
TARGET = leveldb.lib
DESTDIR_TARGET = buildleveldb.lib
####### 隐式规则
.SUFFIXES: .c .cpp .cc .cxx
## util目录
{.util}.cc{buildobj}.obj::
$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR) @<<
$<
<<
## table目录
{. able}.cc{buildobj}.obj::
$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR) @<<
$<
<<
## port目录
{.port}.cc{buildobj}.obj::
$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR) @<<
$<
<<
## doc目录
{.doc}.cc{buildobj}.obj::
$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR) @<<
$<
<<
## helpers目录
{.helpers}.cc{buildobj}.obj::
$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR) @<<
$<
<<
## db目录
{.db}.cc{buildobj}.obj::
$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR) @<<
$<
<<
####### 构建规则
first: all
all: $(DESTDIR_TARGET)
$(DESTDIR_TARGET): $(OBJECTS) FORCE
$(LINKER) $(LFLAGS) /OUT:$(DESTDIR_TARGET) @<<
$(OBJECTS) $(LIBS)
<<
clean:
$(DEL_FILE) /q $(OBJECTS)
$(DEL_FILE) /q $(DESTDIR_TARGET)
$(DEL_DIR) /s /q $(DESTDIR)
install:
uninstall:
check: first
# 因为windows下的mkdir没有-p参数,所以必须先判断目录是否存在
FORCE:
if not exist $(DESTDIR) $(MKDIR) $(DESTDIR)
if not exist $(OBJECTS_DIR) $(MKDIR) $(OBJECTS_DIR)
4、编译
打开VS 2015 开发人员命令提示工具,切换到leveldb目录。
执行下面操作
nmake -f Makefile.vc
如果没包错误的话,编译完成后会在build目录下生成leveldb.lib文件。
因为leveldb没有使用__declspec(dllexport)导出接口,所以这里如果改为生成动态库,不会生成.lib文件。