web-dev-qa-db-fra.com

Comment créer un lien statique sur OS X

J'essaie de créer un lien vers une bibliothèque statique sur OS X. J'ai utilisé le -static flag dans la commande gcc mais j'obtiens le message d'erreur suivant:

 ld_classic: impossible de localiser le fichier pour: -lcrt0.o 
 collect2: ld a renvoyé 1 état de sortie 

J'ai regardé dans les pages de manuel et il se lit quelque chose comme:

Cette option ne fonctionnera pas sur Mac OS X à moins que toutes les bibliothèques (y compris libgcc.a) aient également été compilées avec -static. Puisqu'aucune version statique de libSystem.dylib ni crt0.o n'est fournie, cette option n'est pas utile à la plupart des gens.

Existe-t-il un autre moyen de créer un lien vers cette bibliothèque statique?

48
Frank

Pour créer un lien vers une bibliothèque d'archives (parfois aussi appelée bibliothèque statique), il suffit de l'ajouter à la ligne de lien:

gcc main.o ... -lfoo ...

L'éditeur de liens recherchera libfoo.dylib, puis libfoo.a, qui est tout ce dont vous avez besoin.

Si vous avez les deux versions de la bibliothèque et que vous souhaitez créer un lien avec une version d'archive de préférence à la version dynamique, spécifiez simplement le chemin d'accès complet à l'archive sur la ligne de lien:

gcc main.o ... /path/to/libfoo.a ...
53
Employed Russian

Malheureusement, ce n'est pas pris en charge . Certaines personnes ont signalé qu'il était possible de compiler manuellement crt0 mais personne ne le confirme .

15
alecco

Un cas courant est de lien statique contre une troisième bibliothèque utilisateur tout en se liant dynamiquement contre les frameworks système et les bibliothèques, afin que vos utilisateurs n'aient pas besoin d'installer des bibliothèques tierces avant d'utiliser votre programme. Si la bibliothèque est liée dynamiquement aux frameworks (comme c'est souvent le cas), elle peut toujours être livrée avec un .a statique, mais il ne suffit pas de remplacer -l<libname> avec /path/to/libname.a car le .a ne contiendra pas les dépendances. Vous devrez également établir un lien dynamique avec les frameworks que votre bibliothèque utilisait.

Par exemple, supposons que vous souhaitiez écrire un programme qui utilise la libusb open source sans obliger votre utilisateur à télécharger et installer libusb. Supposons que vous ayez créé un binaire lié dynamiquement avec ceci:

clang -lusb-1.0 main.c -o myprogram

Pour lier statiquement sous OS X, la commande ressemble à ceci (notez le -framework arguments):

clang -framework CoreFoundation -framework IOKit main.c /path/to/libusb-1.0.a -o myprogram

Pour trouver les frameworks et bibliothèques système que vous devez ajouter, consultez le dylib tiers utilisant otool:

otool -L /usr/local/opt/libusb/lib/libusb-1.0.0.dylib

qui montre:

/usr/local/opt/libusb/lib/libusb-1.0.0.dylib:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)  

Vous pouvez commencer par ajouter les frameworks, puis les bibliothèques une par une et vous verrez la liste des erreurs de référence non définies se réduire. Notez que vous n'aurez probablement pas besoin d'ajouter toutes les bibliothèques, car certaines peuvent être chargées en tant que dépendances pour celles que vous avez explicitement ajoutées.

Si vous ne savez pas où se trouve le dylib, construisez votre programme de la manière dynamique d'origine (avec -lusb-1.0), et exécutez otool dessus:

clang -lusb-1.0 main.c -o myprogram
otool -L myprogram

qui donne:

myprogram:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)

Lisez également la licence de la bibliothèque à laquelle vous créez un lien.

10
Michael Chinen

-Bstatic semble être un no-op sur OS-X Lion - utilisé gcc -v pour le confirmer.

7
atrens

J'ai rencontré le même problème. Voici un exemple à contourner:

ÉTAPE 1: créer des fichiers

myfunc1.c:

#include <stdio.h>

void myfunc1() {
    printf( "This is my func1!\n" );
}

myfunc2.c:

#include <stdio.h>

void myfunc2() {
    printf( "This is my func2!\n" );
}

et myfunc.c:

#include <stdio.h>

void myfunc1( void );
void myfunc2( void );

int main() {
    myfunc1();
    myfunc2();
    return 0;
}

ÉTAPE2: ​​créer la lib

gcc -c myfunc1.c myfunc2.c

ar -r libmyfuncs.a myfunc1.o myfunc2.o

ÉTAPE3: lien

gcc -o myfunc -L. myfunc.c -lmyfuncs 

N'oubliez pas de taper "-L."; le point indique le chemin actuel.

J'espère que cela pourra aider.

0
Zhi Q.