Mac 从Makefile 编译 Rocksdb 源码的一些注意事项
文章目录
- 前言
- Makefile 编译流程
- 1. 平台变量/环境变量的初始化。
- 2. 编译需要的源码文件变量初始化。
- 3. include 目录的设置。
- 4. 编译的执行逻辑。
- 问题记录1:可能的打包命令`ar` 失效问题
- 5. 执行具体的编译指令
- 问题记录2: jar 包编译
前言
最近在Mac 本地编译Rocksdb 过程中踩过不少坑,特此做一个记录,希望能帮助到大家。
Rocksdb 源码的本地编译需求来自于 Rocksdb 使用者对本地开发/测试环境的依赖,尤其是Java 开发的同学依赖更强,因为基本的开发和调试在本地的 IDEA 会方便无数倍。而且,RocksJava 的功能也会随着社区版本迭代,所以使用过程中需要编译不同版本的的 Rocksdb 的jar
包。
本地编译原生主要是两种,一种是Makefile
,另一种是CMakeList.txt
,还有一种是bazel
方式,官方也提供了TARGET
文件。当然,用bazel从源码编译可能会更方便一些,符号信息也会更全一些,这里就看大家自己的选择了。
此外, 本篇可能记录的是我遇到的一些坑,但不代表大家就一定能遇到,或者说大家遇到的我不一定能够遇到。所以整体提供的解决方法以及案例可能更偏向于方法论,就是告诉大家实际的编译流程,以及这个过程中的source
文件,include
文件,依赖库 都是在哪里进行初始化的,以及可以在哪里进行补充,这样大家有了整个编译流程之后就能够根据自己的环境快速解决对应的问题。
描述之前,可以先做一些方便大家阅读makefile的准备工作,我这里使用的是ctags + vim。
好处是rocksdb 直接提供ctags的生成目录,在Makefile 所在目录执行命令make ctags -j
就好了。可能需要大家安装cscope命令brew install cscope
有了ctags的辅助,我们就可以在Makefile中自由跳转了。
Makefile 编译流程
1. 平台变量/环境变量的初始化。
Makefile中会有一些类似 $(PLATFORM)
这样的外部变量,Makefile中的逻辑大多是根据这一些外部变量来判断自己的编译行为。比如不同的操作系统 选择不同的编译库/编译逻辑,对系统依赖库的初始化设置。
所有这一些系统变量/环境变量的初始化都在这个文件中:
build_tools/build_detect_platform
像基本的系统库,是否使用fallocate
, snappy
, zstd
等 都是这里面设置的,还有我们编译打包的基础命令$(CC), $(CXX), $(AR)
的初始化也都是在这个文件中。
也就是说make static_lib
这条命令会先通过 上面这个文件进行变量的初始化,而如果我们想要外部改变变量,则指定的ROCKSDB_DISABLE_GFLAGS=1 make static_lib -j
也都是通过这个文件来生效的。
2. 编译需要的源码文件变量初始化。
我们在Makefile 有一些带有SOURCE
的关键字,他们一些保存源码路径的变量,用来编译一些库文件。
这个时候我们通过前面说的ctags 来跳转到声明ctrl + ]
,返回上一个位置ctrl + o
。就能看到这一些初始化的变量是在
src.mk
之中。
也就是大家如果想要补充一些自己修改的源码文件,即可到src.mk
之中添加。
而在Makefile中 src.mk
变量被引入的方式是:
include src.mkAM_DEFAULT_VERBOSITY = 0
如果有对rocksjni 的代码进行修改,则同样需要将对应的代码文件补充到src.mk
中的JNI_NATIVE_SOURCES
变量。
3. include 目录的设置。
我们想要设置一些编译依赖的头文件所在目录,可以在如下集中的一个地方进行设置:
CFLAGS += $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
CXXFLAGS += $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -Woverloaded-virtual -Wnon-virtual-dtor -Wno-missing-field-initializers
也就是说如果大家遇到一些依赖库的问题,即通过-lxxx
这样的方式解决不了的,则可以直自己从源码编译依赖库,在这里指定include 和 .dylib 所在位置就可以。
4. 编译的执行逻辑。
这个其实很简单,有了我们的ctags
,我们很容易梳理出一个大体的执行流。从make static_lib
来看,最终的成果物是一个librocksdb.a
文件。
如上执行目标是static_lib
,则$(LIBRARY)
是实际的${LIBNAME}.a
,也就是我们想要生成librocksdb.a
,那就看$(LIBRARY)作为执行目标的位置。
这里我们就看到了真正生成librocksdb.a
执行目标的位置了,下面的$(AM_V_at)
以及 $(AR)
则是提前初始化好的打包命令,而$(LIBOBJECTS)
则是要求从源码文件.cc
编译成.o
的文件集LIBOBJECTS = $(LIB_SOURCES:.cc=.o)
。
如果再想仔细追溯每一个变量的源头,按照tags 跳转就好了。
问题记录1:可能的打包命令ar
失效问题
提一下,在6.6.0版本以前,on Mac的打包命令可能会失效,因为 on linux 和 on mac 的初始化AR
变量有差异。
所以大家可以在build_tools/build_detect_platform
中增加针对$(AR)
的显式设置,这样不论什么时候$(AR)
变量都是一个有效的子命令。
if test -z "$AR"; thenif [ -x "$(command -v gcc-ar)" ]; thenAR=gcc-arelif [ -x "$(command -v llvm-ar)" ]; thenAR=llvm-arelseAR=arfifi
5. 执行具体的编译指令
编译的时候我们一般会编译一些library或者一些测试工具, 这里简单说明一下编译命令。
- 编译动态库/静态库
make static_lib -j6
或者make shared_lib -j6
,默认不带任何符号信息。
如果想要把符号信息也添加进去来方便调试,则需要设置DEBUG_LEVEL=1 make static_lib
,会以 -O2 的方式进行编译,并将一些测试代码和符号信息也编译到库中。 - 编译rokcsdb 的测试工具:
DEBUG_LEVEL=0 make db_bench
因为工具的运行需要一些依赖库,这里可能需要大家安装对应的依赖库。
gflags
,snappy
,zstd
,zlib
,lz4
等,安装可以直接通过brew install xxx
就可以,而像一些fallocate
或者jemalloc
的依赖问题,如果不想安装,可以通过ROCKSDB_DISABLE_FALLOCATE=1
或者ROCKSDB_DISABLE_JEMALLOC=1
来禁用即可。
编译完成之后,可以通过otool -L db_bench
这样的命令来进行测试。
问题记录2: jar 包编译
编译jar包,建议通过 rocksdbjavastatic 来进行编译,否则一些jni
的代码编译不进去,出来的jar 包无法独立使用,缺少一些jni的符号。
编译java的时候如果本地shell 环境没有设置JAVA_HOME
,则需要单独指定。
- 通过执行
/usr/libexec/java_home
来得到JAVA_HOME
的路径
如果执行失败,则表示没有安装$ /usr/libexec/java_home /Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home
jdk
,需要brew search jdk
并brew install jdk@xxx
安装指定版本的jdk - 通过 rocksdbjavastatic 编译的时候需要 从网络上下载 以及 编译一些压缩算法,这里建议 单独下载好到
Makefile
所在目录。lz4-*.tar.gz . snappy-*.tar.gz . zlib-*.tar.gz . zstd-*.tar.gz . bzip2-*.tar.gz .
- 编译命令则建议通过
ROCKSDB_DISABLE_JEMALLOC=0 DEBUG_LEVEL=0 JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home make rocksdbjavastatic -j6
进行安装。
编译完成之后会在java/target/
目录下生成 jar 包 和 librocksdbjni 的library。ls java/target apidocs rocksdbjni-6.4.6-javadoc.jar classes rocksdbjni-6.4.6-osx.jar librocksdbjni-osx.jnilib rocksdbjni-6.4.6-sources.jar librocksdbjni-osx.jnilib.dSYM test-classes
jar 包的测试,可以通过java/samples/src/main/java/RocksDBSample.java
代码进行测试:
cd java/src
# 1. 编译测试代码
/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home/bin/javac -d . -cp \
../target/rocksdbjni-6.4.6-osx.jar:. ../samples/src/main/java/RocksDBSample.java \
-Xlint:deprecation# 2. 运行测试代码 并指定db-dir
/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home/bin/java -cp \
../target/rocksdbjni-6.4.6-osx.jar:. RocksDBSample db-dir
没有core 且生成db-dir 目录,则表示当前jar
包无异常。
当然,也可以跑一下java的unitest,如果都过了,那也没什么问题。
相关文章:

Java项目:在线考试系统(单选,多选,判断,填空,简答题)(java+Springboot+ssm+mysql+html+maven)
源码获取:博客首页 "资源" 里下载! 功能: 学生信息 班级 专业 学号 姓名 在线考试 成绩查询 个人信息 密码修改 教师管理 教师编号 姓名 所教科目 题库管理 单选题 多选题 填空题 判断题,简答题(人工…

看了极光推送技术原理的几点思考
看了极光推送技术原理的几点思考 分类: android2012-11-26 20:50 16586人阅读 评论(18) 收藏 举报目录(?)[] 移动互联网应用现状 因为手机平台本身、电量、网络流量的限制,移动互联网应用在设计上跟传统 PC 上的应用很大不一样,需要根据手机…

查询远程或本地计算机的登录账户
用下面这个函数能获取远程或本地电脑的当前登录用户,同时附加了它的计算机名,所以当你查询多台电脑时将知道结果从哪里来。function Get-LoggedOnUser {param([String[]]$ComputerName $env:COMPUTERNAME)$ComputerName | ForEach-Object {(quser /SERV…

LIS ZOJ - 4028
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode4028 memset超时 这题竟然是一个差分约束 好吧呢 对于每一个a[i], l < a[i] < r 那么设一个源点s 使 l < a[i] - s < r 是不是就能建边了 然后对于每一个f[i] 如果前面有一个相等的f[j] 则肯定 a[i…

存储引擎 K/V 分离下的index回写问题
前言 近期在做on nvme hash引擎相关的事情,对于非全序的数据集的存储需求,相比于我们传统的LSM或者B-tree的数据结构来说 能够减少很多维护全序上的计算/存储资源。当然我们要保证hash场景下的高写入能力,append-only 还是比较友好的选择。 …

经典贪心法:时间序列问题及其全局最优性证明
贪心算法是指在对问题求解时,总做出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解。一旦贪心算法求出了一个可行解,就要确定这个算法是否找到了最优解。为此,要么证…

Java项目:在线水果商城系统(java+JSP+Spring+SpringMVC +MyBatis+html+mysql)
源码获取:博客首页 "资源" 里下载! 一、项目简述 功能: 区分为管理员用户和普通用户,普通用户:用户注册登录,首页水果展示,商品分类展示,购物车添加,下单&…

曲苑杂坛--收缩数据库文件
很多人在删除大量数据后收缩数据库,却发现没法收缩到预期效果。 由于使用DBCC SHRINKFILE来收缩数据文件时,是针对数据区来收缩,因此可以先使用DBCC SHOWFILESTATS来查看文件中未使用的分区数(TotalExtents-UsedExtents),如果删除…

python字典去重
今天实习的web大表哥说帮我看环境不过前提是要我帮他写个python合并列表的demo,大概思路就是利用zip库进行keys和values的遍历,然后在输出就行key1{name1:小明,name2:小红} key2{小明:[men,20],小红:[women,30]} for k,v in zip(key1.values(),key1.keys()):for i, …

关于 线程模型中经常使用的 __sync_fetch_and_add 原子操作的性能
最近从 kvell 这篇论文中看到一些单机存储引擎的优秀设计,底层存储硬件性能在不远的未来可能不再是主要的性能瓶颈,反而高并发下的CPU可能是软件性能的主要限制。像BPS/AEP/Optane-SSD 等Intel 推出的硬件存储栈已经能够在延时上接近DRAM的量级ÿ…

R 语言爬虫 之 cnblog博文爬取
Cnbolg Crawl a). 加载用到的R包 ##library packages needed in this case library(proto) library(gsubfn) ## Warning in doTryCatch(return(expr), name, parentenv, handler): 无法载入共享目标对象‘/Library/Frameworks/R.framework/Resources/modules//R_X11.so’&#…

Java项目:宿舍管理系统(java+jsp+SSM+Spring+mysql)
源码获取:博客首页 "资源" 里下载! 一、项目简述 功能:包括学生管理,班级管理,宿舍管理,人员信息维 护。维修登记,卫生管理,访客管理等等。 二、项目运行 环境配置&am…

项目管理5大过程组,42个过程一句话讲解
2019独角兽企业重金招聘Python工程师标准>>> 启动过程组:(1)制定项目章程:诞生项目,并为项目经理“正名”;(2)识别干系人:搞清楚谁与项目相关;规划…
Android Q 变更和新特性
安全和隐私变更 隐私保护是Android Q重要的主题之一,Android Q带来了一系列增强用户隐私保护的变更。 1 应用文件存储空间限制 应用访问限制是Android Q影响最大变更之一。在Android Q系统中,应用只可以通过路径读取自己应用沙箱内的文件,如果…

KVell 单机k/v引擎:用最少的CPU 来调度Nvme的极致性能
文章目录前言KVell背景业界引擎使用Nvme的问题CPU 会是 LSM-kv 存储的瓶颈CPU 也会是 Btree-kv 存储的瓶颈KVell 设计亮点 及 总体架构实现KVell 设计亮点1. Share nothing2. Do not sorted on disk, but keep indexes in memory3. Aim for fewer syscalls , not for sequentia…

android录像增加时间记录(源码里修改)
需要做一个功能,录像和播放时都显示录时的时间,参考文章链接找不到了,不好意思,这里记录一下,防止下次找不到了。另一篇关于源码录像的流程请参考 http://www.verydemo.com/demo_c131_i79000.html 在源码CameraSource.…

Java项目:在线旅游系统(java+jsp+SSM+Spring+mysql+maven)
源码获取:博客首页 "资源" 里下载! 一、项目简述 功能:用户的登录注册,旅游景点的展示,旅游预订,收藏,购买,以及酒店住宿留言等等,后台管理员,订单…

混合式APP开发中中间件方案Rexsee
发现Rexsee时,他已经一年多没有更新过了,最后版本是2012年的。 他的实现思路是通过Android自带的Java - Javascript 桥机制,在WebView中的JavaScript同Java进行通信,而这样的话即Javascript可以直接创建原生UI界面,以获…

vue 前端框架 (三)
VUE 生命周期 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><script type"text/javascript" src"js/vue.js"></script><link rel"stylesheet" type"te…

Rocksdb 的 MergeOperator 简单使用记录
本篇仅仅是一个记录 MergeOperator 的使用方式。 Rocksdb 使用MergeOperator 来代替Update 场景中的读改写操作,即用户的一个Update 操作需要调用rocksdb的 Get Put 接口才能完成。 而这种情况下会引入一些额外的读写放大,对于支持SQL这种update 频繁的…

Java项目:考试系统Java基础Gui(java+Gui)
源码获取:博客首页 "资源" 里下载! 功能简介: 所属课程、题目内容、题目选项、题目答案、题目等级、学生管理、试卷管理、题目管理、时间控制 服务页面: public class ServerClient extends javax.swing.JFrame {/** …

软件工程需求设计说明书
Java即时通聊天程序 设计需求说明书 专业班级: 计本班1202班 项目组成员: 杨宗坤 刘瑞 满亚洲 指导教师: 张利峰 开始日期: 完成日期: 编写目的: 本说明书是在充分理解系统需求分析…

Nagios 安装文档
安装前的装备工作(1)解决安装Nagios的依赖关系:Nagios基本组件的运行依赖于httpd、gcc和gd。可以通过以下命令来检查nagios所依赖的rpm包是否已经安装完成:#yum -y install httpd gcc glibc glibc-common *gd* php php-mysql mysql mysql-server --skip-…

Comprehensive Guide to build a Recommendation Engine from scratch (in Python) / 从0开始搭建推荐系统...
https://www.analyticsvidhya.com/blog/2018/06/comprehensive-guide-recommendation-engine-python/, 一篇详细的入门级的推荐系统的文章,这篇文章内容详实,格式漂亮,推荐给大家. 下面是翻译,翻译关注的是意思&#x…

关于std::string 在 并发场景下 __grow_by_and_replace free was not allocated 的异常问题
使用string时发现了一些坑。 我们知道stl 容器并不是线程安全的,所以在使用它们的过程中往往需要一些同步机制来保证并发场景下的同步更新。 应该踩的坑还是一个不拉的踩了进去,所以还是记录一下吧。 string作为一个容器,随着我们的append 或…

Java项目:银行管理系统+文档Java基础Gui(java+Gui)
源码获取:博客首页 "资源" 里下载! 功能介绍: 登录、打印、取款、改密、转账、查询、挂失、存款、退卡 服务模块: public class atmFrame extends JFrame {private JPanel contentPane;private user user; // private…

ie旋转滤镜Matrix
旋转一个元素算是一个比较常见的需求了吧,在支持CSS3的浏览器中可以使用transform很容易地实现,这里有介绍:http://www.css88.com/archives/2168,这里有演示http://www.css88.com/tool/css3Preview/Transform.html,就不…

音频(3):iPod Library Access Programming Guide:Introduction
NextIntroduction介绍iPod库访问(iPod Library Access)让应用程序可以播放用户的歌曲、有声书、和播客。这个API设计使得基本播放变得非常简单,同时也支持高级的搜索和播放控制功能。iPod library access 通过打开iOS允许的音乐相关的广阔范围…

【2019/4/30】周进度报告
冲刺可以推迟了,但这不妨碍知识储备(另外这周看了看梦断代码,感觉还是很有意思的一本书)。 第七周所花时间约9个小时代码量700多行,主要是阅读代码为主(框架内代码)博客量1篇了解到的知识点 1.y…

关于 智能指针 的线程安全问题
先说结论,智能指针都是非线程安全的。 多线程调度智能指针 这里案例使用的是shared_ptr,其他的unique_ptr或者weak_ptr的结果都是类似的,如下多线程调度代码: #include <memory> #include <thread> #include <v…