GNU/Linux >> Tutoriels Linux >  >> Linux

Vous ne trouvez pas .so dans le même répertoire que l'exécutable ?

Solution 1 :

Bien que vous puissiez définir LD_LIBRARY_PATH pour que l'éditeur de liens dynamique sache où chercher, il existe de meilleures options. Vous pouvez mettre votre bibliothèque partagée dans l'un des emplacements standard, voir /etc/ld.so.conf (sous Linux) et /usr/bin/crle (sur Solaris) pour la liste de ces lieux

Vous pouvez passer -R <path> au linker lors de la construction de votre binaire, ce qui ajoutera <path> à la liste des répertoires analysés pour votre bibliothèque partagée. Voici un exemple. D'abord, montrant le problème :

libtest.h :

void hello_world(void);

libtest.c :

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

bonjour.c :

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

Makefile (les onglets doivent être utilisés) :

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

Exécutons-le :

$ 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

Comment le réparer? Ajouter -R <path> aux drapeaux de l'éditeur de liens (ici, en définissant 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!

En regardant le binaire, vous pouvez voir qu'il a besoin de libtest.so.0 :

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

Le binaire cherchera ses bibliothèques, en dehors des emplacements standards, dans le répertoire spécifié :

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

Si vous voulez que le binaire regarde dans le répertoire courant, vous pouvez définir le RPATH sur $ORIGIN . C'est un peu délicat, car vous devez vous assurer que le signe dollar n'est pas interprété par make. Voici une façon de procéder :

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

Solution 2 :

Le chargeur ne vérifie jamais le répertoire actuel pour les objets partagés à moins qu'il ne soit explicitement dirigé via $LD_LIBRARY_PATH . Voir le ld.so(8) page de manuel pour plus de détails.

Solution 3 :

Pour charger les objets partagés depuis le même répertoire que votre exécutable, exécutez simplement :

$ LD_LIBRARY_PATH=. ./binary

Remarque :Cela ne modifiera pas la variable LD_LIBRARY_PATH de votre système. Le changement n'affecte que cela, et uniquement cela, l'exécution de votre programme.

Solution 4 :

Pour tous ceux qui utilisent CMake pour leur build, vous pouvez définir le CMAKE_EXE_LINKER_FLAGS à ce qui suit :

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

Cela propagera correctement les drapeaux de l'éditeur de liens pour tous les types de construction (par exemple, Debug, Release, etc.) pour rechercher d'abord les fichiers .so dans le répertoire de travail actuel.

Solution 5 :

Pour tous ceux qui se débattent encore sans réponse, j'en ai trouvé une moi-même avec la suggestion suivante :

Vous pouvez essayer de mettre à jour le ld.so.cache en utilisant :sudo ldconfig -v

A travaillé pour moi.


Linux
  1. Comment trouver le fichier le plus ancien dans une arborescence de répertoires sous Linux

  2. Faire référence à un fichier sous le même répertoire qu'un script trouvé dans $path ?

  3. Comment puis-je calculer une somme de contrôle md5 d'un répertoire?

  4. Où se trouve le fichier d'en-tête <conio.h> sous Linux ? Pourquoi ne puis-je pas trouver <conio.h> ?

  5. Comment puis-je exécuter dos2unix sur un répertoire entier ?

Comment trouver la taille d'un répertoire sous Linux

Comment trouver la taille totale d'un répertoire sous Linux

Corrigez l'erreur impossible de trouver la commande hwmatch sur Grub

La commande Linux find Directory :Explication

Où puis-je trouver la première version du système d'exploitation Linux ?

Comment dissocier tous les liens symboliques sous le répertoire ?