2009-05-10 10 views
41

Estoy tratando de vincular a una biblioteca estática en OS X. He utilizado la bandera -static en el comando gcc, pero me sale el siguiente mensaje de error:Cómo estática de enlaces en OS X

 
ld_classic: can't locate file for: -lcrt0.o 
collect2: ld returned 1 exit status 

Miré en las páginas man y lee algo como:

Esta opción no funcionará en Mac OS X a menos que todas las bibliotecas (incluyendo libgcc.a) también se hayan compilado con -static. Como no se proporciona una versión estática de libSystem.dylib ni crt0.o, esta opción no es útil para la mayoría de las personas.

¿Hay alguna otra forma de vincular a esta biblioteca estática?

+1

Los estúpidos documentos de Apple recomiendan enlaces dinámicos, pero no muestran ningún comando 'ld' que realmente lo haga. – mcandre

Respuesta

53

Con el fin de enlazar a una biblioteca de archivo (a veces también llamado biblioteca estática), sólo tiene que añadir a la línea de enlace:

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

El enlazador buscará libfoo.dylib, y luego libfoo.a, que es todo lo que necesitas

Si tiene ambos versiones de la biblioteca, y desea establecer el vínculo con una versión comprimida en la preferencia de la dinámica, basta con especificar la ruta completa al archivo en la línea de enlace:

gcc main.o ... /path/to/libfoo.a ... 
+8

No hay crt0.o o crt0.a ni nada de eso en OS X y XCode. – alecco

+0

@alecco Usted * puede * obtener 'crt0.o' a través de [' Csu'] (https://opensource.apple.com/tarballs/Csu/) (abreviatura de "C start up"), pero lamentablemente 'crt0 .o' no puede enlazar con 'libc' ya que no hay una versión estática de' libSystem.dylib'. Hay más detalles sobre este tema en un [boleto de Github] (https://github.com/skaht/Csu-85/issues/2) para 'Csu'. – GDP2

12

Lamentablemente, it's not supported. Algunas personas informaron que es posible compilar manualmente crt0 pero nobody confirms it.

+3

Parece que '-Bstatic' funciona. – Galaxy

+0

Usted * puede * compilar 'crt0.o' a través de [' Csu'] (https://opensource.apple.com/tarballs/Csu/) (abreviatura de "C start up"), pero lamentablemente 'crt0.o 'no puede enlazar con' libc' ya que no hay una versión estática de 'libSystem.dylib'. Así que sí, no es compatible hasta que Apple nos proporcione una versión estática de 'libSystem.dylib'. O eso o no usas 'libc'. Hay más detalles sobre este [boleto de Github] (https://github.com/skaht/Csu-85/issues/2) para 'Csu'. – GDP2

7

-Bstatic parece ser una operación no operativa en OS-X Lion - gcc -v usado para confirmar esto.

5

Un caso común es enlace estático contra una tercera biblioteca de usuario mientras enlaza dinámicamente con los marcos de sistema y bibliotecas, por lo que los usuarios no necesitan instalar libs de terceros antes de usar su programa. Si la biblioteca está vinculada dinámicamente con marcos (como suele ser el caso), aún puede enviarse con un .a estático, pero no es suficiente reemplazar -l<libname> con /path/to/libname.a porque el .a no tendrá las dependencias en él. También tendrá que vincular dinámicamente con los marcos que su biblioteca estaba usando.

Por ejemplo, supongamos que desea escribir un programa que utiliza el libusb de código abierto sin que el usuario tenga que descargar e instalar libusb. Digamos que tiene un binario enlazado dinámicamente que construyó con esto:

clang -lusb-1.0 main.c -o myprogram 

Para enlazar estáticamente en OS X, el comando es el siguiente (tenga en cuenta las -framework argumentos):

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

Para encontrar marcos qué sistema y las bibliotecas que necesita añadir, miran el dylib terceros usando otool:

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

que muestra:

/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) 

Puede comenzar añadiendo los marcos, seguidos por las bibliotecas de uno en uno y verá cómo se reduce la lista de errores de referencia no definidos.Tenga en cuenta que probablemente no necesite agregar todas las bibliotecas, porque algunas pueden cargarse como dependencias para las que agregó explícitamente.

Si no está seguro de que existe la dylib, construir su programa de la forma dinámica original (con -lusb-1.0), y ejecutar otool en él:

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

lo que da:

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) 

Además, lea la licencia de la biblioteca a la que está enlazando.

0

Me he encontrado con el mismo problema. Este es un ejemplo para trabajar en torno a:

Paso 1: crear archivos

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"); 
} 

y myfunc.c:

#include <stdio.h> 

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

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

PASO 2: crea la lib

gcc -c myfunc1.c myfunc2.c 

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

PASO 3: enlace

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

No se olvide de escribir; "L". dot indica la ruta actual.

Espero que ayude.