Skip to content

Packages using float may not be relocatable #53

@kevinushey

Description

@kevinushey

For example, on my Fedora 42 machine:

lib1 <- tempfile("library-")
dir.create(lib1)
.libPaths(lib1)
install.packages("rsparse")

lib2 <- tempfile("library-")
file.rename(lib1, lib2)
.libPaths(lib2)

library(rsparse)

This gives me:

Error: package or namespace load failed for 'rsparse' in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/tmp/RtmpaEkwR1/library-1bea6cc6135c/rsparse/libs/rsparse.so':
  float.so: cannot open shared object file: No such file or directory

I believe this occurs because the path to the float.so library gets encoded into the compiled rparse.so shared object, e.g.

> system(paste("objdump -x", rsparse, "| grep float"))
  NEEDED               float.so
  RUNPATH              /tmp/RtmpaEkwR1/library-1bea347adee3/float/libs

And that RUNPATH is no longer valid since the library has been moved.

I suspect this is coming from float:::ldflags(), e.g. the rpath flags:

$ R -s -e 'float:::ldflags()'
-L/home/kevin/R/x86_64-redhat-linux-gnu-library/4.5/float/libs -l:float.so -Wl,-rpath=/home/kevin/R/x86_64-redhat-linux-gnu-library/4.5/float/libs 

I'm not sure if there's a clean solution. The simplest / closest fix I can think of is to use $ORIGIN, but this will still assume that float and any packages using float live in the same library path. (And it still won't work with renv's caching system, but that's another story...)

Alternatively, instead of linking to float.so an interface using R_RegisterCCallable and R_GetCCallable could be used, but I realize this is basically asking you to do an odious amount of work for only a vague benefit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions