I have some c code that utilizes the igraph library. I would like to put an R wrapper around it and send it off to CRAN as an R package.
igraph already has an R port on CRAN, so it would make sense for my R package 'foo' to depend on R's igraph. Since foo uses its own C code that depends on the C igraph, how can I link my C functions to the original igraph library? I've read that this is done in a file called Makevars, but linking to an external library is very hairy.
If this isn't possible, is it better to just copy the entire igraph source code and put the whole thing into my /src directory? The R igraph package already has a file called Makevars, but I don't understand how all the c files get built - normally in my Makefile I have something like gcc (some list of .c source files) -o, but Makevar only contains
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)
and there is no other Makefile. In summary, how do I go about putting C code into an R package that depends on another C library, and how do I write the corresponding Makevars (or Makefile) to incorporate the C functions?
An older question was posted here but only seems to link to help on writing your own C code that does not depend on anything.
There are several questions here:
Can a package 'foo' reliably link to a package 'bar'? "Writing R Extensions", at the beginning of Section 5.8 on "Linking to Other Packages" says "no, not generally" as Gabor hinted too in his earlier comment.
Can C source code put into a package to build a package that depends on another libary: Yes, of course, and lots of packages on CRAN do it. Pick eg an example of a package depending on the GSL, or the JPEG/TIFF graphics libraries, or XML, or ... You can study these sources. That is not trivial easier, but if you study these packages, the documentation in Writing R Extensions and the other answers to related questions here you should get there.
I take a slightly different reading of "Writing R Extensions". Paragraph 1 of Section 5.8.1 (dealing with unix-like operating systems) says that it's possible but not portable or recommended to link to a shared library. Paragraph 2 says static libraries are ok (the 'This' at the head of the paragraph is confusing; what does it refer to?) because the static library provided by packA can be discovered by packB when packB is installed, and is then incorporated into the dynamic library. This requires that packA provides a static library, and hence that packA realized that it's role was to do this; many packages will instead think of their role as providing an R interface to a subset of the functionality of the library that they wrap, and provide a shared object that links to the shared library in its own package.
An example is the Rsamtools package in Bioconductor, which creates static versions of the samtools library and provides a (tricky-to-get-right) mechanism for packages wanting to access the static library (a vignette provides a dependent package view of things). It's important to provide the absolute path to the static library PKG_LIBS="-l$(PKGB_PATH)/libpackB.a"
to avoid static linking to the same library provided by the system (with the headers provided by packA).
@DirkEddelbuettel has almost surely gone down this road himself, and will point out my errors. I agree with his comment below that using a static library is sub-optimal (primarily from the memory consumption perspective?) but make the choice to avoid the portability reasons alluded to in paragraph 5.8.1.