Rcpp包创建符号未找到错误

时间:2017-07-13 14:41:44

标签: c++ r rcpp r-package

我正在尝试用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

我收到以下错误:

  

dyn.load中的错误(文件,DLLpath = DLLpath,...):     无法加载共享对象' /private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so':     dlopen(/private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so,6):找不到符号:__ Z16 MyFunction iii     参考自:/private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so     预计在:平面命名空间    在/private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so   错误:加载失败   执行停止   错误:加载失败   *删除'/ private / var / folders / 37 / vpwyrl2j2bxdj91kh9fktzk00000gn / T / RtmpybFnDv / Rinst2f1e7114fbd2 / RSQMC'

MyFunction是我试图在Generate_RQMC.hpp的主文件中调用的函数。

我通过添加-I" ... / src / SQMC_scripts / include"修改了Makevars。到PKG_LIBS,但它不会改变任何东西。

我正在使用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文件夹中定义的不同类和函数),例如:

  

未找到符号:__ ZN19DigitalNetGeneratorC1E4_dgtj

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)

2 个答案:

答案 0 :(得分:5)

Section 1.1.5: Package subdirectoriesWriting R Extensions中介绍了包子目录是一个有趣的主题。不幸的是,它留下了一点点。所以,这个问题有点......实际上,我有一个与Rcpp Attribute use in subfolders相关的类似变体。 (剧透:不能使用src/子文件夹中的属性...)

不幸的是,对src目录中的文件夹执行此操作的唯一方法是修改Makevars文件,如Section 1.2.1: Using MakevarsWriting 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.rdssrc/的原因虽然......

答案 1 :(得分:3)

您需要首先进入src/的子目录并编译您包含的代码,可能是一个静态库(或只是一堆.o个文件),然后您可以从{{{{ 1}}。

有一些软件包可以做到这一点,但我无法想到一个伟大的或规范的参考。我倾向于选择外部库。

作为替代方案,您可以将所有C ++文件放入src/Makevars,R将采用构建。您可能需要调整文件中的src/路径。