Rcpp: невозможно загрузить общий объект, неопределенный символ
Я пытаюсь использовать Rcpp для расширения функциональности от BayesOpt библиотека C++ в R. Я давний пользователь R, но относительно новый для C++, и у меня возникают некоторые проблемы. Я следил за виньетками Rcpp для настройки пакета, который, как я понимаю, является лучшим способом привлечения внешних библиотек c++.
Я установил pkg_cppflags и PKG_LIBS в src/Makevars в BayesOpt, включая папки и библиотеку, и у меня есть один .cpp-файл (назовите его test.СРР) в src/, который использует #include для некоторых файлов заголовков из BayesOpt. В этом файле у меня есть // [[Rcpp::export]]
над функцией, которую я хочу экспортировать.
когда я запускаю R CMD check mypackage
, библиотека, похоже, работает успешно - глядя на журнал, все идет хорошо, пока она не попытается загрузить пакет, который был только что "установлен". Тогда я получаю
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/home/me/p3/mypackage.Rcheck/mypackage/libs/mypackage.so':
/home/me/p3/mypackage.Rcheck/mypackage/libs/mypackage.so: undefined symbol: _ZTIN8bayesopt13DiscreteModelE
в журнале ошибок. echo _ZTIN8bayesopt13DiscreteModelE | c++filt
дает typeinfo for bayesopt::DiscreteModel
, который является первым объектом в моем тесте.cpp-файл, который использует заголовки BayesOpt. Я посмотрел высоко и низко для решения этого, но я не могу найти его. Я хотел бы верить, что Makevars указывает на библиотеку правильно, потому что он может найти файлы заголовков во время первой проверки установки-только при загрузке пакета-кандидата я получаю эту неопределенную ошибку символа. Я просмотрел пример Rcpp, который использует внешние библиотеки, но тот, на который указывает Дирк в ответах, которые я просмотрел,RcppGSL
, имеет 3500 + line configure скрипт, который заполняет Makevars, и это немного трудно разобрать.
Я был бы признателен за любую помощь - мое последнее средство-сбросить все в src
но это кажется громоздким и менее чем элегантным для библиотеки, которая уже аккуратно организована.
1 ответов
не смотри на configure
скрипт, который автоматически ... посмотри на configure.ac
который является его источником, и который все 5 строк, которые имеют значение (см. ниже) плюс, возможно, 5 строк настройки и отделки.
и в двух словах, вам может просто понадобиться загрузить значения для обоих заголовков (через -I...
) и связывание (через -L... -l...
).
и для этого мы делаем это в src/Makevars.in
:
# set by configure
GSL_CFLAGS = @GSL_CFLAGS@
GSL_LIBS = @GSL_LIBS@
# combine with standard arguments for R
PKG_CPPFLAGS = $(GSL_CFLAGS) -I../inst/include
PKG_LIBS = $(GSL_LIBS)
две переменные, обозначаемые @GSL...@
как установить через configure
и configure.ac
(в сущности) просто звонит gsl-config
после утверждения, что у нас есть:
## Use gsl-config to find arguments for compiler and linker flags
##
## Check for non-standard programs: gsl-config(1)
AC_PATH_PROG([GSL_CONFIG], [gsl-config])
## If gsl-config was found, let's use it
if test "${GSL_CONFIG}" != ""; then
# Use gsl-config for header and linker arguments
GSL_CFLAGS=`${GSL_CONFIG} --cflags`
GSL_LIBS=`${GSL_CONFIG} --libs`
else
AC_MSG_ERROR([gsl-config not found, is GSL installed?])
fi
многие другие библиотеки, созданные за последнее десятилетие или около того, используют аналогичный (но более общий) инструмент под названием pkg-config
который служит той же цели: передайте флаги компиляции и компоновщика программам, использующим библиотеку.
и do нужны оба, ваш комментарий
я хотел бы верить, что Makevars указывает на библиотеку правильно, потому что это может найти файлы заголовков во время первой проверки установки
указывает, что у вас есть сборник разобраться, но не связывание или, возможно, не системное обеспечение вашей библиотеки. Опять же, для RcppGSL заключительная строка во время сборки следующая (отредактированная для краткости)
g++ -shared -L/usr/lib/R/lib -o RcppGSL.so \
RcppExports.o fastLm.o setErrorHandler.o \
-L/usr/lib/x86_64-linux-gnu -lgsl -lgslcblas \
-lm -L/usr/lib/R/lib -lR
он связывает три исходных файла с двумя библиотеками, связанными с GSL, а также с R и математической библиотекой. Вы должны увидеть что-то подобное в ваша сборка, или она неправильно настроена.
Edit: и если вы связываете BayesOpt в свой пакет, то вам нужно построить его в static библиотека и список, который в src/Makevars
. Это другой случай использования: для RcppGSL мы ищем система установка GSL. Местные разные. Вы можете изучить пакет nloptr, который имеет дело с обоими случаями.