rcpp包创建符号找不到错误
Rcpp package creation Symbol not found error
我正在尝试使用 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.[= 中对所有脚本进行分组的共享库18=]
在 main.cpp 文件中,我想从 Generate_RQMC.hpp 调用一个函数,所以我在脚本的开头添加了以下行:
#include "SQMC_scripts/R_Functions/include/Generate_RQMC.hpp"
当我运行
R CMD build RSQMC
我收到以下错误:
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/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): Symbol not found: __Z16MyFunctioniii
Referenced from: /private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so
Expected in: flat namespace
in /private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/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 文件夹中定义的不同 classes 和函数)例如:
Symbol not found: __ZN19DigitalNetGeneratorC1E4_dgtj
DigitalNetGenerator 是在 C 文件 DigitalNetsBase2.
中定义的 class
更新 2
多亏了 Coatless 的回答和这个 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)
您需要先进入 src/
的子目录并编译您包含的代码,可能是一个静态库(或只是一堆 .o
文件),然后您可以从您的src/Makevars
.
有一些软件包可以做到这一点,但我想不出一个很好的或规范的参考。我倾向于更喜欢外部库。
作为替代方案,您可以 将所有 C++ 文件放入 src/
,R 将进行构建。您可能需要调整文件中的 #include
路径。
包子目录是 Section 1.1.5: Package subdirectories in Writing R Extensions. Unfortunately, it leaves a bit out. So, this question comes up a bit... In fact, I had a similar variant of it as it related to Rcpp Attribute use in subfolders 中涵盖的一个有趣主题。 (剧透:不能在 src/
子文件夹中使用属性...)
不幸的是,对 src
目录中的文件夹执行此操作的唯一方法是修改 Makevars
文件,如 Section 1.2.1: Using Makevars in 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/
中...
我正在尝试使用 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.[= 中对所有脚本进行分组的共享库18=]
在 main.cpp 文件中,我想从 Generate_RQMC.hpp 调用一个函数,所以我在脚本的开头添加了以下行:
#include "SQMC_scripts/R_Functions/include/Generate_RQMC.hpp"
当我运行
R CMD build RSQMC
我收到以下错误:
Error in dyn.load(file, DLLpath = DLLpath, ...) : unable to load shared object '/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): Symbol not found: __Z16MyFunctioniii Referenced from: /private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so Expected in: flat namespace in /private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/RSQMC/libs/RSQMC.so Error: loading failed Execution halted ERROR: loading failed * removing ‘/private/var/folders/37/vpwyrl2j2bxdj91kh9fktzk00000gn/T/RtmpybFnDv/Rinst2f1e7114fbd2/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 文件夹中定义的不同 classes 和函数)例如:
Symbol not found: __ZN19DigitalNetGeneratorC1E4_dgtj
DigitalNetGenerator 是在 C 文件 DigitalNetsBase2.
中定义的 class更新 2
多亏了 Coatless 的回答和这个 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)
您需要先进入 src/
的子目录并编译您包含的代码,可能是一个静态库(或只是一堆 .o
文件),然后您可以从您的src/Makevars
.
有一些软件包可以做到这一点,但我想不出一个很好的或规范的参考。我倾向于更喜欢外部库。
作为替代方案,您可以 将所有 C++ 文件放入 src/
,R 将进行构建。您可能需要调整文件中的 #include
路径。
包子目录是 Section 1.1.5: Package subdirectories in Writing R Extensions. Unfortunately, it leaves a bit out. So, this question comes up a bit... In fact, I had a similar variant of it as it related to Rcpp Attribute use in subfolders 中涵盖的一个有趣主题。 (剧透:不能在 src/
子文件夹中使用属性...)
不幸的是,对 src
目录中的文件夹执行此操作的唯一方法是修改 Makevars
文件,如 Section 1.2.1: Using Makevars in 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/
中...