funciones - principales librerias en lenguaje c
¿Dónde están definidas las funciones en la biblioteca estándar de C? (5)
No estoy interesado en el código fuente, quiero saber cómo el compilador de C (GCC) realmente encuentra las funciones. Como en, cuando el preprocesador ve que he incluido stdio.h
, ¿dónde busca los archivos que definen los cuerpos de función?
Editar
Probablemente debería decir también que estoy usando Ubuntu 12.04, pero si hay una respuesta general, eso también funcionaría.
Mira las rutas de la biblioteca establecidas por la variable de entorno.
Su libc
(o libstdc++
para C ++) puede encontrarse en /usr/lib
o /usr/lib64
en Linux. Estas son bibliotecas compartidas y puede modificar la variable LD_LIBRARY_PATH
para especificar en qué directorios se buscan. Un ejemplo práctico sería instalar una copia local de gcc y es posible que tenga una versión actualizada de la biblioteca estándar en lugar de su biblioteca. sistema, por lo que desearía que su gcc local se inicie con eso, es decir, export LD_LIBRARY_PATH=/home/user/local-install/gcc/lib64
Su pregunta tiene que ver con dónde GCC busca archivos de encabezado. Busca los directorios de inclusión estándar. Puede encontrar este hilo para ser útil:
Con varias opciones (como -I y -I- y -isistema) puede especificar muchas características de inclusión diferentes. Básicamente, los directorios especificados por -I se buscarán antes que los especificados por -isistema, que a su vez se buscarán antes que los del "sistema estándar incluyen directorios" (al menos, de acuerdo con mis pruebas). La diferencia es que se puede usar -I para cualquier directiva #include, pero -isistema solo se usará para #include <...> Dicho esto, sin embargo, se recomienda usar solo -I para #include "... "Directivas debido al orden de búsqueda. Usar -I- realmente le da mucho control porque cualquier -I usado antes -I- se buscará solo para #include "..." mientras que cualquier -I usado después de -I- se buscará cualquier directiva #include . Además, usar -I- significa que no se buscarán los archivos incluidos en el directorio actual a menos que también especifique -I. (buscar el directorio actual).
Si desea obtener una lista de los directorios de búsqueda que son compatibles de forma predeterminada, intente ejecutar este comando:
cpp -v < /dev/null
Esto ejecuta el preprocesador C de GNU sin entrada; en el proceso, imprimirá (dada la marca -v) las rutas de búsqueda del directorio de inclusión. Debería ver frases como "#include <...> la búsqueda comienza aquí:" seguida de una lista de directorios. Esas son las rutas de búsqueda de inclusión estándar, en el orden en que se buscan.
gcc
obtiene las definiciones de funciones de la biblioteca C. Podría determinar la ruta que gcc
buscaría, por defecto, diciendo:
ld --verbose | grep SEARCH_DIR
Esto lleva a /usr/lib
en mi sistema.
Intentemos buscar si la biblioteca contiene el símbolo para una función estándar, digamos scanf
:
nm -A /usr/lib/libc.so | grep scanf
Los resultados incluyen:
/lib/libc.so:0000000000042a90 T scanf
Considere un pequeño ejemplo:
#include <stdio.h>
int main() {
printf("Hello World!/n");
return 0;
}
Llamémoslo ic
:
$ gcc i.c # Compile
$ ldd ./a.out # Try to find dependencies
./a.out:
-lc.12 => /usr/lib/libc.so.12
El último comando esencialmente implica que el binario depende de /usr/lib/libc.so.12
y que encontrará las definiciones de las funciones utilizadas en el código.
gcc
viene con archivos de objeto (binarios) ( no archivos de fuente C) que contienen implementaciones de todas las funciones C estándar. Cuando utiliza gcc
para vincular archivos de objeto en un archivo ejecutable, el enlazador incluye automáticamente los archivos de objeto que implementan las funciones estándar de la biblioteca. De acuerdo con este hilo , ese archivo de objeto estándar probablemente se llamará libc.a
o libc.so
Digamos que incluye una llamada a printf
en su programa. Cuando el enlazador intenta resolver dónde debería ir esa llamada, encontrará la definición de printf
en libc.a
, y hará que su función llame al punto.
Consulte http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html y observe las opciones -nostdlib
y -nodefaultlibs
. Puede usar estas opciones para decirle al enlazador de gcc
no incluya los archivos de objetos de biblioteca estándar de forma predeterminada.