Pierre
Pierre

Reputation: 35246

R and external C library " cannot open shared object file" while LD_LIBRARY_PATH is set

I'm building a C extension for R, this library also uses the HDF5 library.

I compiled a dynamic library (gcc flag: -fPIC -shared -Wl,-soname,libmy.so -o ../lib/libmy.so in a 'lib' directory:

$ file /path/to/my/lib/libmy.so

/path/to/my/lib/libmy.so: ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not stripped

LD_LIBRARY_PATH is set:

$ echo $LD_LIBRARY_PATH 
/path/to/hdf5/lib:/path/to/my/lib

and now when I want to load my library in R from the directory /path/to/my/src

dyn.load("libmy.so")

I get the following error:

Error in dyn.load("libmy.so") : 
  unable to load shared object '/path/to/my/src/libmy.so':
  /path/to/my/src/libmy.so: cannot open shared object file: No such file or directory
Execution halted

If libmy.so is moved to my current working directory (I don't want this)

 mv ../lib/libmy.so ./

the library seems to be loaded but R is still missing the symbols from the hdf5 library:

Error in dyn.load("libmy.so") : 
  unable to load shared object ' /path/to/my/src/libmy.so':
  /path/to/my/src/libmy.so: undefined symbol: H5T_C_S1_g
Execution halted

I also tried load("my.so") instead of "libmy.so".

How can I load my dynamic library ?

Thanks.

EDIT: Added an example on github: https://gist.github.com/lindenb/7cd766cbb37de01f6cce

Upvotes: 0

Views: 1061

Answers (1)

Pierre
Pierre

Reputation: 35246

The solution was provided by John McKown on the R-Help mailing list.

I found that the dyn.load() function in R does NOT use the dlopen() routine as I was expecting. Instead it does an open(). The open() function needs a specific file name, including path information, in order to open a file. It does NOT look a the LD_LIBRARY_PATH environment variable or anything else.

Here is my code:

load.dynamic.libraries<-function(libnames)
    { 
    for(libname in libnames)
        {
        found_file=libname;
            for(path in unlist(strsplit(Sys.getenv("LD_LIBRARY_PATH"),":",fixed=TRUE))) 
                {
                    try_file <- paste0(path,"/",libname);

                    if( file.exists(try_file) )
                            {

                            found_file = try_file;
                            break;
                            }
                }
            write(paste("Loading :", try_file), stderr())
            dyn.load(found_file);
        }

    }

Upvotes: 1

Related Questions