Windows下 VS2015编译RocksDB

2023-11-07

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 的相关文章

  • rocksdb的原子flush

    如果始终启用 WAL xff0c 则无需使用原子刷新选项 启用 WAL 后 xff0c 单个 WAL 文件用于捕获对所有列族的写入 因此 xff0c 恢复的数据库 xff08 通过在崩溃 恢复路径中重播 WAL 日志 xff09 保证在所有
  • 【数据库】Redis和RocksDB、levelDB的区别

    区别 Redis 是一个服务 xff0c 独立的进程 xff0c 用户的程序需要与它建立连接才能向它发请求 xff0c 读写数据 RocksDB 和LevelDB 是一个库 xff0c 嵌入在用户的程序中 xff0c 用户程序直接调用接口读
  • std::numeric_limits 出错

    not enough actual parameters for macro max for std numeric limits
  • ubuntu2004/1804安装编译RocksDB

    Linux Ubuntu下载依赖 Upgrade your gcc to version at least 4 8 to get C 11 support Install gflags First try sudo apt get inst
  • RocksDB介绍:一个比LevelDB更彪悍的引擎

    关于LevelDB的资料网上还是比较丰富的 如果你尚未听说过LevelDB 那请稍微预习一下 因为RocksDB实际上是在LevelDB之上做的改进 本文主要侧重在架构上对RocksDB对LevelDB改进的地方做个简单介绍并添加一些个人的
  • 【RocksDB】Ubuntu18.04下编译rocksdb

    最近的新项目是NewSQL 底层存储引擎是rocksdb 于是在Ubuntu下编译了一下 下面是编译过程 首先安装依赖的包以及组件 安装gcc g 及make sudo apt get install build essential 安装g
  • Windows下 VS2015编译RocksDB

    VS2015编译RocksDB RocksDB 是一个来自 facebook 的可嵌入式的支持持久化的 key value 存储系统 也可作为 C S 模式下的存储数据库 但主要目的还是嵌入式 RocksDB 基于 LevelDB 构建 1
  • 【RocksDB】Ubuntu20.04下编译rocksdb

    前言 我在刚学rocksdb的时候是在2022年 但是网上的资源很少 查了好久才把rocksdb安装成功 在这里向大家分享一下我的经历 安装过程中也报了很多错误 希望大家不要迷路 首先 在虚拟机里面安装依赖的包以及组件 总共七个依赖包和组件
  • 读写锁 share_mutex

    实现一个Windows下的共享锁 读写锁 一 作者 tyc611 cublog cn 2008 11 18 在Windows Vista Server 2008之前 Windows没有提供共享锁 通俗称为读写锁 只能靠自己实现 但从Wind
  • CODIS原理 之 数据迁移流程[2.X]

    CODIS原理 之 数据迁移流程 2 X 分类 源码剖析设计思路 1173 0 作者 邹祁峰 邮箱 Qifeng zou job hotmail com 博客 http blog csdn net qifengzou 日期 2016 08
  • Rocksdb 代码学习 写流程1(WriteBatch写,WriterThead调度Writer)

    1 几个需要使用的相关类 1 Slice 主要用来装数据的 就两个成员变量data size 就是用装key和value的值 长度 以及一些处理函数 class Slice public Create an empty slice Slic
  • MariaDB 10.2 和 Openssl 1.1.0e 出现“不完整类型 MD5_CONTEXT”错误

    我无法在 CentOS 7 中构建启用 RocksDB 的 MariaDB 10 2 它有以下编译错误 root mariadb 10 2 mysys ssl my md5 cc In function void md5 result MD
  • Kafka Streams:如何使用 persistenceKeyValueStore 从磁盘重新加载现有消息?

    我的代码当前使用 InMemoryKeyValueStore 这避免了对磁盘或 kafka 的任何持久化 我想使用rocksdb Stores persistentKeyValueStore 以便应用程序将从磁盘重新加载状态 我正在尝试实现
  • Rocksdb.errors.RocksIOError:IO错误:锁定文件时:sample.db/LOCK:资源暂时不可用

    如何删除rocksDB上的锁 我尝试运行以下代码但出现以下错误 Running on http 127 0 0 1 5000 Press CTRL C to quit Restarting with stat Traceback most
  • 将键值数据库与 Spark 集成

    我无法理解 Spark 如何与存储交互 我想创建一个从 RocksDB 数据库 或任何其他键值存储 获取数据的 Spark 集群 然而 此时此刻 我能做的最好的事情就是将整个数据集从数据库获取到每个集群节点的内存中 例如映射到映射中 并从该
  • Apache Flink 检查点卡住

    我们正在运行一个 ListState 介于 300GB 到 400GB 之间的作业 并且有时该列表可能会增加到数千 在我们的用例中 每个项目都必须有自己的 TTL 因此我们使用 S3 上的 RocksDB 后端为此 ListState 的每
  • Kafka Streams - 低级处理器 API - RocksDB TimeToLive(TTL)

    我正在尝试使用低级处理器 API 我正在使用处理器 API 对传入记录进行数据聚合 并将聚合记录写入 RocksDB 但是 我想保留在rocksdb中添加的记录仅在24小时内处于活动状态 24 小时后 记录应被删除 这可以通过更改 ttl
  • RocksDb sst 文件的 GUI 查看器

    我正在与 Kafka 合作 将数据保存到rocksdb 中 现在我想看看 Kafka 创建的数据库键和值 我下载了 FastNoSQL 并尝试但失败了 该文件夹包含 sst 文件 日志文件 当前文件 身份文件 锁定文件 日志文件 清单文件
  • ROCKSDB 由于rocksdb_max_row_locks 无法获取锁

    我尝试将 CSV 加载到 Rocksdb 数据库中 但失败并显示以下错误 Got error 10 Operation aborted Failed to acquire lock due to rocksdb max row locks
  • 我可以将 flink RocksDB 状态后端与本地文件系统一起使用吗?

    我正在探索使用 FlinkrocksDb 状态后端 文档似乎暗示我可以使用常规文件系统 例如 file data flink checkpoints 但代码 javadoc 仅在此处提到 hdfs 或 s3 选项 我想知道是否可以将本地文件

随机推荐

  • Flutter组件 等待圈CircularProgressIndicator

    strokeWidth 用于绘制圆的线条的宽度 backgroundColor 背景颜色 value 如果为非null 则该进度指示器的值为0 0 对应于没有进度 1 0对应于所有进度 valueColor 动画的颜色值 在flutter中
  • sqlilab 20-28a之看不懂的教程

    第二十关 接着上面19关的方法 我这里用正确的账号密码登录后发现页面显示了我的Cookie 立刻联想到Cookie注入 还是一样用Burp进行抓包 通过修改Cookie对上面的猜想进行验证 先构造出 uname admin 之后页面出现报错
  • 【数学】2、排列、组合

    文章目录 一 排列 1 1 田忌赛马 1 2 暴力破解密码 二 组合 2 1 递归实现 2 2 应用 2 2 1 乱序搜索词组 多元文法 2 2 2 抽奖 一 排列 排列的定义 从 n 个不同的元素中取出 m 1 m n 个不同的元素 按照
  • ubuntu 环境下安装FastDFS

    一 安装FastDFS依赖包 下载压缩包 github com happyfish100 libfastcommon archive V1 0 38 tar gz 1 解压缩libfastcommonV1 0 38 tar gz 2 进入到
  • 关于Gradle升级版本侯编译jenkins编译或者本地编译有aar报错

    Direct local aar file dependencies are not supported when building an AAR The resulting AAR would be broken because the
  • 使用Frida过程中,打印[object object]

    方法一 先确认object是什么类型 比如要打印p 先console log p className 查看p是什么 数据类型 要注意可能会打印出undefined 比如byte Java cast 把p强转为对应类型 例如 var Map
  • Nmap功能和参数

    一 Nmap常用功能 主要有以下四项 主机存活探测 端口探测并识别端口所提供服务 主机操作系统识别 漏洞扫描检测 二 端口状态 能够识别六种端口状态 1 open 开放的端口 2 closed 关闭的端口 3 filtered 被过滤的 4
  • 加密所有事物,将数据安全存储在任何地方

    Storing your data is easy Protecting it is hard Our personal information photos documents banking information and more i
  • Java学习笔记(四):内部类

    Java学习笔记 四 内部类 一 局部内部类 二 匿名内部类 三 成员内部类 四 静态内部类 内部类 在一个类的内部定义一个类 可以直接访问外部的全部资源 包括私有成员 一 局部内部类 定义在外部类的局部位置 比如方法 有类名 可以直接访问
  • 时序预测

    时序预测 MATLAB实现时间序列回归之交叉验证及损失函数 目录 时序预测 MATLAB实现时间序列回归之交叉验证及损失函数 基本介绍 程序设计 环境准备 交叉验证 损失函数 模型比较 参考资料 致谢 基本介绍 本文介绍MATLAB实现时间
  • 每次刷脸缴费时就可直接进行扣款结算

    人脸识别支付是一款基于面部识别系统的支付应用 支付时消费者只需要面对自助终端屏幕上的摄像头 系统会获取用户面部信息并将面部信息与支付宝账户关联 通过支付宝账户进行费用支付 整个交易过程十分便捷 首次刷脸支付 在刷脸页面进行面部识别 输入与支
  • 【Linux】进程信号 -- 信号保存与递达

    阻塞信号 信号相关概念 内核中的表示 sigset t 信号集操作函数 sigprocmask sigpending 小实验 观察pending表 信号的捕捉流程 sigaction 1 小实验 如果进程在处理2号信号 那我们继续发送2号信
  • 在VMware上安装Centos操作系统详细教程

    1 下载CentOS 64位镜像 下载CentOS 64位官网 https www centos org download 1 点击CentOS Linux DVD ISO 2 选择任意一个镜像下载 并保存 2 在VMware中创建虚拟机
  • 软件技术文档撰写要求

    作者 龚云卿 2006 5 30 1 针对性 文档编制以前应分清读者对象 按不同的类型 不同层次的读者 决定怎样适应他们的需要 对于面向管理人员和用户的文档 不应像开发文档 面向软件开发人员 那样过多地使用软件 的专业术语 难以避免使用的词
  • php数字取整

    ceil 进一法取整 floor 舍去法取整 round 对浮点数进行四舍五入说明 intval 对变数转成整数型态 echo ceil 4 3 5 echo floor 4 3 4 echo round 3 4 3 echo round
  • java.util.Objects.isNull vs object == null 之Objects类的介绍

    Java7引入了java util Objects类 Objects提供了很多工具类方法 其中包括isNull方法 Java8引入了isNull方法 那么java util Objects isNull 与 object null有何区别
  • Android作业中遇到的各种问题

    1 如何设置Edit View不可输入不可编辑不可点击 eidtex为要设置的文本框的id eidtext setEnabled false 去掉点击时编辑框下面横线 eidtext setFocusable false 不可编辑 eidt
  • antd vue时间选择器(年选择器)

    antd vue时间选择器 年选择器 最近项目中用到了antd vue 项目中的版本是1 5 2版本 在做日期选择器时发现只有日 周 月份选择器 独独缺少年份选择器 如果你的项目也是怕升级对整体影响太多 不妨试试下面这种方式来达到年份选择效
  • 用递归求和:1+2+3+4+....n.

    1 具体代码实现 public class Example2 public static void main String args int n 100 int value add n System out println value pu
  • Windows下 VS2015编译RocksDB

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