Je comprends comment définir des objets partagés au moment de la liaison/compilation. Cependant, je me demande toujours comment les exécutables recherchent l'objet partagé (*.so
bibliothèques) au moment de l'exécution.
Par exemple, mon application a.out
appelle les fonctions définies dans le lib.so
bibliothèque. Après la compilation, je déplace lib.so
vers un nouveau répertoire dans mon $HOME
.
Comment puis-je dire a.out
pour aller le chercher là-bas?
Le HOWTO de la bibliothèque partagée explique la plupart des mécanismes impliqués, et le manuel du chargeur dynamique va plus en détail. Chaque variante Unix a sa propre façon, mais la plupart utilisent le même format exécutable ( ELF ) et ont des linkers dynamiques (dérivés de Solaris). Ci-dessous, je vais résumer le comportement courant en mettant l'accent sur Linux; consultez les manuels de votre système pour l'histoire complète.
En bref, quand il cherche une bibliothèque dynamique (.so
fichier), l'éditeur de liens essaie:
LD_LIBRARY_PATH
variable d'environnement (DYLD_LIBRARY_PATH
sur OSX);/etc/ld.so.conf
plus /lib
et /usr/lib
.Le rpath est stocké dans l'exécutable (c'est le DT_RPATH
ou DT_RUNPATH
attribut dynamique). Il peut contenir des chemins absolus ou des chemins commençant par $Origin
pour indiquer un chemin par rapport à l'emplacement de l'exécutable (par exemple, si l'exécutable est dans /opt/myapp/bin
et son chemin d'accès est $Origin/../lib:$Origin/../plugins
alors l'éditeur de liens dynamique cherchera dans /opt/myapp/lib
et /opt/myapp/plugins
). Le chemin d'accès est normalement déterminé lors de la compilation de l'exécutable, avec le -rpath
option à ld
, mais vous pouvez la changer ensuite avec chrpath
.
Dans le scénario que vous décrivez, si vous êtes le développeur ou le conditionneur de l'application et que vous prévoyez de l'installer dans un …/bin
, …/lib
structure, puis liez avec -rpath='$Origin/../lib'
. Si vous installez un binaire précompilé sur votre système, placez la bibliothèque dans un répertoire sur le chemin de recherche (/usr/local/lib
si vous êtes l'administrateur système, sinon un répertoire que vous ajoutez à $LD_LIBRARY_PATH
), ou essayez chrpath
.
Sous Linux, le comportement est expliqué dans la page de manuel ld(1)
The linker uses the following search paths to locate required shared libraries: 1. Any directories specified by -rpath-link options. 2. Any directories specified by -rpath options. The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option. 3. On an ELF system, for native linkers, if the -rpath and -rpath-link options were not used, search the contents of the environment variable "LD_RUN_PATH". 4. On SunOS, if the -rpath option was not used, search any directories specified using -L options. 5. For a native linker, the search the contents of the environment variable "LD_LIBRARY_PATH". 6. For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared library are searched for shared libraries needed by it. The "DT_RPATH" entries are ignored if "DT_RUNPATH" entries exist. 7. The default directories, normally /lib and /usr/lib. 8. For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file. If the required shared library is not found, the linker will issue a warning and continue with the link.
Je suis sûr que la réponse ici est ldconfig
.
ldconfig crée les liens et le cache nécessaires vers les bibliothèques partagées les plus récentes trouvées dans les répertoires spécifiés sur la ligne de commande, dans le fichier /etc/ld.so.conf et dans les répertoires approuvés (/ lib et/usr/lib). Le cache est utilisé par l'éditeur de liens d'exécution, ld.so ou ld-linux.so. ldconfig vérifie l'en-tête et les noms de fichiers des bibliothèques rencontrées lors de la détermination des versions dont les liens doivent être mis à jour.
Pour exécuter des applications, le fichier /proc/1234/maps
contient toutes les bibliothèques liées dynamiquement.
Où 1234
est le pid de l'exécutable en cours d'exécution.
Linux suit LD_LIBRARY_PATH et d'autres variables, comme indiqué en réponse par Gilles.