2015-06-18 32 views
7

In seguito a questa domanda here, ho problemi con dyn.load per caricare una libreria condivisa che è collegata a un dylib di Rust. Sospetto che abbia qualcosa a che fare con il punto in cui R sta cercando il dylib di Rust, ma non ho trovato un modo per specificare un'altra posizione rispetto a quella predefinita.Carica una libreria condivisa collegata alla libreria Rust in R

Da R, eseguo il seguente:

> dyn.load('src/test.so') 

E ricevere questo messaggio di errore:

Error in dyn.load("src/test.so") : 
    unable to load shared object '/Users/Zelazny7/r-dev/rustr/src/test.so': 
    dlopen(/Users/Zelazny7/r-dev/rustr/src/test.so, 6): Library not loaded: libglue.dylib 
    Referenced from: /Users/Zelazny7/r-dev/rustr/src/test.so 
    Reason: image not found 

Come faccio a caricare una libreria condivisa che dipende da un'altra libreria condivisa?

Il documentation per dyn.load non specifica come eseguire questa operazione.

Aggiornamento:

Grazie a shepmaster sono stato in grado di costruire con successo e importare una libreria condivisa in R. La libreria condivisa è stata compilata in C ed è essa stessa collegata a una libreria di Rust. Questi sono stati i miei passi:

  1. Compile libreria condivisa Rust
  2. Compile condiviso libreria C e il link alla libreria Rust utilizzando il seguente comando (in Windows, come io sono al lavoro questa mattina)

I miei contenuti delle directory:

C:\Users\gravesee\test>ls 
rglue.dll rglue.rs rustr.c treble.h 

Compilare la libreria condivisa finale:

gcc -shared -m64 -I"C:\Program Files\R\R-3.2.0\include" rustr.c -L"C:\Program Files\R\R-3.2.0\bin\x64" -lR -L. -lrglue -o test.dll 

Caricamento della libreria in R:

> dyn.load("test.dll") 
> is.loaded("triple") 
[1] TRUE 
> .Call("triple", as.integer(32)) 
The triple is 96 

risposta

4

Il problema sta per bollire giù per il fatto che le tue librerie condivise non sono nelle directory che il sistema si aspetta che siano per impostazione predefinita.

Ci sono alcuni trucchi che si possono utilizzare, 2 delle quali sono stato in grado di fare il lavoro:

  1. Run R dalla stessa directory avete compilato le librerie.

  2. Impostare la LD_LIBRARY_PATH (Linux) o DYLD_LIBRARY_PATH (OS X) prima di lanciare R.

    DYLD_LIBRARY_PATH=/path/to/rust/lib/ R 
    
  3. Si dovrebbe essere in grado di impostare la rpath quando si costruisce la libreria condivisa.

    g++ -shared treble.cxx -o treble.so -L/tmp/ -Wl,-rpath,/tmp -lglue 
    

    Tuttavia, non ero in grado di farlo funzionare bene su OS X, quindi non sono sicuro di quello che sto facendo male.

  4. (OS X) Dopo aver costruito la libreria C++, è possibile modificare il installare nome che si riferisce alla biblioteca Rust originale e includere il percorso assoluto:

    install_name_tool -change libglue.dylib /tmp/libglue.dylib treble.so 
    

In sostanza, si vorrà cercare come avere librerie condivise che dipendono da altre librerie condivise quando più di quelle librerie non esistono nei percorsi di ricerca del linker predefinito.

Fonti

Linking a dynamic library (libjvm.dylib) in Mac OS X (rpath issue)

Print rpath of executable on OSX

@executable_path, @load_path and @rpath

How do I modify the install name of a .dylib at build time

clang, change dependent shared library install name at link time

+0

Grazie! Leggerò di più su Rpaths ma sono stato in grado di caricare la libreria condivisa avviando R dalla stessa directory. Ho imparato molto a fare queste due domande. – Zelazny7

0

Sebbene la risposta originale sia buona, ho proposto un approccio alternativo per questo here.

Problemi correlati