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.
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 faitcygxxx.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.