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/Homejdk,需要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,如果都過了,那也沒什么問題。
總結
以上是生活随笔為你收集整理的Mac 从Makefile 编译 Rocksdb 源码的一些注意事项的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个用名字取qq网名。
- 下一篇: 存储引擎 K/V 分离下的index回写