R包链接到外部C库

时间:2012-09-08 04:59:37

标签: c r graph linker igraph

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

igraph已经在CRAN上有一个R端口,所以它对我的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代码放入依赖于另一个C库的R包中,如何编写相应的Makevars(或Makefile)来合并C函数?

发布了一个较旧的问题here,但似乎只是链接到帮助您编写自己的C代码而不依赖于任何内容。

2 个答案:

答案 0 :(得分:6)

这里有几个问题:

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

  2. 可以将C源代码放入一个包中构建一个依赖于另一个库的包:是的,当然,CRAN上的很多包都可以。选择例如根据GSL,JPEG / TIFF图形库或XML或...的包的示例。您可以研究这些来源。这不是一件容易的事,但是如果你研究这些软件包,写下R扩展中的文档以及相关问题的其他答案就可以到达那里。

答案 1 :(得分:5)

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

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

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