引言
一直听说Google
的开源项目leveldb
是一个很好的学习C++
的项目,可以学习到C++
、C++命名规范
、数据库知识
、软件开发流程和设计模式
等,简直是一举多得啊。作为学习的第一步,首先得将leveldb
的环境搭建起来啊,但是这些开源工程并不会直接提供一个leveldb
的vs project
给你,不是简单的双击就能用打开工程。事实上在linux
下学习是最好的,但是平时还是在windows
下比较方便,所以还是尝试在vs2015
下面搭建一下学习环境。本文只测试了VS2015
,其他版本的VS
应该大同小异。
VS2015编译levelDB
1.下载leveldb源码
直接使用git
命令从官方clone
一个即可:
git clone https://github.com/google/leveldb.git
使用git branch
查看当前分支和所有分支:
git branch
可以看到有两个分支master
和windows
,由于要在windows下编译,所以切换到windows
分支:
git checkout windows
目录结构如图所示:
其中WINDOWS
文件介绍了如何使用VS
编译leveldb
,但是不完全靠谱。
2.安装boost库
下载编译
由于leveldb
使用了boost库的依赖,所以要去boost官网下载最新版本的boost,我下载的是boost1.67版本源码。下载完成后将其拷贝到想要安装的目录下面(例如我想装在D盘根目录)进行解压,需要自己将源码编译,推荐使用VS
自带的命令行工具编译。如图:
我的boost
存放目录为D:\boost_1_67_0
,所以使用cd
命令进入这个目录,运行bootstrap.bat
命令,会生成若干个文件,其中需要使用的是b2.exe
,这个exe
可以设置很多参数,但是全默认就行了。在命令行输入b2.exe
回车运行,等待快则十几分钟,慢则几个小时的编译。。。最后就会编译成功。
简单运行测试
编译完成后,新建一个简单的VS
控制台工程测试一下boost
库是否能够工作正常。新建一个main.cpp
如下:
#include <boost/scoped_array.hpp>
int main()
{
boost::scoped_array<int> i(new int[2]);
*i.get() = 1;
i[1] = 2;
i.reset(new int[3]);
}
可以看到有错误提示,
因为需要在工程中配置一个boost
的include
和lib
路径,在工程名上右键,打开属性页面:
-
配置属性 -> C/C++ -> 常规 -> 附加包含目录中添加 boost的根目录,我的是
D:\boost_1_67_0
-
配置属性 -> 链接器 -> 常规 -> 附加库目录中添加 boost根目录下的
stage\lib
目录,我的是D:\boost_1_67_0\stage\lib
此时就不用有错误提示了,可以正常编译通过就说明boost
库基本上没问题。
3.创建VS工程
从已有代码创建项目
打开VS,选择 文件 => 新建 => 从现有项目代码创建项目:
要创建的项目类型选择Visual C++
,下一步之后,填入项目文件位置和项目名称:
再下一步,选择 控制台应用程序项目:
最后直接点完成。如果现在直接尝试编译的话会报一堆错误。。。
属性设置
这一步主要是解决include
找不到路径的问题。
先配置
boost
库的路径:和第2步中测试boost
库一样配置。-
配置本项目内的文件夹路径,在配置属性 -> C/C++ -> 常规 -> 附加包含目录中添加:
leveldb
根目录,leveldb
文件夹下的include
文件夹。
- 添加宏:在配置属性 -> C/C++ -> 预处理器-> 预处理器定义中添加LEVELDB_PLATFORM_WINDOWS; OS_WIN两个宏。
修改源码
-
从项目中排除如下文件:
- port/port_android.cc
- port/port_posix.cc
- util/env_posix.cc
- doc/db_bench_tree_db.cc
- doc/db_bench_sqlite3.cc
- db/c_test.c
- *_test.cc
- *_bench.cc
-
修改
port/port.h
文件#elif defined(LEVELDB_PLATFORM_ANDROID) # include "port/port_android.h"
- 修改
db/c.cc
文件
第8行的 #include <unistd.h>
的头文件在windows下是找不到的,可以直接删除,也可以加个宏控制,修改如图:
-
修改
port/port_win.h
文件将第四行的宏定义给注释掉
#define snprintf _snprintf // 注释掉此句
-
添加自己的测试文件
新建
my_test.cpp
文件(后缀可以为cpp
或者cc
),添加代码如下:#include <iostream> #include <cassert> #include <cstdlib> #include <string> // 包含必要的头文件 #include <leveldb/db.h> using namespace std; int main(void) { leveldb::DB *db = nullptr; leveldb::Options options; // 如果数据库不存在就创建 options.create_if_missing = true; // 创建的数据库在 /tmp/testdb leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db); assert(status.ok()); std::string key = "A"; std::string value = "a"; std::string get_value; // 写入 key1 -> value1 leveldb::Status s = db->Put(leveldb::WriteOptions(), key, value); // 写入成功,就读取 key:people 对应的 value if (s.ok()) s = db->Get(leveldb::ReadOptions(), "A", &get_value); // 读取成功就输出 if (s.ok()) cout << get_value << endl; else cout << s.ToString() << endl; delete db; return 0; }
-
看情况而定
第一次操作的时候最后还发生了类似“:error C2039: “int_fast16_t”: 不是“global namespace”的成员 ”的错误,第二次重新创建工程却没有发生。 如果发生了,解决办法是将
port/win/stdint.h
文件替换为VS
安装后自带的文件,我的安装路径是D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\stdint.h
接下来重新编译就可以成功了~ 运行之后可以发现在当前磁盘的根目录有一个tmp
文件夹,里面有一个testdb
文件夹,程序创建的数据库文件都在里面。
接下来就可以开始源码学习之旅啦。
注:从项目中排除的文件大部分都是测试文件,在对代码熟悉的差不多之后可以重新添加回来。