GNU/Linux >> Linux Esercitazione >  >> Linux

Non riesci a trovare .so nella stessa directory dell'eseguibile?

Soluzione 1:

Mentre puoi impostare LD_LIBRARY_PATH per far sapere al linker dinamico dove cercare, ci sono opzioni migliori. Puoi mettere la tua libreria condivisa in uno dei posti standard, vedi /etc/ld.so.conf (su Linux) e /usr/bin/crle (su Solaris) per l'elenco di questi luoghi

Puoi superare -R <path> al linker durante la creazione del binario, che aggiungerà <path> all'elenco delle directory scansionate per la tua libreria condivisa. Ecco un esempio. Innanzitutto, mostrando il problema:

libtest.h:

void hello_world(void);

libtest.c:

#include <stdio.h>
void hello_world(void) {
  printf("Hello world, I'm a library!\n");
}

ciao.c:

#include "libtest.h"
int main(int argc, char **argv) {
  hello_world();
}

Makefile (devono essere utilizzate le schede):

all: hello
hello: libtest.so.0
%.o: %.c
        $(CC) $(CFLAGS) -fPIC -c -o [email protected] $<
libtest.so.0.0.1: libtest.o
        $(CC) -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
libtest.so.0: libtest.so.0.0.1
        ln -s $< [email protected]
clean:
        rm -f hello libtest.o hello.o libtest.so.0.0.1 libtest.so.0

Eseguiamolo:

$ make
cc  -fPIC -c -o libtest.o libtest.c
cc -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
ln -s libtest.so.0.0.1 libtest.so.0
cc     hello.c libtest.so.0   -o hello
$ ./hello 
./hello: error while loading shared libraries: libtest.so.0: cannot open shared object file: No such file or directory

Come sistemarlo? Aggiungi -R <path> ai flag del linker (qui, impostando LDFLAGS ).

$ make clean
(...)
$ make LDFLAGS="-Wl,-R -Wl,/home/maciej/src/tmp"
(...)
cc   -Wl,-R -Wl,/home/maciej/src/tmp  hello.c libtest.so.0   -o hello
$ ./hello 
Hello world, I'm a library!

Guardando il binario, puoi vedere che ha bisogno di libtest.so.0 :

$ objdump -p hello | grep NEEDED
  NEEDED               libtest.so.0
  NEEDED               libc.so.6

Il binario cercherà le sue librerie, a parte le posizioni standard, nella directory specificata:

$ objdump -p hello | grep RPATH
  RPATH                /home/maciej/src/tmp

Se vuoi che il binario cerchi nella directory corrente, puoi impostare RPATH su $ORIGIN . Questo è un po' complicato, perché devi assicurarti che il simbolo del dollaro non sia interpretato da make. Ecco un modo per farlo:

$ make CFLAGS="-fPIC" LDFLAGS="-Wl,-rpath '-Wl,\$\$ORIGIN'"
$ objdump -p hello | grep RPATH
  RPATH                $ORIGIN
$ ./hello 
Hello world, I'm a library!

Soluzione 2:

Il caricatore non controlla mai la directory corrente per gli oggetti condivisi a meno che non sia esplicitamente diretto tramite $LD_LIBRARY_PATH . Vedi il ld.so(8) pagina man per maggiori dettagli.

Soluzione 3:

Per caricare gli oggetti condivisi dalla stessa directory del tuo eseguibile, esegui semplicemente:

$ LD_LIBRARY_PATH=. ./binary

Nota:non modificherà la variabile LD_LIBRARY_PATH del tuo sistema. La modifica riguarda solo questa, e solo questa, esecuzione del tuo programma.

Soluzione 4:

Per chiunque utilizzi CMake per la propria build, puoi impostare CMAKE_EXE_LINKER_FLAGS al seguente:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'")

Questo propagherà correttamente i flag del linker per tutti i tipi di build (ad es. Debug, Release, ecc...) per cercare prima i file .so nella directory di lavoro corrente.

Soluzione 5:

Per chiunque stia ancora lottando senza una risposta, ne ho trovata una io stesso con il seguente suggerimento:

Potresti provare ad aggiornare ld.so.cache usando:sudo ldconfig -v

Ha funzionato per me.


Linux
  1. Come trovare il file più vecchio in un albero di directory in Linux

  2. Trovare file per i quali più varianti su quel nome file esistono insieme nella stessa directory?

  3. Come posso calcolare un checksum md5 di una directory?

  4. Dove posso trovare il file buildinfo.sh?

  5. Dov'è il file di intestazione <conio.h> su Linux? Perché non riesco a trovare <conio.h>?

Come trovare la dimensione di una directory in Linux

Come trovare la dimensione totale di una directory in Linux

Risolto l'errore, impossibile trovare il comando hwmatch su Grub

Il comando Trova Directory di Linux:spiegato

Come trovo la posizione dell'eseguibile in C?

Dove posso trovare la prima versione del sistema operativo Linux?