在Rcpp的帮助下,使用C,GSL和OpenMP的R包的便携式Makevars

时间:2014-11-24 12:06:56

标签: c r openmp rcpp gsl

我正在构建一个R包,其中我几乎没有使用GSL和OpenMP的第三方C函数,然后我使用Rcpp创建的包装器从R调用它们(它只修改一些参数并调用适当的C函数)。在我的Windows机器上一切正常,但我不确定如何以便携方式定义Makevars.win和Makevars文件。我的Makevars.win看起来像这样:

## This assumes that the LIB_GSL variable points to working GSL libraries
PKG_CPPFLAGS=-I$(LIB_GSL)/include -I../inst/include
PKG_LIBS=-L$(LIB_GSL)/lib/x64 -lgsl -lgslcblas $(SHLIB_OPENMP_CFLAGS)
PKG_CFLAGS=$(SHLIB_OPENMP_CFLAGS)

它基本上是从各种来源复制的。如上所述,这在我的计算机中编译(使用来自Rtools的工具链),如果我删除PKG_CFLAGS=$(SHLIB_OPENMP_CFLAGS)我也可以在没有OpenMP的情况下编译(出于某种原因,我不明白如果我删除OpenMP标志会出错在PKG_LIBS)。

我的Makevars文件看起来很相似,但我无法访问Unix平台,因此我不确定如何处理这一方面。我的猜测是我需要用某些东西替换LIB_GSL

修改

好吧,我想我终于明白了配置等是如何工作的,并且能够让一切正常。

我的Makevars.win

## This assumes that the LIB_GSL variable points to working GSL libraries
PKG_CPPFLAGS=-I$(LIB_GSL)/include -I../inst/include
PKG_LIBS="-L$(LIB_GSL)/lib/$(R_ARCH)" -lgsl -lgslcblas $(SHLIB_OPENMP_CFLAGS)
PKG_CFLAGS=$(SHLIB_OPENMP_CFLAGS)

我的Makevars.in

GSL_CFLAGS = @GSL_CFLAGS@
GSL_LIBS = @GSL_LIBS@

PKG_LIBS=$(GSL_LIBS) $(SHLIB_OPENMP_CFLAGS)
PKG_CFLAGS=$(GSL_CFLAGS) $(SHLIB_OPENMP_CFLAGS)

我的configure.ac:

AC_INIT([testpackage], 0.0.1)

## 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

# Now substitute these variables in src/Makevars.in to create src/Makevars
AC_SUBST(GSL_CFLAGS)
AC_SUBST(GSL_LIBS)

AC_OUTPUT(src/Makevars)

然后我在testpackage目录中运行autoconf以获取configure文件,该文件在运行Makevars.in时会将Makevars转换为R CMD INSTALL

1 个答案:

答案 0 :(得分:0)

有一些CRAN包使用GSL和/或我们的RcppGSL绑定。以下是我在其中一个(我的RcppZiggurat包)中所做的事情:

PKG_CPPFLAGS = -I. -I../inst/include
## Use the R_HOME indirection to support installations of multiple R version
PKG_LIBS = `$(R_HOME)/bin/Rscript -e "RcppGSL:::LdFlags()"`

这就是整个/src/Makevars。您可以从R中简单地添加相同的OpenMP变量。这当然会创建对RcppGSL的依赖(因为我已经在RcppZiggurat中使用它)。另外,您可以查看RcppGSL的R/init.R,看看它如何尝试与gsl-config对话并存储这些值。你可以在src/Makevars中做同样的事情 - 它只是基本的使用而没有特定的Rcpp。