Windows下 VS2015編譯levelDB(nmake)


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:\Boost\include\boost-1_62 -Fobuild\obj\ @C:\Users\o\AppData\Local\Temp\nm35AF.tmp
port_win.cc
C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\ucrt\stdio.h(1925): warning C4005: 'snprintf': macro redefinition
D:\work_code\DataServices\3rd\LevelDB\port/port_win.h(34): note: see previous definition of 'snprintf'
C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\ucrt\stdio.h(1927): fatal error C1189: #error:  Macro definition of snprintf conflicts with Standard Library function declaration

3、添加Makefile.vc文件

直接拷貝下面的內容,在leveldb目錄下創建Makefile.vc文件,粘貼過去。

注意,需要修改下面INCPATHLIBS兩處,需要修改為正確的boost庫路徑。

下面的SOURCES中的.\db\db_bench.cc.\util\testutil.cc.\util\win_logger.cc
以及OBJECTS中的$(OBJECTS_DIR)\db_bench.obj$(OBJECTS_DIR)\testutil.obj$(OBJECTS_DIR)\win_logger.obj實際上是不需要的,可以移除。但是放在這里也沒有什么關系,可以留着。

如果需要啟用Snappy壓縮,那么還需要在DEFINES處添加-DSNAPPY,同時還需要在INCPATHLIBS處指定libsnappyinclude和庫文件路徑。

#############################################################################

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:\Boost\include\boost-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:\Boost\lib64-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   = build\obj

####### 文件列表
SOURCES		= 	.\db\builder.cc \
				.\db\c.cc \
				.\db\dbformat.cc \
				.\db\db_bench.cc \
				.\db\db_impl.cc \
				.\db\db_iter.cc \
				.\db\filename.cc \
				.\db\log_reader.cc \
				.\db\log_writer.cc \
				.\db\memtable.cc \
				.\db\repair.cc \
				.\db\table_cache.cc \
				.\db\version_edit.cc \
				.\db\version_set.cc \
				.\db\write_batch.cc \
				.\port\port_win.cc \
				.\table\block.cc \
				.\table\block_builder.cc \
				.\table\format.cc \
				.\table\iterator.cc \
				.\table\merger.cc \
				.\table\table.cc \
				.\table\table_builder.cc \
				.\table\two_level_iterator.cc \
				.\util\arena.cc \
				.\util\cache.cc \
				.\util\coding.cc \
				.\util\comparator.cc \
				.\util\crc32c.cc \
				.\util\env.cc \
				.\util\env_boost.cc \
				.\util\hash.cc \
				.\util\histogram.cc \
				.\util\logging.cc \
				.\util\options.cc \
				.\util\status.cc \
				.\util\testutil.cc \
				.\util\win_logger.cc \

OBJECTS		=	$(OBJECTS_DIR)\builder.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)\repair.obj \
				$(OBJECTS_DIR)\table_cache.obj \
				$(OBJECTS_DIR)\version_edit.obj \
				$(OBJECTS_DIR)\version_set.obj \
				$(OBJECTS_DIR)\write_batch.obj \
				$(OBJECTS_DIR)\port_win.obj \
				$(OBJECTS_DIR)\block.obj \
				$(OBJECTS_DIR)\block_builder.obj \
				$(OBJECTS_DIR)\format.obj \
				$(OBJECTS_DIR)\iterator.obj \
				$(OBJECTS_DIR)\merger.obj \
				$(OBJECTS_DIR)\table.obj \
				$(OBJECTS_DIR)\table_builder.obj \
				$(OBJECTS_DIR)\two_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)\testutil.obj \
				$(OBJECTS_DIR)\win_logger.obj \

DESTDIR        = build
TARGET         = leveldb.lib
DESTDIR_TARGET = build\leveldb.lib


####### 隱式規則

.SUFFIXES: .c .cpp .cc .cxx

## util目錄
{.\util}.cc{build\obj\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR)\ @<<
	$<
<<

## table目錄
{.\table}.cc{build\obj\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR)\ @<<
	$<
<<

## port目錄
{.\port}.cc{build\obj\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR)\ @<<
	$<
<<

## doc目錄
{.\doc}.cc{build\obj\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR)\ @<<
	$<
<<

## helpers目錄
{.\helpers}.cc{build\obj\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$(OBJECTS_DIR)\ @<<
	$<
<<

## db目錄
{.\db}.cc{build\obj\}.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文件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM