Comment puis-je relier statiquement uniquement certaines bibliothèques spécifiques à mon binaire lors de la liaison avec GCC?
gcc ... -static ...
essaie de lier statiquement toutes les bibliothèques liées, mais je n'ai pas la version statique de certaines d'entre elles (par exemple: libX11).
gcc
linker
static-libraries
peoro
la source
la source
Réponses:
gcc -lsome_dynamic_lib code.c some_static_lib.a
la source
code.c
fichier garantit que les symboles qu'il contient seront ignorés à moins qu'il ne se produise unemain()
fonction dans l'un des fichiers objets de la bibliothèque.Vous pouvez également utiliser l'
ld
option-Bdynamic
Toutes les bibliothèques suivantes (y compris celles système liées automatiquement par gcc) seront liées dynamiquement.
la source
vous pouvez également utiliser: des
-static-libgcc -static-libstdc++
indicateurs pour les bibliothèques gccgardez à l'esprit que si
libs1.so
et leslibs1.a
deux existent, l'éditeur de liens choisiralibs1.so
si c'est avant-Wl,-Bstatic
ou après-Wl,-Bdynamic
. N'oubliez pas de passer-L/libs1-library-location/
avant d'appeler-ls1
.la source
-static
quelque part dans la commande échoue (je suppose qu'elle essaie de lier plus de choses statiquement que seulement les bibliothèques que je veux).-Wl,-Bstatic
et-Wl,-Bdynamic
est important.Depuis la page de manuel de
ld
(cela ne fonctionne pas avec gcc), en se référant à l'--static
option:Une solution consiste à placer vos dépendances dynamiques avant l'
--static
option sur la ligne de commande.Une autre possibilité est de ne pas utiliser
--static
, mais plutôt de fournir le nom / chemin complet du fichier objet statique (c'est-à-dire sans utiliser l'option -l) pour créer une liaison statique dans une bibliothèque spécifique. Exemple:Comme vous pouvez le voir dans l'exemple,
libX11
n'est pas dans la liste des bibliothèques liées dynamiquement, car il était lié statiquement.Attention: un
.so
fichier est toujours lié dynamiquement, même lorsqu'il est spécifié avec un nom de fichier / chemin complet.la source
ldd a.out
?ldd
renvoie les bibliothèques partagées requises et libX11 n'apparaît pas dans cette liste.Le problème tel que je le comprends est le suivant. Vous disposez de plusieurs bibliothèques, certaines statiques, d'autres dynamiques et d'autres à la fois statiques et dynamiques. Le comportement par défaut de gcc est de lier "principalement dynamique". Autrement dit, gcc crée des liens vers des bibliothèques dynamiques lorsque cela est possible, mais revient autrement aux bibliothèques statiques. Lorsque vous utilisez l' option -static pour gcc, le comportement consiste à ne lier que les bibliothèques statiques et à quitter avec une erreur si aucune bibliothèque statique ne peut être trouvée, même s'il existe une bibliothèque dynamique appropriée.
Une autre option, que j'ai à plusieurs reprises souhaité que gcc ait, est ce que j'appelle -mostly-static et est essentiellement l'opposé de -dynamic (la valeur par défaut). -mostly-static , s'il existait, préférerait se lier à des bibliothèques statiques mais retomberait dans des bibliothèques dynamiques.
Cette option n'existe pas mais elle peut être émulée avec l'algorithme suivant:
Construire la ligne de commande de lien sans inclure -static .
Parcourez les options de lien dynamique.
Accumuler les chemins de bibliothèque, c'est-à-dire les options de la forme -L <lib_dir> dans une variable <lib_path>
Pour chaque option de lien dynamique, c'est-à-dire celles de la forme -l <lib_name> , exécutez la commande gcc <lib_path> -print-file-name = lib <lib_name> .a et capturez la sortie.
Si la commande imprime autre chose que ce que vous avez transmis, ce sera le chemin complet de la bibliothèque statique. Remplacez l'option de bibliothèque dynamique par le chemin complet de la bibliothèque statique.
Rincez et répétez jusqu'à ce que vous ayez traité toute la ligne de commande du lien. En option, le script peut également prendre une liste de noms de bibliothèques à exclure de la liaison statique.
Le script bash suivant semble faire l'affaire:
Par exemple:
sur mon système renvoie:
ou avec une exclusion:
J'obtiens alors:
la source
Il existe également une
-l:libstatic1.a
variante (moins l deux-points) de l'option -l dans gcc qui peut être utilisée pour lier une bibliothèque statique (Merci à https://stackoverflow.com/a/20728782 ). Est-ce documenté? Pas dans la documentation officielle de gcc (ce qui n'est pas exact pour les bibliothèques partagées également): https://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlLe doc binutils ld le décrit. L'
-lname
option rechercheralibname.so
alors l'libname.a
ajout du préfixe lib et.so
(si activé pour le moment) ou du.a
suffixe. Mais l'-l:name
option ne recherchera exactement que le nom spécifié: https://sourceware.org/binutils/docs/ld/Options.htmlLa variante
-l:namespec
est documentée depuis la version 2.18 de binutils (2007): https://sourceware.org/binutils/docs-2.18/ld/Options.htmlla source
Certains chargeurs (linkers) fournissent des commutateurs pour activer et désactiver le chargement dynamique. Si GCC fonctionne sur un tel système (Solaris - et éventuellement d'autres), vous pouvez utiliser l'option appropriée.
Si vous savez quelles bibliothèques vous souhaitez lier statiquement, vous pouvez simplement spécifier le fichier de bibliothèque statique dans la ligne de lien - par chemin complet.
la source
à dynamique de la liaison et la bibliothèque statique dans une ligne, vous devez mettre libs statiques après libs dynamiques et les fichiers d'objets, comme ceci:
gcc -lssl main.o -lFooLib -o main
sinon, cela ne fonctionnera pas. il me faut un certain temps pour le comprendre.
la source