warship
warship

Reputation: 3024

Setting a directory path to a dynamically linked library in an R package

What is the proper way to load in a dynamically linked library (i.e., a .so file) when writing an R package? The only solution that has worked for me so far has been to specify the full path to the .so file, e.g.:

dyn.load('/FULL/PATH/TO/MY/R_PACKAGE/src/my_file.so')

Obviously, this approach will not work for a CRAN/Bioconductor submission since the .so file will not be located. As such, I have (unsuccessfully) tried the following alternatives:

1) library.dynam()

2) library.dynam('my_file.so')

3) library.dynam('my_file.so', 'R_PACKAGE')

4) system.file("src", "my_file.so", package = "R_PACKAGE")

Related links: R: C symbol not in load table, R: C symbol name not in load table - error in linking with external .c files.

Just to be crystal clear, users of my R package may obviously set any arbitrary working directory on their computers. The only way a full path approach (as shown above) would ever work is if they set their working directory to /FULL/PATH/TO/MY/R_PACKAGE/src, which is (of course) impractical.

Upvotes: 2

Views: 826

Answers (2)

Dirk is no longer here
Dirk is no longer here

Reputation: 368251

Quick points:

  • Why do you need to ship a .so file? This would preclude uploads to common repos like CRAN which will not accept binary content

  • You can compute the full /FULL/PATH/TO/MY/R_PACKAGE/src/my_file.so by using system.file("src", "my_file.so", package="R_PACKAGE") (but then make sure you actually install a src/ which is not standard)

  • In all other cases (as pointed out by @BenBolker) R will know how to create the dynamic library and load it for you. Every package with compiled code does that. Just drop your source code into src/ and you are (essentially) done.

Upvotes: 1

Ben Bolker
Ben Bolker

Reputation: 226192

The standard way to do this, as described in Writing R Extensions, is:

1.5.4 useDynLib

A NAMESPACE file can contain one or more useDynLib directives which allows shared objects that need to be loaded.* The directive

useDynLib(foo)

registers the shared object foo** for loading with library.dynam. Loading of registered object(s) occurs after the package code has been loaded and before running the load hook function. Packages that would only need a load hook function to load a shared object can use the useDynLib directive instead.

* NB: this will only be read in all versions of R if the package contains R code in a R directory. ** Note that this is the basename of the shared object, and the appropriate extension (.so or .dll) will be added.

Upvotes: 1

Related Questions