Una de las razones es que GCC puede ser construido y utilizado en (por ejemplo, sistemas Unix propietarios como algunos de FreeBSD MacOSX, Solaris, HPUX o) sistemas que tienen su propia biblioteca estándar C .
Incluso en Linux, puede tener una biblioteca estándar C que no sea GNU Glibc . En particular, puede construir GCC (o usarlo) en sistemas Linux con musl-libc o con Bionic (sistemas Android) o con dietlibc , etc. Y un sistema Linux podría tener GNU Glibc y usar algún otro compilador de C (como Clang o TinyCC).
Además, la biblioteca C depende en gran medida del núcleo de Linux. Algunas versiones antiguas del núcleo pueden requerir algún tipo particular (o versión) delibc
Y GCC se puede construir como un compilador cruzado .
Y detalles como "cómo llamar a una main
función" también dependen del compilador, pero de hecho, esos detalles los proporciona libc.so
un sistema Linux.
Eso no es exactamente correcto. La main
función se llama (en un entorno alojado) por el material crt0 , parte del cual es proporcionado por GCC (por ejemplo, /usr/lib/gcc/x86_64-linux-gnu/6/crtbegin.o
en mi Debian / Sid / x86-64 es del libgcc-6-dev
paquete). Lea también sobrelibgcc
En realidad, existe una relación medio oculta entre libc
y GCC, por ejemplo, porque muchos libc
encabezados están (opcionalmente) utilizando algunos atributos incorporados de gcc o funciones .
(por lo tanto, los desarrolladores de GCC y los desarrolladores de GNU libc tienen que interactuar)
.... si cambio el compilador para que funcione con otro ABI ...
Deberá ... /configure
compilar el GCC y reconstruirlo, e incluso podría necesitar parchear el compilador GCC (para describir su ABI y las convenciones de llamadas ). El x32 ABI es un buen ejemplo.
Finalmente, algunos contribuyentes o mantenedores de GCC (incluido yo) han firmado una asignación de derechos de autor que cubre GCC pero no el GNU glibc
.
(con respecto a la licencia de GCC, lea cuidadosamente la excepción de la biblioteca de tiempo de ejecución de GCC )
Tenga en cuenta que algunos encabezados estándar, como <limits.h>
o <stdint.h>
son proporcionados por GCC; otros, como <stdlib.h>
son "arreglados" durante la compilación de GCC: el procedimiento de compilación del compilador los toma de la implementación de Libc y los aplica parches. Aún así, otros encabezados estándar (probablemente <stdio.h>
y los encabezados internos que incluye) se toman del libc
. Lea más sobre GCC FIXINCLUDES y los archivos de encabezado fijo .
(La solución incluye algo que yo (Basile) todavía no entiendo bien)
Puede compilar gcc -v -H
para comprender con mayor precisión qué programas reales se ejecutan (ya que gcc
es un controlador, ejecuta el cc1
compilador, los ld
& collect2
linkers, el as
ensamblador, etc.) y qué encabezados están incluidos, qué bibliotecas y archivos de objetos están vinculados (incluso implícitamente, incluyendo la biblioteca estándar C y el crt0 ). Lea más sobre las opciones de GCC .
Por cierto, puede usar una biblioteca estándar C diferente de la que su GCC espera o para la que fue creada (por ejemplo, musl-libc
o alguna dietlibc ), omitiendo los argumentos adicionales apropiados para gcc
...