如何修改src/Makevars以在R包安装时构建rocksdb静态库?
解决R包中集成RocksDB的构建问题
问题背景
你尝试在R包中集成RocksDB,编写了src/Makevars配置,但安装时出现大量编译报错;不过直接在RocksDB源码目录执行make static_lib却能成功构建,说明问题出在R包编译时传递给RocksDB构建的环境变量或Make规则上。
排查核心问题点
原来的Makevars存在几个关键疏漏:
- RocksDB是C项目,你传递的是C语言的
CFLAGS,但应该传递R的C编译标志**CXXFLAGS**,同时必须带上CPICFLAGS(位置无关代码编译标志,R包编译强制要求) - 没有传递R使用的
CXX编译器变量,导致RocksDB可能用系统默认g++编译,和R的编译器版本不一致,引发链接错误 - 缺少部分必要的链接依赖声明,且环境变量传递不完整
修改后的src/Makevars配置
替换成以下内容,每个改动都做了适配:
CXX_STD = CXX11 # 引入RocksDB头文件目录 PKG_CPPFLAGS = -I./rocksdb/include/ # 链接静态库与系统依赖,注意rocksdb静态库放在最前面 PKG_LIBS = rocksdb/librocksdb.a -lbz2 -lz -lzstd -llz4 -lsnappy -lgflags # 明确R包共享库依赖RocksDB静态库 $(SHLIB): rocksdb/librocksdb.a # 构建RocksDB静态库,完全复用R的编译环境变量 rocksdb/librocksdb.a: rocksdb/Makefile CXX="$(CXX)" \ CXXFLAGS="$(CXXFLAGS) $(CPICFLAGS) -DNDEBUG" \ AR="$(AR)" \ RANLIB="$(RANLIB)" \ LDFLAGS="$(LDFLAGS)" \ $(MAKE) --jobs=3 --directory=rocksdb static_lib # 清理规则:同时清理RocksDB和R包的编译产物 clean: $(MAKE) --directory=rocksdb clean rm -f $(SHLIB) *.o
关键改动说明
- 新增
CXX="$(CXX)":让RocksDB使用R当前的C++编译器,避免版本不一致导致的兼容性问题 - 替换
CFLAGS为CXXFLAGS:匹配RocksDB的C++项目属性,传递正确的编译标志 - 新增
-DNDEBUG:和R的默认编译模式对齐,禁用调试信息,缩小编译产物体积 PKG_LIBS添加-lgflags:显式声明gflags依赖,避免链接阶段找不到库- 扩展清理规则:同时清理R包自身的编译产物,保证下次构建环境干净
验证步骤
用你提供的Docker环境测试:
- 启动容器:
docker run --rm -ti rocker/r-ver:latest bash
- 安装系统依赖:
apt-get update apt-get install -y libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev git-core
- 安装R依赖:
install2.r Rcpp checkmate R6 tinytest
- 克隆代码并安装:
cd /tmp git clone https://gitlab.com/artemklevtsov/rocksdb cd rocksdb/ git submodule init git submodule update # 替换src/Makevars为上面的内容后执行 R CMD INSTALL .
这样就能让RocksDB的构建完全适配R包的编译环境,顺利完成安装。
内容的提问来源于stack exchange,提问作者Artem Klevtsov
相关产品推荐
相关产品推荐

