2012-01-01 17 views
13

Me pregunto qué hace la opción estática en gcc. Necesito esta opción al compilar una aplicación determinada, sin embargo, cuando lo haga, me sale el siguiente error:-opción estática para gcc?

gcc -static -O3 -o prog prog.c 
/usr/bin/ld: cannot find -lc 
collect2: ld returned 1 exit status 

Lo que necesita la instalación?

versión de GCC:

[[email protected] dir]$ gcc -v 
Using built-in specs. 
COLLECT_GCC=gcc 
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.6.1/lto-wrapper 
Target: x86_64-redhat-linux 
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux 
Thread model: posix 
gcc version 4.6.1 20110908 (Red Hat 4.6.1-9) (GCC) 

Respuesta

-23

En general, debe evitar vincular estáticamente su aplicación (y debe explicarnos por qué no desea el enlace dinámico habitual). Sugiero al menos vincular dinámicamente las bibliotecas del sistema (libc en particular) - si lo desea, podría vincular bibliotecas menos comunes estáticamente -. ¿Por qué quieres vincular estáticamente tu aplicación? En general, es un error (porque no aprovecha las actualizaciones de las bibliotecas dinámicas del sistema). En particular, name service switch instalaciones de libc quiere bibliotecas dinámicas.

Su sistema debería haber instalado el paquete que proporciona la biblioteca libc estática. En Debian, es el paquete libc-dev pero no sé lo que es en RedHat.

Para averiguar la función, pase gcc que la bandera -v como

gcc -v -static -O3 -o prog prog.c 

Pero no se debe vincular estáticamente sus programas. En mis distribuciones de Debian, hay más de 700 programas en /usr/bin y solo uno está estáticamente vinculado.

+0

No estaba seguro de qué es lo que hace. Estoy usando una aplicación preexistente, y por alguna razón tenía esta opción en su archivo MAKE. En este punto, estoy pensando que ya no debería importar. Gracias. – sj755

+29

-1: Oculta la respuesta en una lo que en gran parte es una diatriba con hechos de apoyo limitados. – mattnz

5

La bandera -static obliga al enlazador para aceptar sólo las bibliotecas estáticas y ninguna bibliotecas compartidas.

Si desea utilizar -static, debe asegurarse de tener instalada una versión estática de la biblioteca C, lo que puede ser difícil de encontrar (la mayoría de los sistemas ya no tienen una biblioteca C estática). O tiene que cancelar el efecto de -static. Sin embargo, en el ejemplo, eso vencería el propósito de -static ya que la única biblioteca vinculada es (implícitamente) la biblioteca C.

+1

¿Hay alguna razón particular por la que no debería ser posible tener simplemente el enlazador estáticamente adjuntar código de cualquier bibliotecas están disponibles para el enlazador?Incluso si las referencias dentro del código están formateadas de tal forma que deben resolverse en tiempo de ejecución, creo que debería ser posible adjuntar las rutinas apropiadas al archivo ejecutable y remendar las referencias para que apunten al código dentro del archivo ejecutable. . – supercat

+0

@supercat: en una biblioteca de archivos ordinaria, los archivos de objetos individuales son identificables por separado y se pueden extraer fácilmente de la biblioteca y vincular al ejecutable. Mi impresión (semi-informada) es que las bibliotecas compartidas no contienen los archivos de objeto por separado de la misma manera, por lo que obtienes todo o no obtienes nada. Me atrevo a decir que podría ser posible simplemente vincular toda la biblioteca compartida en el ejecutable, pero también podría generar una gran cantidad de código no utilizado. Sé que algunas grandes compañías prefieren usar enlaces estáticos para todo, menos riesgo de cambios inesperados. –

+1

Incluso si el código termina teniendo que cargarse dinámicamente, sugiero que las aplicaciones instaladas de forma predeterminada reciban sus propias copias de la mayoría de las bibliotecas. Si las bibliotecas necesitan ser actualizadas, eso podría manejarse haciendo que el sistema operativo guarde para cada programa una configuración de "configuración de actualización" [p. si un programa que usa FooLib 1.7 advierte que "FooLib 1.8" está instalado, podría permitir al usuario ejecutarlo con 1.7 o 1.8 y guardar la selección como predeterminada]. De esa forma, si un programa tiene problemas relacionados con FooLib, el usuario podría actualizarlo, pero las cosas no cambiarían espontáneamente. – supercat

33

La opción -static vincula un programa estáticamente, en otras palabras, no requiere una dependencia de bibliotecas dinámicas en tiempo de ejecución para poder ejecutarse.

Para lograr la vinculación estática requiere que existan las versiones de archivos (.a) de sus bibliotecas en el sistema. so /usr/lib/libc.a /usr/lib/crt1.o etc ...

En los sistemas linux modernos (como se usa el sombrero rojo): cuando un enlace binario se junta, 1) pone el código en el ejecutable a través de archivos .o y .a, o 2) pone referencias a archivos de bibliotecas dinámicas (.so) que se resuelven mediante /lib/ld-linux.so (o/lib64/ld-linux = x86-64. entonces) que siempre está en un lugar conocido.

Para su sistema particular, si un programa está buscando específicamente para crear una versión estática de sí mismo, entonces usted necesita para instalar las versiones estáticas de sus herramientas Devel. Necesita, como mínimo, paquete glibc-estático. También puede necesitar libstdC++ - paquete estático también.

Cuestiones relacionadas