Previous: El lanzamiento inicial a partir de la semilla binaria reducida, Up: Lanzamiento inicial [Contents][Index]
La figura previa muestra el auténtico inicio del grafo de dependencias de la
distribución, correspondiente a las definiciones de paquete del módulo
(gnu packages bootstrap)
. Un gráfico similar puede generarse con
guix graph
(see Invocación de guix graph
), más o menos así:
guix graph -t derivation \ -e '(@@ (gnu packages bootstrap) %bootstrap-gcc)' \ | dot -Tps > gcc.ps
o, para la semilla binaria aún más reducida del lanzamiento inicial
guix graph -t derivation \ -e '(@@ (gnu packages bootstrap) %bootstrap-mes)' \ | dot -Tps > mes.ps
En este nivel de detalle, las cosas son ligeramente complejas. Primero,
Guile en sí consiste en un ejecutable ELF, junto a muchas fuentes y archivos
compilados Scheme que se cargan dinámicamente durante la ejecución. Esto se
almacena en el archivador tar guile-2.0.7.tar.xz mostrado en este
grafo. Este archivador es parte de la distribución de “fuentes” de Guix, y
se inserta en el almacén con add-to-store
(see El almacén).
¿Pero cómo escribimos una derivación que extraiga este archivador y lo añada
al almacén? Para resolver este problema, la derivación
guile-bootstrap-2.0.drv
—la primera en construirse—usa bash
como su constructor, que ejecuta build-bootstrap-guile.sh
, que a su
vez llama a tar
para extraer el archivador. Por tanto, bash,
tar, xz y mkdir son binarios enlazados estáticamente,
también parte de la distribución de fuentes de Guix, cuyo único propósito es
permitir la extracción del archivador de Guile.
Una vez queguile-bootstrap-2.0.drv
se ha construido, tenemos un Guile
funcional que se puede usar para ejecutar los programas de construcción
siguientes. Su primera tarea es descargar los archivadores qu contienen los
otros binarios preconstruidos—esto es lo que las derivaciones
.tar.xz.drv hacen. Módulos Guix como ftp-client.scm
se usan
para este propósito. Las derivaciones module-import.drv
importan esos
módulos en un directorio del almacén, manteniendo la distribución de
carpetas. Las derivaciones module-import-compiled.drv
compilan esos
módulos, y los escriben en un directorio con la distribución de carpetas
correcta. Esto corresponde al parámetro #:modules
de
build-expression->derivation
(see Derivaciones).
Finalmente, los archivadores tar son extraídos por las derivaciones
gcc-bootstrap-0.drv
, glibc-bootstrap-0.drv
, or
bootstrap-mes-0.drv
y bootstrap-mescc-tools-0.drv
, hasta el
punto en el que disponemos de una cadena de herramientas C funcional.
El lanzamiento inicial está completo cuando tenemos una cadena de
herramientas completa que no depende en las herramientas preconstruidas del
lanzamiento inicial descritas previamente. Este requisito de no-dependencia
se verifica comprobando si los archivos de la cadena de herramientas final
contienen referencias a directorios de /gnu/store de las entradas del
lanzamiento. El proceso que lleva a esta cadena de herramientas “final” es
descrito por las definiciones de paquetes encontradas en el módulo
(gnu packages commencement)
.
La orden guix graph
nos permite “distanciarnos” en comparación
con el grafo previo, mirando al nivel de objetos de paquetes en vez de
derivaciones individuales—recuerde que un paquete puede traducirse en
varias derivaciones, típicamente una derivación para descargar sus fuentes,
una para construir los módulos Guile que necesita y uno para realmente
construir el paquete de las fuentes. La orden:
guix graph -t bag \ -e '(@@ (gnu packages commencement) glibc-final-with-bootstrap-bash)' | xdot -
muestra el grafo de dependencias que lleva a la biblioteca C “final”52, mostrado a continuación.
La primera herramienta que se construye con los binarios del lanzamiento
inicial es GNU Make—marcado como make-boot0
en el grafo—,
que es un pre-requisito para todos los paquetes siguientes. Una vez hecho se
construyen Findutils y Diffutils.
Después viene la primera fase de Binutils y GCC, construidas como herramientas pseudo-cruzadas—es decir, con --target igual a --host. Se usan para construir libc. Gracias a este truco de compilación cruzada, se garantiza que esta libc no tendrá ninguna referencia a la cadena de herramientas inicial.
Posteriormente se construyen las herramientas Binutils y GCC (no mostradas
previamente) finales. GCC usa ld
de la construcción final de
Binutils y enlazan los programas contra la libc recién construía. Esta
cadena de herramientas se usa para construir otros paquetes usados por Guix
y el sistema de construcción GNU: Guile, Bash, Coreutils, etc.
¡Y voilà! En este punto tenemos un conjunto completo de herramientas de
construcción esperadas por el sistema de construcción GNU. Están en la
variable %final-inputs
del módulo (gnu packages commencement)
,
y se usan implícitamente por cualquier paquete que use
gnu-build-system
(see gnu-build-system
).
Debido a que la cadena de herramientas final no depende de los binarios de
lanzamiento, estos rara vez necesitan ser actualizados. No obstante, es útil
tener una forma automatizada de producirlos en caso de que se dé una
actualización, y esto es lo que proporciona el módulo (gnu packages
make-bootstrap)
.
La siguiente orden construye los archivadores que contienen los binarios de lanzamiento (Binutils, GCC, glibc para el lanzamiento inicial tradicional y linux-libre-headers, bootstrap-mescc-tools y bootstrap-mes para el lanzamiento inicial basado en la semilla binaria reducida, y Guile y un archivador que contiene una mezcla de Coreutils y otras herramientas básicas de línea de órdenes):
guix build bootstrap-tarballs
Los archivadores “tar” generados son aquellos a cuya referencia debe
encontrarse en el módulo (gnu packages bootstrap)
mencionado al
inicio de esta sección.
¿Todavía aquí? Entonces quizá se habrá empezado a preguntar: ¿cuándo llegamos a un punto fijo? ¡Esa es una pregunta interesante! La respuesta es desconocida, pero si pudiese investigar más a fondo (y tiene unos recursos computacionales y de almacenamiento significativos para hacerlo) háganoslo saber.
Nuestros binarios de lanzamiento actualmente incluyen GCC, GNU Libc, Guile, etc. ¡Eso es mucho código binario! ¿Por qué es eso un problema? Es un problema porque esos grandes fragmentos de código binario no son auditables en la práctica, lo que hace difícil establecer qué código fuente los produjo. Cada binario no-auditable también nos deja vulnerables a puertas traseras en los compiladores, como describió Ken Thompson en su publicación de 1984 Reflections on Trusting Trust.
Esto se mitiga por el hecho de que nuestros binarios de lanzamiento fueron generados por una revisión anterior de Guix. No obstante, esto no posee el nivel de transparencia que obtenemos en el resto del grado de dependencias de los paquetes, donde Guix siempre nos da una asociación de fuente-a-binario. Por lo tanto, nuestro objetivo es reducir el conjunto de binarios de lanzamiento al mínimo posible.
El sitio web Bootstrappable.org enumera proyectos en activo realizándolo. Uno de ellos está a punto de sustituir el GCC de lanzamiento con una secuencia de ensambladores, interpretes y compiladores de complejidad incremental, que pueden ser construidos desde las fuentes empezando con un código ensamblador simple y auditable.
Nuestro primer logro de importancia es la sustitución de GCC, la biblioteca de C de GNU y Binutils por MesCC-Tools (un enlazador hexadecimal y un macro-ensamblador) y Mes (see GNU Mes Reference Manual in GNU Mes, un intérprete de Scheme y compilador de C en Scheme). Ni MesCC-Tools ni Mes pueden lanzarse inicialmente a sí mismas completamente todavía y por lo tanto se inyectan como semillas binarias. A esto es lo que llamamos la semilla binaria reducida del lanzamiento inicial, ¡ya que ha reducido a la mitad el tamaño de nuestros binarios del lanzamiento inicial! También ha eliminado el binario del compilador de C; los paquetes de Guix en i686-linux y x86_64-linux se generan a partir de un lanzamiento inicial sin ningún binario que sea un compilador de C.
Se está trabajando en hacer que MesCC-Tools y Mes puedan lanzarse inicialmente de manera completa, y también se buscan otros binarios para el lanzamiento inicial. ¡Su ayuda es bienvenida!
Puede haberse dado cuenta de la etiqueta
glibc-intermediate
, sugiriendo que no es completamente final,
pero como es una buena aproximación, la consideraremos final.