我正在尝试使用Rcpp创建一个R包。
我要导出的主要代码是C++,但它依赖于其他C++和C脚本。
我的项目如下所示:
├── DESCRIPTION
├── NAMESPACE
├── R
│ └── RcppExports.R
├── README.md
├── Read-and-delete-me
├── inst
│ ├── include
│ │ ├── Generate_RQMC.hpp
│ │ ├── Get_seed.hpp
│ │ ├── HilbertCode.hpp
│ │ └── SamplePack
│ │ ├── DB_NX.h
│ │ ├── DB_ShiftNets.h
│ │ ├── DigitalNetsBase2.h
│ │ ├── Measurements.h
│ │ └── RadicalInversesBase2.h
│ └── libsqmc_main.a
├── man
│ └── RSQMC-package.Rd
└── src
├── Makevars
├── RSQMC.so
├── RcppExports.cpp
├── RcppExports.o
├── SQMC.cpp
├── SQMC.o
└── libqmc
├── Generate_RQMC.cpp
├── Generate_RQMC.o
├── Get_seed.cpp
├── Get_seed.o
├── HilbertCode.cpp
├── HilbertCode.o
└── SamplePack
├── DigitalNetsBase2.C
├── Measurements.C
├── dn2dpro.C
├── dnmeasure.C
├── ricapdisc.C
├── rimeasure.C
├── rivis.C
└── tparam.C
其中libsqmc.so是将文件夹R_Functions中的所有脚本分组的共享库。
在main.cpp文件中,我想从Generate_RQMC.hpp调用一个函数,因此我在脚本的开头添加了以下行:
#include "SQMC_scripts/R_Functions/include/Generate_RQMC.hpp"
当我跑步时
R CMD build RSQMC
我收到以下错误:
MyFunction是我尝试从Generate_RQMC.hpp调用主文件中的函数。
我通过将-I“... / src / SQMC_scripts / include”添加到PKG_LIBS来修改了Makevars,但它没有任何改变。
我正在使用macOS Sierra 10.12.5,R 3.3.2和Rcpp 0.12.11。
更新
我修改了我的Makevars,现在看起来像这样:
CXX_STD = CXX11
SOURCES=$(wildcard SQMC_scripts/*.cpp SQMC_scripts/*/*.C)
OBJECTS = SQMC.o RcppExports.o $(SOURCES:.cpp=.o)
PKG_CXXFLAGS = -I".../RSQMC/src/"
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
all: $(SHLIB)
$(OBJECTS): clean
clean: @rm -f $(OBJECTS)
但是我仍然有相同类型的错误(针对SQMC_scripts文件夹中定义的不同类和函数),例如:
DigitalNetGenerator是在C文件DigitalNetsBase2中定义的类。
更新2
由于没有外套的回答和这个repository,我终于设法使它起作用。
如果对他人有帮助,这是我的Makevars文件:
$(info The compilation root directory is: $(ROOT_DIR))
$(info The name of the shared library to be created is: $(SHLIB))
CXX_STD = CXX11
PKG_CPPFLAGS= -Dlibqmc_core_shared_EXPORTS -I../inst -I../inst/include
PKG_LIBS= -L../inst -lsqmc_main -lgsl -lCGAL -lgslcblas
LIBS= -L./ -L../inst
SOURCES_C = ./libqmc/SamplePack/DigitalNetsBase2.C ./libqmc/SamplePack/dn2dpro.C ./libqmc/SamplePack/dnmeasure.C ./libqmc/SamplePack/Measurements.C ./libqmc/SamplePack/ricapdisc.C ./libqmc/SamplePack/rimeasure.C ./libqmc/SamplePack/rivis.C ./libqmc/SamplePack/tparam.C
SOURCES_CPP= ./libqmc/Generate_RQMC.cpp ./libqmc/Get_seed.cpp ./libqmc/HilbertCode.cpp
OBJECTS = SQMC.o RcppExports.o $(SOURCES_CPP:.cpp=.o) $(SOURCES_C:.c=.o)
#all: $(SHLIB)
all: $(SHLIB) ../inst/libsqmc_main.a
$(SHLIB): $(OBJECTS) ../inst/libsqmc_main.a
../inst/libsqmc_main.a: $(OBJECTS)
ar -rvs ../inst/libsqmc_main.a $(OBJECTS)
最佳答案
包子目录是Section 1.1.5: Package subdirectories中Writing R Extensions涵盖的有趣主题。不幸的是,它有一点遗漏。所以,这个问题出现了一点……实际上,我有一个类似的变体,因为它与Rcpp Attribute use in subfolders有关。 (剧透:无法使用src/
子文件夹中的属性...)
不幸的是,对src
目录中的文件夹执行此操作的唯一方法是修改Makevars
文件,如Section 1.2.1: Using Makevars中Writing R Extensions的后半部分所述。
因此,类似以下内容:
SOURCES=$(wildcard subfolder/*.cpp subfolder2/*.cpp)
OBJECTS = toplevelsrcfile.o RcppExports.o $(SOURCES:.cpp=.o)
PKG_CPPFLAGS=-I.
all: $(SHLIB)
clean:
@rm -f $(OBJECTS)
应该管用...
注意,在您的情况下,
toplevelsrcfile.o
应该是SQMC.o
。虽然不确定为什么
symbols.rds
在src/
中...