web-dev-qa-db-fra.com

Pourquoi dois-je définir LD_LIBRARY_PATH avec une exportation chaque fois que j'exécute mon application?

J'ai du code qui utilise des bibliothèques partagées (code c sur gcc). Lors de la compilation, je dois définir explicitement les répertoires d'inclusion et de bibliothèque à l'aide de -I et -L, car ils ne sont pas dans les emplacements standard. Lorsque j'essaie d'exécuter le code, j'obtiens l'erreur suivante:

./sync_test 
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory

Cependant, procédez comme suit, tout fonctionne très bien:

export LD_LIBRARY_PATH="/path/to/library/"
./sync_test

Maintenant, la partie étrange est que cela ne fonctionne qu'une seule fois. Si j'essaie de réexécuter sync_test, j'obtiens la même erreur, sauf si j'exécute d'abord la commande d'exportation. J'ai essayé d'ajouter ce qui suit à mon .bashrc, mais cela n'a fait aucune différence:

LD_LIBRARY_PATH="/path/to/library/"
41
Paul Wicks

Utilisation

export LD_LIBRARY_PATH="/path/to/library/"

dans votre .bashrc sinon, il ne sera disponible que pour bash et pas pour les programmes que vous démarrez.

Essayez -R/path/to/library/ flag lorsque vous effectuez une liaison, cela fera que le programme apparaîtra dans ce répertoire et vous n'aurez pas besoin de définir de variables d'environnement.

EDIT: ressemble à -R est uniquement Solaris et vous êtes sous Linux.

Une autre manière serait d'ajouter le chemin d'accès à /etc/ld.so.conf et exécutez ldconfig. Notez qu'il s'agit d'un changement global qui s'appliquera à tous les binaires liés dynamiquement.

42
brian-brazil

Vous devez éviter de définir LD_LIBRARY_PATH dans votre .bashrc. Voir "Why LD_LIBRARY_PATH is bad " pour plus d'informations.

Utilisez l'option de l'éditeur de liens - - rpath lors de la liaison afin que l'éditeur de liens dynamique sache où trouver libsync.so pendant l'exécution.

gcc ... -Wl,-rpath /path/to/library -L/path/to/library -lsync -o sync_test

MODIFIER:

Une autre façon serait d'utiliser un wrapper comme celui-ci

#!/bin/bash

LD_LIBRARY_PATH=/path/to/library sync_test "$@"

Si sync_test démarre tous les autres programmes, ils pourraient finir par utiliser les bibliothèques de /path/to/library qui peut ou non être destiné.

44
sigjuice

Vous pouvez simplement mettre tout cela sur une seule ligne:

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/library" ./sync_test

Devrait rendre les choses un peu plus faciles, même si cela ne change rien de fondamental

10
unwesen

Avez-vous "exporté" votre .bashrc?

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"
10
bedwyr

Au lieu de remplacer le chemin de recherche de la bibliothèque lors de l'exécution avec LD_LIBRARY_PATH, vous pouvez le faire cuire dans le binaire lui-même avec rpath. Si vous établissez un lien avec GCC en ajoutant -Wl,-rpath,<libdir> devrait faire l'affaire, si vous créez un lien avec ld, c'est juste -rpath <libdir>.

4
fgp

Ce que vous pouvez également faire, si c'est quelque chose que vous avez installé sur votre système, est d'ajouter le répertoire qui contient les bibliothèques partagées à votre /etc/ld.so.conf , ou créez un nouveau fichier dans /etc/ld.so.conf.d/

(J'ai vérifié la distribution RHEL5 et Ubuntu donc je pense que c'est générique pour linux)

Le programme ldconfig s'assurera qu'ils sont inclus à l'échelle du système.

Voir le lien suivant pour plus d'informations: www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/dlls.html

2
Roalt

Vous pouvez ajouter dans votre code un système d'appel avec la nouvelle définition:

sprintf(newdef,"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s:%s",ld1,ld2);
system(newdef);

Mais, je ne sais pas si c'est la bonne solution mais ça marche.

Cordialement

1
user3916212