在 R 包中构建和链接共享库 - 代码编译、链接,但不会加载

Building and linking shared libraries in an R package - code compiles, links, but won't load

测试平台:Linux Mint 17,Ubuntu 14.04 完整示例:this repository.

我在做什么,为什么?

我正在尝试构建一个包含 CAF library using Rcpp and RcppEigen.

子集的 R 包

我已经成功地link将 R 包编辑到 CAF 的系统级安装 (example here)(注意:ABSEIR 不再使用 CAF, 2/5/2015),但我希望有一个很好的方法将 CAF 部署到没有管理员访问权限的机器,从而简化其他 CAF 依赖包的安装(是的,我知道 R 没有直接支持 linking 针对其他编译包,但似乎其他人已成功规避此限制)。

有什么问题?

除了包共享对象 (RcppCAF.so) 之外,我还在包编译期间构建了两个共享对象:libcaf_core.so 和 libcaf_io.so。这些已成功编译和 linked,但包加载失败,声称:

** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) : 
  unable to load shared object '/home/grantbrown/R/x86_64-pc-linux-gnu-library/3.2/RcppCAF/libs/RcppCAF.so':
  librcaf_core.so: cannot open shared object file: No such file or directory

我尝试了什么?

除了许多失败的 Makevars 配置之外,我还发现 如果我手动设置 LD_LIBRARY_PATH 到包含编译代码的文件夹,包将成功安装。显然,我想通过找到一种方法告诉 R 在哪里寻找这些依赖项来避免这一步。为此,我尝试使用 inst 文件夹但没有效果。我的 Makevars 文件如下:

ROOT_DIR := $(abspath .)                                                        
$(info The compilation root directory is: $(ROOT_DIR))                          
$(info The name of the shared library to be created is: $(SHLIB))               
$(info The place R should look for librcaf_core.so is: $(abspath ./libcaf_core)) 
$(info The place R should look for librcaf_io.so is: $(abspath ./libcaf_io)) 

SOURCES = $(wildcard ./*.cpp)
SOURCES1 = $(wildcard ./libcaf_core/*.cpp)
SOURCES2 = $(wildcard ./libcaf_io/*.cpp)

OBJECTS = $(SOURCES:.cpp=.o)
OBJECTS1 = $(SOURCES1:.cpp=.o)
OBJECTS2 = $(SOURCES2:.cpp=.o)

PKG_CPPFLAGS+= -std=c++11 -Dlibcaf_core_shared_EXPORTS -Wall -pedantic -pthread -fPIC -O2 -g -fPIC -I../inst -I../inst/libcaf_core -I../inst/libcaf_io 

PKG_LIBS += -L$(abspath ./libcaf_core) -lrcaf_core -L$(abspath ./libcaf_io) -lrcaf_io

all: $(SHLIB) 

$(SHLIB): $(OBJECTS) libcaf_core/librcaf_core.so libcaf_io/librcaf_io.so

libcaf_core/librcaf_core.so: $(OBJECTS1)
    g++ -o libcaf_core/librcaf_core.so $(OBJECTS1) $(PKG_CPPFLAGS) -shared

libcaf_io/librcaf_io.so: $(OBJECTS2) 
    g++ -o libcaf_io/librcaf_io.so $(OBJECTS2) $(PKG_CPPFLAGS) -shared

Whosebug 和邮件列表上有很多线程处理加载共享对象的问题,但我找不到任何人有完全相同的问题。我什至在过去做过类似的事情,没有任何问题,所以我很难弄清楚为什么 R 找不到我的共享对象。有什么建议吗?

编辑

Dirk 建议编译为单个共享对象,我现在正在努力。然而,在 "Writing R Extensions" 的 "Using Makevars" 部分,它似乎确实暗示构建依赖项应该是可能的:

“如果你想创建然后 link 到一个库,比如使用子目录中的代码,使用类似

.PHONY: all mylibs

all: $(SHLIB)
$(SHLIB): mylibs

mylibs:
    (cd subdir; make)

根据 your most recent commit,您似乎也发现了最简单的方法,就是将 R 'glue' 所有目标代码放入一个共享库中。

这往往 "just work" 但它有点昂贵,因为需要重建图书馆。我们可以考虑包装 CAF as an external library which would make RcppCAF 更轻量级。