He estado investigando la creación de cadenas de herramientas cruzadas y tengo una pregunta general sobre la compilación y el funcionamiento de gcc.
La pregunta es sobre este extracto de la documentación oficial de gcc :
Para compilar GCC, la biblioteca estándar de C y los encabezados deben estar presentes para todas las variantes de destino para las que se compilarán las bibliotecas de destino (y no solo la variante del compilador host C++).
¿Por qué se requiere la biblioteca estándar del objetivo para construir el compilador (cruzado) en sí? ¿No debería el compilador (cruzado) que se ejecuta en el host solo requerir que se construya la biblioteca estándar del host y luego poder compilar la biblioteca estándar del objetivo?
También encontré esto en crosstool-NG sobre cómo se construye una cadena de herramientas :
el compilador final necesita la biblioteca C, para saber cómo usarla, pero: construir la biblioteca C requiere un compilador
Esto es consistente con lo que se indicó anteriormente, pero no entiendo por qué el compilador final debe construirse contra una biblioteca C de destino preconstruida solo para saber cómo usarlo más adelante. ¿Qué debe saber el compilador del host sobre la biblioteca C de destino? ¿No es el trabajo del enlazador vincular los programas de destino con la biblioteca estándar del destino en tiempo de compilación?
Porque esa es la única forma de garantizar que se cree un compilador que funcione para la plataforma de destino. No tiene sentido crear un compilador que no funcione, distribuirlo a la plataforma de destino y descubrir que es inútil.
En general, un archivo ejecutable de objeto no compartido solo se crea correctamente si no hay símbolos sin resolver.
Según la documentación de GCC 11.2 "Opciones generales"
La compilación puede implicar hasta cuatro etapas: preprocesamiento, compilación propiamente dicha, ensamblaje y enlace, siempre en ese orden. GCC es capaz de preprocesar y compilar varios archivos en varios archivos de entrada del ensamblador o en un archivo de entrada del ensamblador; luego, cada archivo de entrada del ensamblador produce un archivo de objeto, y la vinculación combina todos los archivos de objeto (los recién compilados y los especificados como entrada) en un archivo ejecutable.
Entonces, el paso final es vincular. La página de manual de GNU linker 'ld' dice:
Normalmente, el enlazador generará un mensaje de error para cada símbolo sin resolver notificado, pero la opción
--warn-unresolved-symbolspuede cambiar esto a una advertencia.
y
--error-unresolved-symbols Esto restaura el comportamiento predeterminado del enlazador de generar errores cuando informa sobre símbolos no resueltos.
Entonces, por defecto, la vinculación falla cuando hay símbolos sin resolver.
¿Por qué?
Porque si hay símbolos sin resolver, el archivo ejecutable resultante no funcionará cuando se ejecute.
Y la única forma de asegurarse de que no haya símbolos sin resolver es tener todas las bibliotecas necesarias de la plataforma de destino disponibles cuando se realice la compilación cruzada para que todos los símbolos se puedan resolver cuando se vinculen los nuevos ejecutables del compilador.