R, который ссылается на внешнюю библиотеку C - программирование

R, который ссылается на внешнюю библиотеку C

У меня есть код c, который использует библиотеку igraph. Я хотел бы поместить вокруг него обертку R и отправить ее в CRAN как R-пакет.

igraph уже имеет R-порт на CRAN, поэтому для моего R-пакета 'foo' было бы целесообразно зависеть от R igraph. Поскольку foo использует собственный C-код, который зависит от C igraph, как я могу связать свои C-функции с оригинальной библиотекой igraph? Я читал, что это делается в файле под названием Makevars, но привязка к внешней библиотеке очень волосатая.

Если это невозможно, лучше всего скопировать весь исходный код igraph и поместить все это в каталог /src? В пакете R igraph уже есть файл под названием Makevars, но я не понимаю, как все c файлы создаются - обычно в моем Makefile. У меня есть что-то вроде gcc (некоторый список .c исходных файлов) -o, но Makevar содержит только

PKG_CFLAGS=-DUSING_R -I. -Ics -Iglpk -Iglpk/amd -Iglpk/colamd \
-g -O2 -I/usr/include/libxml2 -g -O2 -I/usr/include/libxml2 -DNDEBUG \
-DPACKAGE_VERSION=\"0.6\" -DINTERNAL_ARPACK \
-DIGRAPH_THREAD_LOCAL=/**/
PKG_CXXFLAGS= -DUSING_R -DIGRAPH_THREAD_LOCAL=/**/ -DNDEBUG
PKG_LIBS=-lxml2 -lz -lpthread -licucore -lm -lgmp  $(FLIBS) $(LAPACK_LIBS) $(BLAS_LIBS)

all: $(SHLIB)

и нет другого Makefile. В целом, как я могу поместить C-код в R-пакет, который зависит от другой библиотеки C, и как я могу написать соответствующие Makevars (или Makefile) для включения функций C?

Старый вопрос был отправлен here, но, похоже, он ссылается на помощь в написании собственного кода на C, который ничем не зависит.

4b9b3361

Ответ 1

Здесь есть несколько вопросов:

  • Может ли пакет 'foo' надежно связываться с пакетом 'bar'? "Написание R-расширений" в начале раздела 5.8 "Связывание с другими пакетами" говорится "нет, а не вообще", как Габор намекал также на его предыдущий комментарий.

  • Может ли исходный код C помещаться в пакет для создания пакета, который зависит от другой библиотеки: Да, конечно, и много пакетов на CRAN делают это. Выберите пример пакета в зависимости от GSL или графических библиотек JPEG/TIFF, или XML, или... Вы можете изучить эти источники. Это не так просто, но если вы изучите эти пакеты, документация в Writing R Extensions и другая ответьте на связанные вопросы здесь, вы должны туда добраться.

Ответ 2

Я немного по-другому читаю "Написание R-расширений". В параграфе 1 раздела 5.8.1 (относящийся к UNIX-подобным операционным системам) говорится, что он возможен, но не переносится или не рекомендуется связываться с разделяемой библиотекой. В параграфе 2 говорится, что статические библиотеки в порядке ('This' во главе абзаца запутан, что это значит?), Поскольку статическая библиотека, предоставляемая packA, может быть обнаружена packB при установке packB и затем включается в динамическая библиотека. Для этого требуется, чтобы packA предоставлял статическую библиотеку, и, следовательно, packA понял, что это роль должна была сделать это; многие пакеты вместо этого будут думать о своей роли как предоставления R-интерфейса подмножеству функциональных возможностей библиотеки, которую они обертывают, и предоставить общий объект, который ссылается на общую библиотеку в своем собственном пакете.

В качестве примера можно привести пакет Rsamtools в Bioconductor, который создает статические версии библиотеки samtools и предоставляет (сложный для получения -right) для пакетов, которые хотят получить доступ к статической библиотеке (vignette предоставляет зависимый пакетный вид вещей). Важно обеспечить абсолютный путь к статической библиотеке PKG_LIBS="-l$(PKGB_PATH)/libpackB.a", чтобы избежать статической привязки к той же библиотеке, предоставляемой системой (с заголовками, предоставленными packA).

@DirkEddelbuettel почти наверняка спустился по этой дороге и укажет на мои ошибки. Я согласен с его комментарием ниже, что использование статической библиотеки является субоптимальным (в первую очередь, с точки зрения потребления памяти?), Но сделайте выбор, чтобы избежать причин переносимости, упомянутых в пункте 5.8.1.