Rcpp: установить пакет со статическими библиотеками для независимого от платформы использования - PullRequest
0 голосов
/ 05 декабря 2018

Я хочу использовать библиотеку libDAI C ++ в R-пакете и хочу, чтобы пакет:

  1. мог использоваться в Linux и Windows
  2. saveдисковое пространство (во внешней библиотеке ~ 60 Мб)
  3. конечному пользователю не нужно устанавливать boost и gmp для компиляции

Моя текущая настройка:

  • прекомпиляция libDAI
    • копирование libdai.a в lib /
    • копирование всех заголовочных файлов libDAI в inst / include
  • добавление Makevar в src /

Изменить файл Makevar:

# include libraries
PKG_CPPFLAGS =-I../inst/include/
PKG_LIBS = -Llib -l../lib/libdai.a

Мой скрипт для доступа к библиотеке libDAI (test.cpp в src /):

#include <dai/factorgraph.h>
#include <Rcpp.h>
#include <cmath>

using namespace Rcpp;
using namespace std;
using namespace dai;

//'
//' Creates libDAI factor graph object
//'
//' @param factor_graph character definition of the factor graph
//' @export
// [[Rcpp::export]]
void initialize_factor_graph(const char* factor_graph) {

  // read the factor graph from the string
  std::istringstream fgStream(factor_graph);
  FactorGraph net;
  net.ReadFromString( fgStream );

  // Output some information about the factorgraph
  cout << "Factor graph has " << net.nrVars() << " variables" << endl;
  cout << "Factor graph has " << net.nrFactors() << " factors" << endl;

}

running Rscript -e "Rcpp::compileAttributes('libdai')", затем R CMD INSTALL libdai возвращает ошибку:

Error: package or namespace load failed for 'libdai' in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object 
'/home/jk/libs/R/libdai/libs/libdai.so':
  /home/jk/libs/R/libdai/libs/libdai.so: undefined symbol: _ZTVN3dai11FactorGraphE
Error: loading failed

Итак, мои вопросы:

  • Что не так с моей настройкой?
  • Что такоелучшая процедура для предоставления моего окончательного пакета в CRAN?
  • Какая самая хорошая настройка для совместного использования пакета?

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

1 Ответ

0 голосов
/ 05 декабря 2018

Как связать со статической библиотекой

Вы можете использовать -L<directory> -l<name> или <path>, т.е. в вашем случае

PKG_LIBS = -L../lib -ldai

или

PKG_LIBS = ../lib/libdai.a

Размещение заголовка

Заголовки для libDAI используются только для внутреннего использования.Нельзя ссылаться на функции, объявленные в этих заголовках.Поэтому я бы не использовал inst/include для этих заголовков.

Зависимости от CRAN

Библиотека gmp доступна для сборщиков CRAN, cf https://github.com/cran/gmp и https://cran.r -project.org / пакет = ГМП .Кажется, что libDAI требует связывание для повышения (параметры программы), ср https://bitbucket.org/jorism/libdai/src/83bd24a4c5bf17b0592a7b5b21e26bf052881833/Makefile.LINUX?at=master&fileviewer=file-view-default#Makefile.LINUX-49. Однако, глядя на фактический Makefile, кажется, что это используется только для тестов и служебных программ.Таким образом, вам может не понравиться заголовок boost , предоставляемый пакетом BH.

Предварительная сборка статических библиотек

Это распространенный подход в Windows (см. ).https://github.com/rwinlib),, но я нахожу это необычным для Linux. Более распространенным подходом будет один из:

  • включает исходные коды в пакет и компилируется во время настройки или установки пакета
  • загрузкаисходники и компиляция во время настройки
  • ссылка с системной библиотекой (хотя я не видел ни одного для libDAI).

Для всех трех подходов есть многочисленные примеры на CRAN и GitHubТрудно дать рекомендацию, хотя. Вероятно, я бы пошел «включить исходники в пакет» и использовал Makefile, предоставленный апстримом, в качестве отправной точки для построения библиотеки.

...