web-dev-qa-db-fra.com

Liaison statique et dynamique / partagée avec MinGW

Je veux commencer par une simple utilisation de liens pour expliquer mon problème. Supposons qu'il existe une bibliothèque z qui pourrait être compilée dans la bibliothèque partagée libz.dll (D: /libs/z/shared/libz.dll) ou dans la bibliothèque statique libz.a (D:/libs/z/statique/libz.a).

Permettez-moi de lier contre elle, alors je fais ceci:

gcc -o main.exe main.o -LD:/libs/z/static -lz

Selon cette documentation , gcc rechercherait libz.a, qui est

fichiers d'archive dont les membres sont des fichiers objets

Je peux également faire ce qui suit:

gcc -o main.exe main.o -LD:/libs/z/shared -lz

Il n'est pas mentionné dans la documentation ci-dessus que -l le drapeau recherchera lib<name>.so.

Que se passera-t-il si je libz.a et libz.dll seront dans le même répertoire? Comment la bibliothèque sera-t-elle liée à un programme? Pourquoi j'ai besoin des drapeaux -Wl,-Bstatic et -Wl,-Bdynamic si -l recherche les bibliothèques partagées et statiques?

Pourquoi certains développeurs fournissent des fichiers .a avec des fichiers .dll pour les mêmes modules, si je compile une distribution de bibliothèque partagée?

Par exemple, Qt fournit des fichiers .dll dans le répertoire bin avec des fichiers .a dans le répertoire lib. Est-ce la même bibliothèque, mais construite comme partagée et statique, respectivement? Ou les fichiers .a sont-ils des sortes de bibliothèques factices qui assurent la liaison avec les bibliothèques partagées, où il existe de véritables implémentations de bibliothèques?

Un autre exemple est la bibliothèque OpenGL sous Windows. Pourquoi chaque compilateur doit fournir la bibliothèque OpenGL statique comme libopengl32.a dans MingW?

À quoi servent les fichiers avec les extensions .dll.a et .la?

P.S. Il y a beaucoup de questions ici, mais je pense que chacune dépend de la précédente et il n'est pas nécessaire de les diviser en plusieurs questions.

27
Yuki

Veuillez consulter ld et WIN32 (cygwin/mingw) . En particulier, la liaison directe vers une section dll pour plus d'informations sur le comportement de -l drapeau sur les ports Windows de LD. Extrait:

Par exemple, lorsque ld est appelé avec l'argument -lxxx, il tentera de trouver, dans le premier répertoire de son chemin de recherche,

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll

avant de passer au répertoire suivant du chemin de recherche.

(*) En fait, ce n'est pas cygxxx.dll mais est en fait <prefix>xxx.dll, où <prefix> est défini par l'option ld -dll-search-prefix=<prefix>. Dans le cas de cygwin, le fichier de spécifications gcc standard comprend -dll-search-prefix=cyg, donc nous recherchons en fait cygxxx.dll.

REMARQUE: Si vous avez déjà construit Boost avec MinGW, vous vous souvenez probablement que le nom des bibliothèques Boost obéit exactement au modèle décrit dans le lien ci-dessus.

Dans le passé, il y avait des problèmes dans MinGW avec un lien direct vers *.dll, il a donc été conseillé de créer une bibliothèque statique lib*.a avec des symboles exportés de *.dll et liez-le à la place. Le lien vers cette page wiki MinGW est maintenant mort, donc je suppose qu'il devrait être correct de lier directement contre *.dll maintenant. De plus, je l'ai fait moi-même plusieurs fois avec la dernière distribution MinGW-w64, et je n'ai eu aucun problème pour l'instant.

Vous avez besoin d'indicateurs de lien -Wl,-Bstatic et -Wl,-Bdynamic parce que parfois vous voulez forcer la liaison statique, par exemple, lorsque la bibliothèque dynamique du même nom est également présente dans un chemin de recherche:

gcc object1.o object2.o -lMyLib2 -Wl,-Bstatic -lMyLib1 -Wl,-Bdynamic -o output

L'extrait ci-dessus garantit que la priorité de liaison par défaut de -l l'indicateur est remplacé pour MyLib1, c'est-à-dire même si MyLib1.dll est présent dans le chemin de recherche, LD choisira libMyLib1.a pour établir un lien. Notez que pour MyLib2 LD préférera à nouveau la version dynamique.

REMARQUE: Si MyLib2 dépend de MyLib1, puis MyLib1 est également lié dynamiquement, indépendamment de -Wl,-Bstatic (c'est-à-dire qu'il est ignoré dans ce cas). Pour éviter cela, vous devez lier MyLib2 statiquement aussi.

28