构建R包时R函数调用Rcpp函数遇错误的技术求助
问题描述
尝试构建包含Rcpp函数的R包,此前用sourceCpp调用该函数完全正常,但通过roxygen等工具构建包时出现第一个错误:
"_myPackage_myFunction" not available for .Call() for package "myPackage"
查阅教程后手动修改NAMESPACE文件,添加以下内容:
useDynLib(mypackage) importFrom(Rcpp, evalCpp)
但安装包时又出现第二个错误:
** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for ‘myPackage’ in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object '/home/me/R/x86_64-pc-linux-gnu-library/4.3/00LOCK-myPackage/00new/myPackage/libs/myPackage.so':
/home/marc/R/x86_64-pc-linux-gnu-library/4.3/00LOCK-MSCA2/00new/MSCA2/libs/MSCA2.so: undefined symbol: _ZTIN3tbb4taskE
Error: loading failed
当前环境的sessionInfo()输出:
> sessionInfo() R version 4.3.3 (2024-02-29) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Ubuntu 22.04.4 LTS Matrix products: default BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0 LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0 locale: [1] LC_CTYPE=en_GB.UTF-8 LC_NUMERIC=C LC_TIME=en_GB.UTF-8 LC_COLLATE=en_GB.UTF-8 [5] LC_MONETARY=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 LC_PAPER=en_GB.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C time zone: Europe/London tzcode source: system (glibc) attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] devtools_2.4.5 usethis_3.0.0
问题分析与解决建议
针对第一个错误(.Call()找不到函数)
手动修改NAMESPACE是错误做法,roxygen2会自动生成该文件,手动修改易导致名称不匹配(比如你写的mypackage是小写,包名实际是myPackage)。正确操作:
- 在Rcpp函数对应的R包装函数(或Rcpp代码的注释块)中添加roxygen标签:
#' @useDynLib myPackage, .registration = TRUE #' @importFrom Rcpp evalCpp - 重新运行
devtools::document()生成正确的NAMESPACE文件 - 若用
// [[Rcpp::export]]导出C++函数,roxygen会自动处理函数注册,无需手动写.Call()调用
针对第二个错误(未定义TBB符号)
错误中的_ZTIN3tbb4taskE是Intel TBB(线程构建模块)库的符号,说明你的C++代码依赖TBB,但打包时未链接该库:
- 检查C++代码:确认是否包含TBB头文件(如
tbb/task.h)或使用了TBB并行功能 - 配置编译参数:
- 在包的
src/Makevars文件中添加TBB链接参数:PKG_LIBS += $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) -ltbb - 若TBB头文件路径非标准,补充添加:
PKG_CPPFLAGS += -I/usr/include/tbb
- 在包的
- 安装系统依赖:Ubuntu下执行
sudo apt-get install libtbb-dev安装TBB开发库
额外排查步骤
- 用
devtools::check()代替直接安装,获取更详细的构建错误日志 - 运行
devtools::clean_dll()清理旧的编译缓存后,再重新构建包
内容的提问来源于stack exchange,提问作者marc

