我正在尝试使用Rcpp将功能从BayesOpt C++库扩展到R.我是一个长期的R用户,但对C++来说相对较新,我遇到了一些问题.我已经按照Rcpp的插图设置了一个包,我理解这是引入外部C++库的最佳方法.
我在src/Makevars中将PKG_CPPFLAGS和PKG_LIBS设置为BayesOpt包含文件夹和库,我在src /中有一个.cpp文件(称为test.cpp),它使用#include来处理来自BayesOpt的一些头文件.在这个文件中,我有// [[Rcpp::export]]我要导出的函数.
当我运行时R CMD check mypackage,库似乎成功运行 - 查看日志,一切顺利,直到它尝试加载刚刚"安装"的软件包.然后,我明白了
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/home/me/p3/mypackage.Rcheck/mypackage/libs/mypackage.so':
/home/me/p3/mypackage.Rcheck/mypackage/libs/mypackage.so: undefined symbol: _ZTIN8bayesopt13DiscreteModelE
Run Code Online (Sandbox Code Playgroud)
在错误日志中. echo _ZTIN8bayesopt13DiscreteModelE | c++filt给出typeinfo for bayesopt::DiscreteModel,这是我的test.cpp文件中第一个使用BayesOpt头的对象.为了解决这个问题,我看起来又高又低,但我似乎找不到一个.我想相信Makevars正确地指向库,因为它能够在第一次安装检查期间找到头文件 - 只有在加载候选包时我得到这个未定义的符号错误.我看过一个使用外部库的Rcpp示例,但是Dirk在我看到的答案中指出RcppGSL,有一个3500+行配置脚本填充了Makevars,并且它有点难以解析.
我很感激任何人的帮助 - 我的最后一招是把所有东西都放进去,src但对于一个已经整齐有序的图书馆来说,这似乎很麻烦而且不那么优雅.
不要看configure自动生成的脚本 - 看看configure.ac它的来源是哪一个,哪个是重要的5行(见下文)加上5行设置和完成.
简而言之,您可能只需要为标题(通过-I...)和链接(通过-L... -l...)加载值.
为此我们这样做src/Makevars.in:
# set by configure
GSL_CFLAGS = @GSL_CFLAGS@
GSL_LIBS = @GSL_LIBS@
# combine with standard arguments for R
PKG_CPPFLAGS = $(GSL_CFLAGS) -I../inst/include
PKG_LIBS = $(GSL_LIBS)
Run Code Online (Sandbox Code Playgroud)
表示的两个变量@GSL...@都是通过configure和configure.ac(实质上)设置gsl-config断言后我们拥有它来设置:
## Use gsl-config to find arguments for compiler and linker flags
##
## Check for non-standard programs: gsl-config(1)
AC_PATH_PROG([GSL_CONFIG], [gsl-config])
## If gsl-config was found, let's use it
if test "${GSL_CONFIG}" != ""; then
# Use gsl-config for header and linker arguments
GSL_CFLAGS=`${GSL_CONFIG} --cflags`
GSL_LIBS=`${GSL_CONFIG} --libs`
else
AC_MSG_ERROR([gsl-config not found, is GSL installed?])
fi
Run Code Online (Sandbox Code Playgroud)
在过去十年左右创建的许多其他库使用了一个类似的(但更通用的)工具pkg-config,该工具用于相同的目的:使用库将编译和链接器标志传递给程序.
而你做既需要,您的评论
我想相信Makevars正确指向库,因为它能够在第一次安装检查时找到头文件
表示您已经整理了编译,但没有链接或可能不是您的库的系统配置.同样,对于RcppGSL,构建期间的最后一行是以下(为简洁起见而编辑)
g++ -shared -L/usr/lib/R/lib -o RcppGSL.so \
RcppExports.o fastLm.o setErrorHandler.o \
-L/usr/lib/x86_64-linux-gnu -lgsl -lgslcblas \
-lm -L/usr/lib/R/lib -lR
Run Code Online (Sandbox Code Playgroud)
它将三个源文件与两个GSL相关的库以及R和数学库相链接.您必须在构建中看到类似的内容,或者未正确设置.
编辑:如果你在你的包中捆绑了BayesOpt,那么你需要将它构建到一个静态库中并在其中列出src/Makevars.这是一个不同的用例:对于RcppGSL,我们寻找系统 GSL安装.本地不同.您可以研究处理这两种情况的nloptr包.