Linux From Scratch IX: Resumen y conclusiones sobre el sistema temporal

Nada mejor para el primer post del año que escribir un nuevo artículo de la serie de Linux From Scratch.  En el artículo anterior había terminado de compilar todo el sistema temporal y había quedado todo listo para empezar con el siguiente capítulo. Sin embargo no voy a hacer eso todavía. Antes de empezar con la verdadera compilación, voy a hacer un pequeño resumen de lo conseguido hasta el momento.

¿Qué hemos hecho hasta ahora?

Hasta ahora lo que hemos hecho ha sido compilar un sistema temporal con las herramientas que vamos a necesitar para compilar el verdadero sistema Linux From Scratch. Estas herramientas todavía no son las definitivas. La razón por la que vamos a hacer la compilación final desde un sistema temporal es para que la configuración de nuestro equipo no afecte a la compilación introduciendo cambios que puedan dar problemas más adelante.

Para conseguir esto, primero se genera un sistema temporal con las herramientas mínimas necesarias y compiladas con las características mínimas para poder compilar todo el sistema sin problemas. Luego se compila todo haciendo un chroot al sistema temporal y, una vez terminado todo el proceso, el sistema temporal deja de tener uso y puede borrarse. Esto último lo haremos en los siguientes posts.

Para evitar que nuestra configuración influya al compilar, se realiza todo el proceso desde una cuenta de usuario creado específicamente para ello. Esa cuenta se crea de forma que tenga la mínima configuración necesaria. Para ello se usan varios trucos. Por ejemplo:

  • Al crear la cuenta, se usa el parámetro -k /dev/null en useradd para que no se copien ficheros al home del usuario. En lugar de ello, se crean a mano los ficheros .bash_profile y bashrc.
  • Usar env en el .bash_profile para lanzar el shell sólo con las variables HOME, TERM y PS1. De forma que las demás variables de entorno no influyan en ese usuario.
  • Desactivar la función hash del bash en el .bashrc y poner /tools/bin en primer lugar en el PATH para que el shell encuentre y use en primer lugar las herramientas que estamos generando en vez de las de nuestro sistema.

Otro de los trucos, quizás el más importante, es hacer compilación cruzada. Mediante compilación cruzada lo que hacemos es generar un toolchain (un conjunto de herramientas de compilación) que sirva para compilar programas para una arquitectura distinta de la nuestra. En este caso, tratamos el sistema Linux From Scratch como si fuera una arquitectura diferente y eso nos permite tener instalado a la vez el toolchain y las herramientas de compilación que trae nuestra distro sin que haya problemas entre ellos.

Para hacer esto, lo importante es la variable LFS_TGT. Esta variable contiene el nombre canónico de la arquitectura para la que se está generando y se usa para identificar las herramientas del toolchain. La forma de hacerlo es colocar el contenido de esta variable como prefijo para el nombre del compilador, linkador, etc generados. Por ejemplo, el compilador para LFS en mi caso se llama x86_64-lfs-linux-gnu-gcc en lugar de simplemente gcc porque la arquitectura de mi Linux From Scratch se llama x86_64-lfs-linux-gnu.

Cómo se genera el toolchain

Todo el proceso explicado aquí está en el capítulo 5.2 del libro, pero se entiende mucho más fácilmente después de hacerlo.

En primer lugar, se compila binutils. Esta compilación todavía no es definitiva, ya que debería compilarse con las librerías de glibc, que todavía no tenemos generadas, pero es necesario generar una primera versión de binutils porque gcc y glibc se compilan con el ensamblador y el linkador de binutils.

En segundo lugar, se compila gcc. Tampoco esta compilación es completa, porque es necesario que use el linkador definitivo de binutils, pero hay que generar una versión en este momento para que glibc use este compilador.

A continuación van los headers del API de linux. La finalidad que tienen es que glibc pueda llamar fácilmente a las funciones del kernel, así que se copian a /tools/include.

Lo siguiente es, por fin, compilar glibc. En este punto ya tenemos todo lo necesario para generar una versión definitiva de glibc para el sistema temporal. Lo importante es usar el parámetro --host en el configure para que use el compilador, ensamblador y linkador que hemos generado en los pasos anteriores.

A continuación se compila binutils por segunda vez. Ahora sí que se genera la versión definitiva. En este paso, se usan las librerías de glibc y el compilador, ensamblador y linkador generados anteriormente. Como el configure no tiene parámetro --host, para hacer esto se usan variables de entorno para especificar las herramientas que deben utilizarse.

Por último, se compila otra vez el gcc para que use, por fin, el linkador generado por la segunda compilación de binutils. Aquí se usa el mismo truco de las variables de entorno para especificar las herramientas a usar.

Y con esto ya está lo más importante instalado. El resto del capítulo compila otras herramientas que también son necesarias para generar el sistema Linux From Scratch definitivo, pero salvo algunos cambios menores, ya se compilan con el método habitual que suele usarse para compilar paquetes de código fuente en linux. Lo más importante es el parámetro --prefix=tools para que deje las herramientas temporales en /tools de forma que estén separadas de las definitivas que se generan en el siguiente capítulo.

Paquetes compilados para el sistema temporal

Pongo a continuación la lista de paquetes que hemos compilado para el sistema temporal. Es bueno conocer un poco de todos.

binutils

El paquete binutils contiene las herramientas básicas de compilación aparte del compilador propiamente dicho. Incluye el ensamblador, el linkador, el archivador para librerías, un profiler y algunas herramientas más.

gcc

El paquete gcc contiene el compilador de C y C++, el preprocesador, una herramienta para crear informes de error, otra para hacer tests de cobertura y algunas librerías que necesitan los programas de este paquete. En especial, la librería de C++. Curiosamente la de C no viene aquí sino en glibc.

linux API headers

En este paquete están los ficheros de cabecera necesarios para que los programas puedan llamar a las funciones del kernel fácilmente. Contiene headers con definiciones y estructuras usadas por el kernel.

glibc

Aquí está la librería de C junto con algunas otras librerías más para cálculos matemáticos, criptografía, gestión de memoria, comunicación de procesos, etc. También está el cargador para librerías dinámicas así como otras herramientas de programación variadas.

tcl

Este paquete contiene el interprete de tcl, un lenguaje de script con una sintaxis sencilla usado para desarrollo rápido de prototipos. Lo usa expect para hacer los tests.

expect

El programa expect sirve para controlar la entrada y la salida de otros programas desde scripts de forma que se puedan automatizar tareas en programas interactivos. DejaGNU usa este programa para los tests.

DejaGNU

DejaGNU es un programa que lanza tests hechos con expect. Los demás paquetes lo usan para los tests que se pasan después de compilar.

check

Check es un framework de test unitarios para C. Contiene la librería con la que se enlazan los programas de test y, por lo tanto, es necesario para compilarlos.

ncurses

Contiene la librería de control de terminal ncurses, que sirve para facilitar la creación de programas de pantalla completa para la terminal. Incluye la base de datos de terminales terminfo y tiene algunas utilidades para la terminal como clear y tput.

bash

El archiconocido bash. El shell por antonomasia de cualquier distribución de GNU/Linux que merezca llevar ese nombre. 🙂

bzip2

Contiene el compresor/descompresor bzip2, uno de los más usados en linux, junto con varias utilidades para trabajar con ficheros comprimidos con bzip2.

coreutils

El paquete coreutils contiene la mayoría de las herramientas básicas en cualquier sistema linux. Incluye cosas como ls, cp, rm, mv, chmod, chown, dd, cut, echo y un largo etcétera de herramientas ampliamente conocidas y algunas no tanto.

diffutils

Este paquete contiene las herramientas clásicas para buscar diferencias entre ficheros: diff, diff3, cmp y sdiff.

file

La herramienta file permite determinar el tipo de un fichero analizando su contenido y buscando algún número mágico que lo identifique.

findutils

En este paquete están las utilidades para buscar ficheros como find, xargs, locate y updatedb.

gawk

Este paquete contiene el interprete de awk, un lenguaje de script orientado a extraer datos a partir de textos, y algunas utilidades relacionadas.

gettext

Aquí hay varias utilidades relacionadas con la localización y la internacionalización, o sea, todo lo que sea traducir textos a varios idiomas. Este paquete permite a los traductores (personas) escribir traducciones de los textos de los programas para varios idiomas y a los programadores acceder fácilmente a esas traducciones desde sus programas.

grep

El paquete grep contiene la conocida herramienta grep para buscar expresiones regulares en un texto, así como otras utilidades asociadas como fgrep y egrep.

gzip

Este paquete contiene el compresor/descompresor gzip y otras utilidades para trabajar con ficheros comprimidos con él. También tiene el comando uncompress, útil para descomprimir ficheros comprimidos con compress, el antiguo compresor de UNIX.

M4

El programa M4 es un preprocesador que algunos programas usan para preprocesar sus ficheros de configuración.

make

La herramienta make es una de las más usadas en el mundo de la programación. Sirve principalmente para compilar programas de forma que en cada compilación sólo se compilen los ficheros que hayan cambiado con respecto a la compilación anterior.

patch

Esta utilidad sirve para aplicar al código fuente parches creados con diff. La usaremos ampliamente para aplicar los parches a la mayoría de los paquetes.

perl

El hermano mayor de awk. Un lenguaje de script que ha nacido como herramienta de extracción de informes y se ha acabado convirtiendo en algo mucho más poderoso. El paquete incluye utilidades para convertir de awk, find o sed a perl, para instalar módulos del cpan, enviar informes de error, leer la documentación de perl, lanzar tests, versiones de tar y sed escritas en perl y muchas más cosas.

sed

Aquí está sed, una de las herramientas más usadas. Se trata de un editor de texto no-interactivo basado en scripts.

tar

Una herramienta de compresión diseñada originalmente para trabajar con cintas magnéticas en la época en la que todavía se usaban. Se usa en varios formatos de paquetes para agrupar varios ficheros en uno y comprimirlos con otra herramienta. Ha conseguido sobrevivir hasta nuestros días como muestra de que no hace falta tirar a la basura algo que está bien hecho y funciona bien.

texinfo

Contiene el programa para leer la documentación de GNU en formato info. Personalmente prefiero man, pero…

xz

Este paquete contiene los compresores/descompresores xz y su predecesor lzma así como herramientas adecuadas para trabajar con ambos formatos. Es el compresor que mejor relacción tiene entre ratio de compresión y velocidad.

Conclusión

Lo más interesante de este capítulo del libro es ver cómo se monta el toolchain y cómo se aísla del resto del sistema. En el siguiente artículo empezaré con el capítulo 6 en el cual se compilan definitivamente no sólo los mismos paquetes que hemos compilado hasta ahora sino muchos más. Veremos qué sorpresas nos depara. 🙂

EOF

Anuncios

2 pensamientos en “Linux From Scratch IX: Resumen y conclusiones sobre el sistema temporal

    1. hexborg Autor de la entrada

      ¡Muchas gracias! Me alegro de que te guste. Pienso seguir hasta el final o la muerte, lo que llegue antes. 😀 😀

      Saludos y gracias por pasarte por aquí. 🙂

Los comentarios están cerrados.