GNU/Linux >> Znalost Linux >  >> Linux

Nemůžete najít .so ve stejném adresáři jako spustitelný soubor?

Řešení 1:

I když můžete nastavit LD_LIBRARY_PATH, aby dynamický linker věděl, kde má hledat, existují lepší možnosti. Sdílenou knihovnu můžete umístit na jedno ze standardních míst, viz /etc/ld.so.conf (v systému Linux) a /usr/bin/crle (na Solarisu) pro seznam těchto míst

Můžete projít -R <path> na linker při sestavování vašeho binárního souboru, který přidá <path> do seznamu adresářů prohledaných pro vaši sdílenou knihovnu. Zde je příklad. Nejprve ukažte problém:

libtest.h:

void hello_world(void);

libtest.c:

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

ahoj.c:

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

Makefile (musí být použity karty):

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

Pojďme to spustit:

$ 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

jak to opravit? Přidejte -R <path> na příznaky linkeru (zde nastavením 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!

Při pohledu na binární soubor můžete vidět, že potřebuje libtest.so.0 :

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

Binární soubor bude hledat své knihovny, kromě standardních míst, v zadaném adresáři:

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

Pokud chcete, aby binární soubor vypadal v aktuálním adresáři, můžete nastavit RPATH na $ORIGIN . To je trochu složitější, protože se musíte ujistit, že znak dolaru není interpretován značkou. Zde je jeden způsob, jak to udělat:

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

Řešení 2:

Zavaděč nikdy nekontroluje sdílené objekty v aktuálním adresáři, pokud není explicitně nasměrován přes $LD_LIBRARY_PATH . Viz ld.so(8) manuálová stránka pro více podrobností.

Řešení 3:

Chcete-li načíst sdílené objekty ze stejného adresáře jako váš spustitelný soubor, jednoduše spusťte:

$ LD_LIBRARY_PATH=. ./binary

Poznámka:Nezmění proměnnou LD_LIBRARY_PATH vašeho systému. Změna ovlivní pouze toto a pouze toto provádění vašeho programu.

Řešení 4:

Pro každého, kdo používá CMake pro své sestavení, můžete nastavit CMAKE_EXE_LINKER_FLAGS na následující:

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

Tím se správně rozšíří příznaky linkeru pro všechny typy sestavení (např. Debug, Release, atd...), aby se nejprve hledaly soubory .so v aktuálním pracovním adresáři.

Řešení 5:

Pro každého, kdo stále bojuje bez odpovědi, jsem sám našel jednu s následujícím návrhem:

Můžete zkusit aktualizovat ld.so.cache pomocí:sudo ldconfig -v

Pracovalo pro mě.


Linux
  1. Jak najít nejstarší soubor ve stromu adresářů v Linuxu

  2. Jaký je nejlepší způsob, jak spočítat počet souborů v adresáři?

  3. Najít soubory, pro které existuje více variant tohoto názvu souboru společně ve stejném adresáři?

  1. jak najít vlastníka souboru nebo adresáře v pythonu

  2. Kde je hlavičkový soubor <conio.h> v systému Linux? Proč nemohu najít <conio.h>?

  3. Jak mohu spustit dos2unix v celém adresáři?

  1. Odkazovat na soubor ve stejném adresáři skriptu nalezeného v $path?

  2. Jak mohu vypočítat kontrolní součet md5 adresáře?

  3. Kde najdu soubor buildinfo.sh?