16

我有一些利用igraph库的 c 代码。我想在它周围放一个 R 包装器并将其作为 R 包发送给 CRAN。

igraph在 CRAN 上已经有一个 R 端口,所以我的 R 包 'foo' 依赖于 R 的 igraph 是有意义的。由于 foo 使用自己的依赖于 C igraph 的 C 代码,我如何将我的 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 代码放入依赖于另一个 C 库的 R 包中,以及如何编写相应的 Makevars(或 Makefile)来合并 C 函数?

此处发布了一个较旧的问题,但似乎只是链接以帮助编写您自己的不依赖于任何东西的 C 代码。

4

2 回答 2

6

这里有几个问题:

  1. 包 'foo' 可以可靠地链接到包 'bar' 吗?正如 Gabor 在他之前的评论中所暗示的那样,“编写 R 扩展”在第 5.8 节“链接到其他包”的开头说“不,一般不”。

  2. 可以将 C 源代码放入包中以构建依赖于另一个库的包:是的,当然,CRAN 上的许多包都这样做。例如,根据 GSL、JPEG/TIFF 图形库、XML 或……选择一个包示例。您可以研究这些资源。这不是一件容易的事,但是如果您研究这些包,您应该了解编写 R 扩展中的文档以及此处相关问题的其他答案。

于 2012-09-08T13:44:51.930 回答
5

我对“编写 R 扩展”的阅读略有不同。第 5.8.1 节(处理类 unix 的操作系统)的第 1 段说,链接到共享库是可能的,但不可移植或不推荐。第 2 段说静态库是可以的(段落开头的'This'令人困惑;它指的是什么?)因为packA提供的静态库可以在安装packB时被packB发现,然后合并到动态库中。这要求 packA 提供一个静态库,因此 packA 意识到它的作用就是这样做;相反,许多包会将它们的角色视为为它们包装的库的功能子集提供 R 接口,并提供一个链接到其自己包中的共享库的共享对象。

一个例子是 Bioconductor 中的Rsamtools包,它创建 samtools 库的静态版本,并为想要访问静态库的包提供(棘手的)机制(小插图提供事物的依赖包视图)。提供静态库的绝对路径很重要,PKG_LIBS="-l$(PKGB_PATH)/libpackB.a"以避免静态链接到系统提供的同一库(使用 packA 提供的标头)。

@DirkEddelbuettel 几乎肯定自己已经走上了这条路,并会指出我的错误。我同意他在下面的评论,即使用静态库是次优的(主要从内存消耗的角度来看?),但要选择避免第 5.8.1 段中提到的可移植性原因。

于 2012-09-08T17:18:46.823 回答