Windows下 VS2015编译RocksDB

2023-11-07

Windows下 VS2015编译RocksDB

VS2015编译RocksDB

RocksDB 是一个来自 facebook 的可嵌入式的支持持久化的 key-value 存储系统,也可作为 C/S 模式下的存储数据库,但主要目的还是嵌入式。RocksDB 基于 LevelDB 构建。

1、下载rocksdb源码

git clone https://github.com/facebook/rocksdb.git

2、使用CMAKE生成VS工程

打开cmd窗口(最好使用VS2015开发人员命令提示),进入源码目录,执行下面命令

mkdir msvc14    # 创建构建目录
cd msvc14       # 进入构建目录
# 生成VS项目(D:\Libs\rocksdb是编译后安装路径)
cmake -DCMAKE_INSTALL_PREFIX=D:\Libs\rocksdb -G "Visual Studio 14 Win64" ..

实际上rocksdb源码目录中的CMakeList.txt文件中并没有写INSTALL段的内容,所以这里指定安装路径实际是无效的。

3、编译RocksDB

打开VS2015 x64 本机工具命令提示(或VS2015开发人员命令提示)工具,执行下面命令进行编译64位release版本的RocksDB库

msbuild ALL_BUILD.vcproject /p:configuration=release /maxcpucount:8

因为test项目也都编译了,文件较多,所以这里使用了/maxcpucount:8指定使用的CPU核心数。
如果只编译rocksdb(静态)库,可以使用msbuild rocksdblib.vcproject /p:configuration=release命令
编译动态库使用msbuild rocksdb.vcproject /p:configuration=release命令

编译完成后,通过的做法是使用下面命令进行安装

msbuild INSTALL.vcproject /p:configuration=release

但是这里没有生成INSTALL.vcproject,所以这里的安装需要手动进行。
直接拷贝msvc14/Release目录下的rocksdblib.lib文件和源码目录的include目录即可。

4、编译后续

因为编译出来的是动态库,但是实际上RocksDB的代码中比没有使用__declspec(dllexport)导出函数和类接口,所以在使用的时候会遇到类似如下的问题

rocksdb_test.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl rocksdb::ColumnFamilyOptions::ColumnFamilyOptions(void)" (??0ColumnFamilyOptions@rocksdb@@QEAA@XZ),该符号在函数 "public: __cdecl rocksdb::Options::Options(void)" (??0Options@rocksdb@@QEAA@XZ) 中被引用
rocksdb_test.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl rocksdb::DBOptions::DBOptions(void)" (??0DBOptions@rocksdb@@QEAA@XZ),该符号在函数 "public: __cdecl rocksdb::Options::Options(void)" (??0Options@rocksdb@@QEAA@XZ) 中被引用
rocksdb_test.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl rocksdb::ReadOptions::ReadOptions(void)" (??0ReadOptions@rocksdb@@QEAA@XZ),该符号在函数 main 中被引用
rocksdb_test.obj : error LNK2019: 无法解析的外部符号 "public: static class rocksdb::Status __cdecl rocksdb::DB::Open(struct rocksdb::Options const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class rocksdb::DB * *)" (?Open@DB@rocksdb@@SA?AVStatus@2@AEBUOptions@2@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEAPEAV12@@Z),该符号在函数 main 中被引用
rocksdb_test.exe : fatal error LNK1120: 4 个无法解析的外部命令

这里可以打开生成的VS工程,将配置类型改为静态库,然后再生成静态库即可。

生成后即可使用了。但是还会遇到下面的问题

rocksdb.lib(env_win.obj) : error LNK2019: 无法解析的外部符号 __imp_RpcStringFreeA,该符号在函数 "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl rocksdb::Env::GenerateUniqueId(void)" (?GenerateUniqueId@Env@rocksdb@@UEAA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) 中被引用
rocksdb.lib(env_win.obj) : error LNK2019: 无法解析的外部符号 __imp_UuidCreateSequential,该符号在函数 "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl rocksdb::Env::GenerateUniqueId(void)" (?GenerateUniqueId@Env@rocksdb@@UEAA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) 中被引用
rocksdb.lib(env_win.obj) : error LNK2019: 无法解析的外部符号 __imp_UuidToStringA,该符号在函数 "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl rocksdb::Env::GenerateUniqueId(void)" (?GenerateUniqueId@Env@rocksdb@@UEAA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) 中被引用
rocksdb_test.exe : fatal error LNK1120: 3 个无法解析的外部命令

这些函数实际上是在Rpcrt4.lib这个库里面,所以需要链接上才行。可以在使用的时候在代码中添加#pragma comment(lib,"Rpcrt4.lib")来引入。

相关测试代码如下

#include <cassert>  
#include <string>  
#include <iostream>
#include <chrono>

#include "rocksdb/db.h"  

#pragma comment(lib,"Rpcrt4.lib")

#define TEST_FREQUENCY  (10000)

char* randomstr()
{
    static char buf[1024];
    int len = rand() % 768 + 255;
    for (int i = 0; i < len; ++i) {
        buf[i] = 'A' + rand() % 26;
    }
    buf[len] = '\0';
    return buf;
}

int main() 
{
    rocksdb::DB* db;
    rocksdb::Options options;
    options.create_if_missing = true;

    // 打开数据库
    rocksdb::Status status = rocksdb::DB::Open(options, "./testdb", &db);
    assert(status.ok());

    srand(2017);
    std::string k[TEST_FREQUENCY];
    for (int i = 0; i < TEST_FREQUENCY; ++i) {
        k[i] = (randomstr());
    }
    std::string v("壹贰叁肆伍陆柒捌玖拾");
    v.append(v).append(v).append(v).append(v).append(v);

    // 测试添加
    {
        auto start = std::chrono::system_clock::now();
        for (int i = 0; i < TEST_FREQUENCY; ++i) {
            status = db->Put(rocksdb::WriteOptions(), k[i], v);
            assert(status.ok());
        }
        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        std::cout << TEST_FREQUENCY <<"次添加耗时: "
            << double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
            << "秒" << std::endl;
    }
    // 测试获取
    {
        auto start = std::chrono::system_clock::now();
        std::string v2[TEST_FREQUENCY];
        for (int i = 0; i < TEST_FREQUENCY; ++i) {
            status = db->Get(rocksdb::ReadOptions(), k[i], &v2[i]);
            assert(status.ok());
        }
        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        std::cout << TEST_FREQUENCY <<"次获取耗时: "
            << double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
            << "秒" << std::endl;
        // 验证获取结果是否正确
        std::string ss;
        for (int i = 0; i < TEST_FREQUENCY; ++i) {
            if (v2[i] != v) {
                std::cout << "第 " << i << " 个结果不正确" << std::endl;
                std::cout << v2[i] << std::endl;
            }
        }
    }
    // 测试修改
    {
        auto start = std::chrono::system_clock::now();
        v.append(v);
        for (int i = 0; i < TEST_FREQUENCY; ++i) {
            status = db->Put(rocksdb::WriteOptions(), k[i], v);
            assert(status.ok());
        }
        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        std::cout << TEST_FREQUENCY <<"次修改耗时: "
            << double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
            << "秒" << std::endl;
    }

    // 测试删除
    {
        auto start = std::chrono::system_clock::now();
        for (int i = 0; i < TEST_FREQUENCY; ++i) {
            status = db->Delete(rocksdb::WriteOptions(), k[i]);
            assert(status.ok());
        }
        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        std::cout << TEST_FREQUENCY <<"次删除耗时: "
            << double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
            << "秒" << std::endl;
    }
    delete db;
    return 0;
}

编译命令如下:

# Debug版本
cl rocksdb_test.cpp /I ..\..\libs\vs140-x64\rocksdb\include  ..\..\libs\vs140-x64\rocksdb\Debug\rocksdb.lib /MDd /EHsc \
/GF /TP /Zp8 /Od /Gy /W3 /D "OS_WIN" /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "ROCKSDB_LITE" /D "_MBCS" /D "WIN64" /D "NOMINMAX" 

# Release版本
cl rocksdb_test.cpp /I ..\..\libs\vs140-x64\rocksdb\include  ..\..\libs\vs140-x64\rocksdb\Release\rocksdb.lib /MD /EHsc \
/GF /TP /Zp8 /O2 /Gy /W3 /D "OS_WIN" /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "ROCKSDB_LITE" /D "_MBCS" /D "WIN64" /D "NOMINMAX" 

注意上面使用了/Zp8/TP /GF等选项。如果不设置/Zp8(8字节对齐),在运行时候会抛出异常。因为VS编译64位程序的时候,默认就是8字节对齐,而我没有测试32位版本的,所以这里可能不是关键。

后话

Linux下的编译都比较简单,包括LevelDB等,都只需要直接make即可。Linux下编译的时候可能有某些依赖需要安装一下,包括gflagsjemalloclibsnappylibbz2liblz4等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows下 VS2015编译RocksDB 的相关文章

  • 一文彻底搞懂leveldb架构

    leveldb leveldb是一个写性能十分优秀的存储引擎 xff0c 是典型的LSM tree的实现 LSM的核心思想是为了换取最大的写性能而放弃掉部分读性能 那么 xff0c 为什么leveldb写性能高 xff1f 简单来说它就是尽
  • LevelDB源码分析之从Put说起

    之前分享的文章leveldb实现原理分析详细描述了LevelDB的实现原理 xff0c 本文从Put接口来看下leveldb数据写流程的源码实现 LevelDB的读写接口在类DB中定义 xff08 leveldb db h xff09 xf
  • LevelDb 资料整理

    z 2014 08 29 09 46 17 L 124 39 51223 BG57IV3 64 XCL T161676003 K F4029401865 T6 L94 R5 V74 leveldb介绍 http code google co
  • 【数据库】Redis和RocksDB、levelDB的区别

    区别 Redis 是一个服务 xff0c 独立的进程 xff0c 用户的程序需要与它建立连接才能向它发请求 xff0c 读写数据 RocksDB 和LevelDB 是一个库 xff0c 嵌入在用户的程序中 xff0c 用户程序直接调用接口读
  • leveldb源码分析--SSTable之Compaction 详解

    http www cnblogs com KevinT p 3819134 html leveldb源码分析 SSTable之Compaction 对于compaction是leveldb中体量最大的一部分 也应该是最为复杂的部分 为了便于
  • 大数据时代的Tcaplus游戏存储

    大数据时代的Tcaplus游戏存储 shiweizhang 2015 10 27 1 7k浏览 游戏开发数据分析场景 想免费获取内部独家PPT资料库 观看行业大牛直播 点击加入腾讯游戏学院游戏开发行业精英群711501594 摘要 大数据具
  • LevelDb

    LevelDb 之一 初识LevelDb 说起LevelDb也许您不清楚 但是如果作为IT工程师 不知道下面两位大神级别的工程师 那您的领导估计会Hold不住了 Jeff Dean和Sanjay Ghemawat 这两位是Google公司重
  • leveldb官方手册摘录

    本文内容摘自leveldb官方手册 版权归其所有 CHAPTER 1 基本概念 leveldb是一个写性能十分优秀的存储引擎 是典型的LSM树 Log Structured Merge Tree 实现 LSM树的核心思想就是放弃部分读的性能
  • 键值数据库PebblesDB读后感

    键值数据库PebblesDB读后感 在LevelDB RocksDB这种分层思路上 PebblesDB提出了一种减少写放大的思路 下面学习并总结 所述以论文为基础 也有个人 观点 客观论述请看原文 虽然LSM的写放大最近被研究很多 但是就写
  • LevelDB源码阅读-key

    levelDB中的key 前言 在levelDB中有五种不同的key 在正式分析memtable之前我们先介绍一下这5中不同的key user key ParsedInternalKey InternalKey LookupKey Memt
  • leveldb之Compaction操作下之具体实现

    leveldb之Compaction操作下之具体实现 2015 05 17 19 40 438人阅读 评论 0 收藏 举报 分类 leveldb 13 版权声明 本文为博主原创文章 未经博主允许不得转载 目录 由上文可知 合并主要分为三种
  • Windows下 VS2015编译RocksDB

    Windows下 VS2015编译RocksDB VS2015编译RocksDB RocksDB 是一个来自 facebook 的可嵌入式的支持持久化的 key value 存储系统 也可作为 C S 模式下的存储数据库 但主要目的还是嵌入
  • LSM树存储模型

    大规模分布式存储系统 原理解析与架构实战 读书笔记 之前研究了Bitcask存储模型 今天来看看LSM存储模型 两者虽然同属于基于键值的日志型存储模型 但是Bitcask使用哈希表建立索引 而LSM使用跳跃表建立索引 这一差别导致了两个存储
  • vcpkg编译第三方库leveldb

    vcpkg编译leveldb 1 安装vcpkg 使用git命令直接pull vcpkg源码 git clone https github com microsoft vcpkg 2 在vcpkg目录执行bootstrap vcpkg ba
  • 怎样打造一个分布式数据库——rocksDB, raft, mvcc,本质上是为了解决跨数据中心的复制

    怎样打造一个分布式数据库 rocksDB raft mvcc 本质上是为了解决跨数据中心的复制 摘自 http www infoq com cn articles how to build a distributed database ut
  • CODIS原理 之 数据迁移流程[2.X]

    CODIS原理 之 数据迁移流程 2 X 分类 源码剖析设计思路 1173 0 作者 邹祁峰 邮箱 Qifeng zou job hotmail com 博客 http blog csdn net qifengzou 日期 2016 08
  • 从 Bash 或 Python 获取 google Chrome IndexedDB 中的数据

    我的 Google Chrome 中有 LevelDB IndexedDB 文件 该文件位于此文件夹中 home
  • 无法构建 Objective-C 模块“CoreGraphics”

    当我尝试运行任何单元或 UI 测试时 出现以下错误 运行应用程序本身时不会发生 错误信息如下所示 Applications Xcode app Contents Developer Platforms iPhoneSimulator pla
  • C# 是否有一个好的 leveldb 端口? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我希望在我的纯 C 项目中使用 leveldb 我在 google 上搜索了 leveldb 的 C 版本 但没有找到 谁能告诉我在哪里可
  • Scala SBT 和 JNI 库

    我正在编写一个简单的应用程序Scala通过以下方式使用 leveldb 数据库leveldbjni图书馆 我的build sbt文件看起来像这样 name Whatever version 1 0 scalaVersion 2 10 2 l

随机推荐

  • java web 实战开发经典_java web 开发实战经典(一)

    一 jsp三种Scriptlet 脚本小程序 1 定义局部变量 编写语句等 out println str 编写语句 gt 2 定义全局变量 方法和类 虽然此方可以编写类 但不建议使用 我们一般通过JavaBean的形式调用类 public
  • 区块链学术会议/研究团队汇总

    欢迎评论补充 共建区块链学术生态 一 常见区块链文章发布会议 期刊 领域 简称 全称 CCF Level 备注 网络与信息安全 USENIX Security CCF A TIFS CCF A S P CCF A CCS CCF A Jou
  • 开窗函数 OVER(PARTITION BY)函数介绍

    开窗函数 分析函数用于计算基于组的某种聚合值 它和聚合函数的不同之处是 对于每个组返回多行 而聚合函数对于每个组只返回一行 开窗函数指定了分析函数工作的数据窗口大小 这个数据窗口大小可能会随着行的变化而变化 排序 即便值一样 也不会出现重复
  • java与数据库的相关小知识

    1 软编码链接数据库 public class DBManager private Connection con public Connection getCon String driverClass null String jdbcUrl
  • 实现物体的移动--刚体和代码中操控位置移动

    文章目录 实现物体的移动 先让物体有碰撞体积 给物体绑定刚体 实现物体的移动 先让物体有碰撞体积 给物体绑定刚体 其他的属性和使用方法可以到文档里查看 文档真的超级详细 但是光有碰撞规则是不行的 我们要为它加一个刚体 将对应函数绑定好 然后
  • 计算机网络设置中如何删除家庭组,【求助】Windows无法从该家庭组中删除你的计算机...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 echo 服务名称fdPHost 显示名称Function Discovery Provider Host 进程svchost exe echo DEMAND或DISABLED或AUTO 手动
  • 树莓派 安装Arch Linux ARM

    首先 需要一个linux环境 archlinuxarm系统的安装需要用linux环境复制文件 把sd卡或tf卡连接到装有linux环境的电脑上 首先 确定自己树莓派的型号是b 2b 还是3b 选择合适版本 打开终端 并获得超级权限 sudo
  • Sonar Java默认扫描规则

    规则如下 equals should not be used to test the values of Atomic classes equals 方法不应该用在原子类型的数据上 如 AtomicInteger AtomicLong At
  • MCDF实验——Lab4

    在之前的Lab3中 通过一个初具规模的MCDT的验证环境 学习到 验证环境按照隔离的观念 应分为硬件DUT 软件验证环境 和处于信号媒介的接口interface 对于软件验证环境 需要经历建立阶段 build 连接阶段 connect 产生
  • 浅谈项目售前调研

    一 概述 说到软件项目的售前调研工作 可能还得先谈谈售前顾问这个重要的角色 在IT软件行业 售前顾问位于职业金字塔顶端 是项目开发 实施人员与销售人员间的纽带和桥梁 在销售人员眼中 售前顾问扮演的是技术专家的角色 而在项目实施和开发人员眼中
  • 中兴网络设备交换机路由器查看日志命令方法

    描述 中兴网络设备交换机路由器查看日志命令方法 命令 show logfile
  • 小程序如何实现本地去水印

    自媒体时代 很多人都进行伪原创 但是有些视频本身就有水印的 这个时候我们怎么办 很多人都不懂这个方法 所以导致很多人不会使用 一般都是电脑操作 那我们就没有办法了吗 今天介绍的就是小程序如何实现本地去水印 我们也知道FFmpeg命令 去掉视
  • 波形分析软件 android,新版 PicoScope 软件提供更出色的波形分析和功能 – 免费获取!...

    全球领先的 PC 示波器制造商 Pico Technology Ltd 发布了 PicoScope 软件 6 11 7 版 此版本的 PicoScope 可为研发新一代电气和电子技术的工程师 科学家 技术人员和研究人员提供重要的新功能 本文
  • wifi感知---csi技术

    CSI在WiFi研究领域指Channel State Information 也就是通过接收到的WiFi信号来估计WiFi信号的传播信道长什么样子 它表征了一系列影响的综合 例如散射 衰落 能量随着距离的衰减 目前人们可以从CSI里提取到很
  • C#文件读写小案例

    目录 1 驱动器管理类 2 目录管理类 3 文件管理类 4 路径管理类 5 FileStream类读取文件 6 StreamReader类读取文件 7 使用FileStream类写入文件 用FileStream类写入文件可以指定要写入的位置
  • 逐个版本分析鬼火引擎

    这段时间做手游的cocos2dx的学习 和做web开发的项目 感觉很没劲 还是得研究引擎 我看到有个人的博客直接分析鬼火引擎0 1版本 这个方法不错 两万行左右代码 sourceforge里面有各个版本的代码 这样 正好可以循序渐进地进行
  • Maven导包及打包

    Maven是什么 Maven是一个跨平台的项目管理工具 作为Apache组织的一个颇为成功的开源项目 其主要服务于基于Java平台的项目创建 依赖管理和项目信息管理 是一个自动化构建工具 maven是Apache的顶级项目 解释为 专家 内
  • org.springframework.web.bind.annotation 注解详解

    处理request RequestBody RequestHeader RequestMapping RequestParam RequestPart CookieValue PathVariable 传送门 处理response Resp
  • Python算法教程:强连通分量

    强连通分量 strongly connected components SCCs 是一个能让有向路径上所有节点彼此到达的最大子图 Kosaraju的查找强连通分量算法 def strongly connected components gr
  • Windows下 VS2015编译RocksDB

    Windows下 VS2015编译RocksDB VS2015编译RocksDB RocksDB 是一个来自 facebook 的可嵌入式的支持持久化的 key value 存储系统 也可作为 C S 模式下的存储数据库 但主要目的还是嵌入