`LinkingTo` 在 R 包中做什么?

What does `LinkingTo` do in an R package?

我正在构建一个 R 包,其描述包含:

LinkingTo: Rcpp

该软件包具有相当深的 makefile 结构。我知道使用 R CMD build . 创建和修改诸如 CXX11FLAGS 之类的变量,这些变量必须通过后续的 makefile 层向下传递。

我怀疑LinkingTo也产生了这样一个变量,我必须知道并传递它。我怀疑这是因为,向下几层,我遇到了错误:

mycode.hpp:5:10: fatal error: Rcpp.h: No such file or directory
#include <Rcpp.h>

我不确定如何通知此文件的联编文件 Rcpp 的位置。我怀疑可以使用假设的变量,但我不知道该变量的名称。谁能澄清一下?

我编辑了我的 Makefile 以包含以下黑魔法:

VARS_OLD := $(.VARIABLES)
$(foreach v,                                        \
$(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)),   \
$(info $(v) = $($(v))))

这会打印出当您 运行 R CMD build ..

时 R 传递给 make 进程的所有环境变量

深入挖掘发现了一些非常有趣的变量:

ALL_CPPFLAGS = -I/usr/share/R/include -DNDEBUG  -I"/home/myuser/.R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include" 
CLINK_CPPFLAGS = -I"/home/myuser/.R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include"
R_INCLUDE_DIR = /usr/share/R/include

请注意,这些变量包含 -I 标志,因此必须传达给依赖这些变量的构建过程的任何部分。

通过在 makefile 之间传递这些,我能够实现编译。

这是 LinkingTo: 来自我的一个较小的正在进行的包:

LinkingTo: Rcpp, RcppArmadillo

编译时,这两个包都是通过-I...开关使用的:

edd@bud:~/git/rcppkalman(master)$ ./cleanup 
edd@bud:~/git/rcppkalman(master)$ R CMD INSTALL .
* installing to library ‘/usr/local/lib/R/site-library’
* installing *source* package ‘RcppKalman’ ...
** libs
ccache g++ -I/usr/share/R/include -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include"    -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -Werror -march=native -c RcppExports.cpp -o RcppExports.o
ccache g++ -I/usr/share/R/include -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include"    -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -Werror -march=native -c expmMat.cpp -o expmMat.o
ccache g++ -I/usr/share/R/include -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include"    -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -Werror -march=native -c kfpredict.cpp -o kfpredict.o
ccache g++ -I/usr/share/R/include -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include"    -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -Werror -march=native -c kfupdate.cpp -o kfupdate.o
ccache g++ -I/usr/share/R/include -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include"    -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -Werror -march=native -c ltidisc.cpp -o ltidisc.o
ccache g++ -I/usr/share/R/include -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include"    -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -Werror -march=native -c rtssmooth.cpp -o rtssmooth.o
ccache g++ -I/usr/share/R/include -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include"    -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -Werror -march=native -c tfsmooth.cpp -o tfsmooth.o
g++ -Wl,-S -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o RcppKalman.so RcppExports.o expmMat.o kfpredict.o kfupdate.o ltidisc.o rtssmooth.o tfsmooth.o -llapack -lblas -lgfortran -lm -lquadmath -L/usr/lib/R/lib -lR
installing to /usr/local/lib/R/site-library/RcppKalman/libs
** R
** demo
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (RcppKalman)
edd@bud:~/git/rcppkalman(master)$ 

没有别的需要了。写 R 扩展说:

A package that wishes to make use of header files in other packages needs to declare them as a comma-separated list in the field 'LinkingTo' in the 'DESCRIPTION' file. For example

 LinkingTo: link1, link2

The 'LinkingTo' field can have a version requirement which is checked at installation.

Specifying a package in 'LinkingTo' suffices if these are C++ headers containing source code or static linking is done at installation: the packages do not need to be (and usually should not be) listed in the 'Depends' or 'Imports' fields. This includes CRAN package BH (https://CRAN.R-project.org/package=BH) and almost all users of RcppArmadillo (https://CRAN.R-project.org/package=RcppArmadillo) and RcppEigen (https://CRAN.R-project.org/package=RcppEigen).

For another use of 'LinkingTo' see *note Linking to native routines in other packages::.

从(基本上是空的)src/Makevars:

可以看出这一点
PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

这是 RcppArmadillo 用来支持 LAPACK 和 BLAS 外部链接的标准。请注意,我的包有点落后,因为 RcppArmadillo 在其最新版本中现在使用此 inst/skeleton/Makevars 传递到通过 RcppArmadillo.package.skeleton():

创建的每个包
## optional
#CXX_STD = CXX11

PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS) 
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

在可用的情况下也支持 OpenMP。这是目前推荐的形式。