背景
最近公司项目需要适配arm64架构机器,特意整了两台arm64架构的CentOS7/8的机器来构建。 x86、x64架构下的应用在arm64下面需要解决各种环境和依赖问题。
环境
Linux internal 4.18.0-147.8.1.el7.aarch64 #1 SMP Wed Apr 15 18:13:44 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux
CentOS Linux release 7.8.2003 (AltArch)
编译
在 Linux - CentOS / RHEL 环境下编译,可以选择安装官方完整的依赖或者只安装自己需要的部分。有什么区别?
环境准备:
- gcc升级到至少7的版本,以获得C 17的支持
获取 RocksDB
代码语言:javascript复制get clone https://github.com/facebook/rocksdb.git
安装插件
这些插件可以选择性安装,你需要哪个,在使用时自行安装,也可以一次性装好。
Install gflags:
代码语言:javascript复制git clone https://github.com/gflags/gflags.git
cd gflags
git checkout v2.0
./configure && make && sudo make install
Install snappy:
代码语言:javascript复制sudo yum install snappy snappy-devel
Install zlib:
代码语言:javascript复制sudo yum install zlib zlib-devel
Install bzip2:
代码语言:javascript复制sudo yum install bzip2 bzip2-devel
Install lz4:
代码语言:javascript复制sudo yum install lz4-devel
Install ASAN (optional for debugging):
代码语言:javascript复制sudo yum install libasan
Install zstandard:
With EPEL:
代码语言:javascript复制sudo yum install libzstd-devel
编译静态库
编译使用make
,如果直接使用make
或 make install
编译出来的会是debug模式的程序,会打印一堆日志。
真正需要是一个RocksDB的静态库librocksdb.a
make static_lib
将编译librocksdb.a,RocksDB静态库。当前是 arm 架构下直接使用 make 是编译出不来的,需要加上跨平台参数PORTABLE=1
cd rocksdb
PORTABLE=1 make static_lib
正常输出日志,截取部分
代码语言:javascript复制GEN util/build_version.cc
GEN util/build_version.cc
CC cache/clock_cache.o
CC cache/lru_cache.o
CC cache/sharded_cache.o
CC db/builder.o
CC db/c.o
CC db/column_family.o
CC db/compacted_db_impl.o
CC db/compaction.o
CC db/compaction_iterator.o
CC db/compaction_job.o
CC db/compaction_picker.o
CC db/compaction_picker_universal.o
CC db/convenience.o
CC db/db_filesnapshot.o
CC db/db_impl.o
CC db/db_impl_compaction_flush.o
查看一下这个库的结构,这些对应上面的的插件,如果少装一个,这里查看就会少一个。
代码语言:javascript复制linux-vdso.so.1 => (0x0000ffff973d0000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000ffff96d40000)
librt.so.1 => /lib64/librt.so.1 (0x0000ffff96d10000)
libsnappy.so.1 => /lib64/libsnappy.so.1 (0x0000ffff96ce0000)
libz.so.1 => /lib64/libz.so.1 (0x0000ffff96ca0000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x0000ffff96c80000)
liblz4.so.1 => /lib64/liblz4.so.1 (0x0000ffff96c50000)
libstdc .so.6 => /lib64/libstdc .so.6 (0x0000ffff96b20000)
libm.so.6 => /lib64/libm.so.6 (0x0000ffff96a60000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000ffff96a20000)
libc.so.6 => /lib64/libc.so.6 (0x0000ffff96890000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff973e0000)
编译 rocksdbjni
命令
代码语言:javascript复制PORTABLE=1 DEBUG_LEVEL=0 make -j8 rocksdbjava
获得: librocksdbjni-linux64.so
代码语言:javascript复制drwxr-xr-x. 3 root root 4.0K 3月 10 10:44 apidocs
drwxr-xr-x. 3 root root 17 3月 10 10:44 classes
-rwxr-xr-x. 1 root root 140M 3月 10 10:45 librocksdbjni-linux64.so
-rw-r--r--. 1 root root 140M 3月 10 10:50 librocksdbjni.tar.gz
-rw-r--r--. 1 root root 49M 3月 10 10:46 rocksdbjni-5.15.10-linux64.jar
drwxr-xr-x. 3 root root 17 3月 10 10:44 test-classes
报错处理
编译 rocksdbjni,执行编译PORTABLE=1 DEBUG_LEVEL=0 make -j8 rocksdbjava
命令报错
jni.h: No such file or directory
修改/etc/profile 或者 ~/.bashrc,添加 :
代码语言:javascript复制export CPATH=$CPATH:$JAVA_HOME/include:$JAVA_HOME/include/linux
export C_INCLUDE_PATH=$C_INCLUDE_PATH:$JAVA_HOME/include:$JAVA_HOME/include/linux
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:$JAVA_HOME/include:$JAVA_HOME/include/linux
精简库文件
编译出来的 librocksdb.a 文件,发现有140兆,业务程序都没这么大,这个整这么大。 由于刚编译出来的 librocksdb.a 库文件,包含 debug信息,需要手动给他瘦身一下,提取关键部分: 先看一段 strip 命令的介绍:
strip 命令从 XCOFF 对象文件里有选择地除去行号信息、重定位信息、调试段、typchk 段、凝视段、文件头以及全部或部分符号表。 一旦您使用该命令,则非常难调试文件的符号;因此,通常应该仅仅在已经调试和測试过的生成模块上使用 strip 命令。使用 strip 命令降低对象文件所需的存储量开销。
查看文件概要
代码语言:javascript复制file librocksdbjni-linux64.so
librocksdbjni-linux64.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=43a90c7ba9000ef6a27ba47ac786b7d00d703d83, not stripped
文件瘦身
代码语言:javascript复制strip librocksdbjni-linux64.so
librocksdbjni-linux64.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=43a90c7ba9000ef6a27ba47ac786b7d00d703d83, stripped
瘦射后,140M的文件就只剩下6M!!!!
总结
在 arm 架构通常是在移动端下面使用的比较多,由于苹果M1架构也是基于arm64上构建,所以带动了一波arm架构的热潮,社区开发者纷纷要求提供arm版本的程序,有M1本的程序员就是任性。当然间接带动了linux arm架构下的应用。
RocksDB静态库 PORTABLE=1 make static_lib
RocksDB的共享库 PORTABLE=1 make shared_lib
RocksDB JNI PORTABLE=1 DEBUG_LEVEL=0 make -j8 rocksdbjava
官方文档
https://github.com/facebook/rocksdb/blob/main/INSTALL.md https://github.com/facebook/rocksdb/wiki