Ошибка создания пакета Rcpp Символ не найден

Я пытаюсь создать пакет R с Rcpp.

Основной код, который я хочу экспортировать, написан на 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 (file, 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): символ не найден: __Z16MyFunctionIII
Ссылка на: /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 / private / var / folder / 37 / vpwyrl2j2bxdj91kh9fktzk00000gn / T / RtmpybFnDv / Rinst2f1e7114fbd2 / RSQMC ’

MyFunction — это функция, которую я пытаюсь вызвать в главном файле из Generate_RQMC.hpp.

Я изменил Makevars, добавив -I «… / src / SQMC_scripts / include» в 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

Мне наконец удалось заставить это работать благодаря ответу без пальто, и это хранилище.

Вот мой файл 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)

1

Решение

Подкаталоги пакетов — это интересная тема, Раздел 1.1.5: Подкаталоги пакетов в Написание R расширений. К сожалению, это немного уходит. Итак, этот вопрос возникает немного … На самом деле, у меня был похожий вариант, так как он связан с Использование атрибута Rcpp в подпапках. (Спойлер: не могу использовать атрибуты в src/ вложенные папки …)

К сожалению, единственный способ сделать это с папками в src каталог для изменения Makevars файл, как указано во второй половине Раздел 1.2.1: Использование Makevars в Написание R расширений.

Итак, что-то вроде:

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/ хоть…

4

Другие решения

Вы должны сначала зайти в подкаталог src/ и скомпилируйте ваш включенный код, возможно, в статическую библиотеку (или просто кучу .o файлы), которые вы можете сослаться на src/Makevars,

Есть пакеты, которые делают это, но я не могу придумать хороший или канонический справочник. Я склонен предпочитать внешние библиотеки.

В качестве альтернативы вы мог просто поместите все файлы C ++ в src/ и R возьмет на себя сборку. Возможно, вам придется настроить #include Путь в файлах.

3

По вопросам рекламы [email protected]