Сборка пакета R, который использует библиотеку кода AC - PullRequest
3 голосов
/ 04 октября 2019

Я хочу отправить пакет, но при чтении в политики репозитория R я обнаружил, что: «Исходные пакеты могут не содержать какую-либо форму двоичного исполняемого кода». В настоящее время у меня есть двоичный исполняемый файл для Mac, Win и Linux в .../inst, и пакет работает очень хорошо во всех ОС. Тем не менее, я думаю, что CRAN не примет это. Я начал находить некоторую информацию, но я новичок в C, и все, что я читаю, очень запутанно. Кажется, что есть несколько способов сделать это, и я не знаю, какой из них лучший.

Моему двоичному исполняемому файлу нужен определенный файл класса в каталоге, который отображается функцией.

Все мои функции зависят от библиотеки c. Итак, что я должен сделать, чтобы получить признание CRAN? ... например, скомпилировать с Rtools и поместить исполняемые файлы в .../inst? Оставить библиотеку в .../inst и создать функцию, которая будет выполнять эту работу?

Самостоятельная работа. Обновления о шагах, предпринятых для решения проблемы:

УстановкаRcpp пакет,

install.packages("Rcpp")

и установка R инструментов . Создайте новый пакет в R studio типа "Package w/ Rcpp" и выберите основной файл моей библиотеки кода c в "Create package based on source files".

Ответы [ 3 ]

6 голосов
/ 05 октября 2019

Ваш анализ верен: двоичный файл не будет летать на CRAN. Так что вам нужно сделать это библиотекой. Или, скорее, пакет для CRAN.

Это не так сложно , как кажется. Прежде всего, если вы написали двоичный файл, вы, вероятно, знаете, как реорганизовать код, чтобы сделать

void main() {
     // preliminary stuff on argc/argv
     // sort our arguments
     // call main function f(a, b, c)
}

Если вы можете добраться до этого места, вы почти закончили. Поместите файл с помощью f(a,b,c) в src/ и используйте (довольно просто, сравнительно) код Rcpp tp, передав a, b и c в вашу функцию - и затем получите результаты (числовыевектор, может быть?) назад.

Начните с Rcpp-введения виньетка и возьмите его оттуда.

3 голосов
/ 05 октября 2019

Одного ответа SO недостаточно, чтобы объяснить все детали взаимодействия R с C / C ++. Просто получить код C / C ++ для компиляции на разных системах - это глубокая кроличья нора, и это будет сложной задачей в таких проблемах, как ваша.

CRAN ожидает, что все пакеты, для которых требуется исполняемый файл, включают исходный коддля него, как и все, что необходимо для настройки его компиляции. Первое подразумевает, что любая библиотека, от которой вы зависите, должна иметь открытый исходный код и лицензию, совместимую с политиками CRAN;последнее подразумевает, что библиотека может быть построена с помощью набора инструментов R .

Например, RcppParallel, который, по сути, охватывает TBB * 1011 Intelдля использования пакетов RОн включает исходный код последнего в src и упоминает соответствующие авторские права и системные требования в своем описании (как видно на его странице CRAN). Из того, что я могу сказать, разработчики должны были написать файл Makevars.in, чтобы интегрировать его с R.

Это только один пример, и, к сожалению, нет единого ответа, который бы подходил для всех случаев. ,Посмотрите, например, на README для httpuv (прокрутите вниз).

Я не хочу разочаровывать, но интеграция существующих библиотек C / C ++ с R действительно сложна. Если вы хотите сделать это, вам нужно набраться терпения и начать с основ. Если нужная вам библиотека не с открытым исходным кодом, я сомневаюсь, что вы можете получить свой пакет на CRAN. Если это так, проверьте, как он скомпилирован как автономный, и перейдите оттуда.

Да и кстати, Rcpp не интегрирует существующие библиотеки с R, это по сути пакет с интерфейсами C ++ для RC API (и еще куча дополнительных функций), так что это не лучший пример того, что вы пытаетесь сделать.

1 голос
/ 07 октября 2019

Ответ Дирка описывает, что вы должны сделать: преобразовать вашу программу в библиотеку, то есть набор вызываемых функций, и включить ее в свой пакет. Здесь я хочу привести очень короткий и упрощенный пример того, как сделать этот второй шаг. Обратите внимание, что точные детали будут зависеть от сигнатуры вашей функции.

Давайте начнем с тривиальной функции C, объявленной в foo.h, которую также можно использовать из C ++:

#ifdef __cplusplus
extern "C" {
#endif

    double namefunction(double x);

#ifdef __cplusplus
}
#endif

и определено в foo.c:

#include "foo.h"

double namefunction(double x) {
    return x * 1.234;
}

Чтобы вызвать эту функцию из R, мы пишем функцию-обертку, используя Rcpp:

#include <Rcpp.h>
#include "foo.h"

// [[Rcpp::export]]
double foo(double x) {
    return namefunction(x);
}

Все эти файлы предназначены длябыть помещенным в каталог src пакета R, созданного с помощью Rcpp::Rcpp.package.skeleton() или соответствующей функции в RStudio. После вызова Rcpp::compileAttributes(), сборки и установки пакета (или использования devtools::load_all()) будет доступна функция foo:

> foo(34.03566)
[1] 42
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...