static-httpd

Sitio web estático (HTML + CSS) que sostiene el blog del autor
Log | Files | Refs

index.html (12100B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      5 <meta name="viewport" content="width=device-width, initial-scale=1" />
      6 <title>Anatomía de un SlackBuild</title>
      7 <link rel="icon" type="image/png" href="/favicon.png" />
      8 <link rel="stylesheet" type="text/css" href="../article.css" />
      9 </head>
     10 <body>
     11 <header>
     12 <p class="title">Anatomía de un SlackBuild</p>
     13 <p class="date">12 de diciembre de 2025 • fjbalon</p>
     14 </header>
     15 <p>Como usuario de Slackware, he usado alguna vez scripts de SlackBuild para crear un paquete de software que pueda ser instalado fácil y limpiamente, y eliminado más tarde si es necesario con la misma facilidad y limpieza. Lo veremos en más profundidad más adelante, pero resumidamente sabemos que un SlackBuild es un script de shell que nos permite compilar e instalar paquetes desde el código fuente, creando un paquete -generalmente <emb>txz</emb>, aunque también <emb>tgz</emb>- y se instala mediante la herramienta nativa de Slackware <emb>installpkg</emb>. Se distribuyen principalmente en el repositorio oficial de <a href="https://slackbuilds.org">slackbuilds.org</a>.</p>
     16 <p>Al final, los SlackBuilds constituyen la forma oficial, digamos, de instalar software que mno viene en los repositorios base de Slackware.</p>
     17 <p>Existen diferentes enfoques de un script de SlackBuild, por ejemplo <i>Alien Bob</i> tiene su muy útil <a href="https://alien.slackbook.org/AST/">creador de SlackBuilds</a> y, en términos generales, lo respetaremos. Y como ejemplo mediante el cual encarnar lo que vamos a describir, usaré el paquete <a href="https://slackbuilds.org/repository/15.0/system/ksh-openbsd/">ksh-openbsd</a>. La descarga, generalmente, viene en un paquete comprimido <emb>.tar.gz</emb>, que se destarea y descomprime con <emb>tar xzvf</emb>, siendo el contenido del directorio:</p>
     18 <pre><code>ls
     19 doinst.sh  ksh-openbsd.info  ksh-openbsd.SlackBuild  README  slack-desc</code></pre>
     20 <p>Siendo el que nos interesa realmente el script <emb>ksh-openbsd.SlackBuild</emb> (téngase en cuenta que he eliminado comentarios para una mejor legibilidad):</p>
     21 <pre><code>#!/bin/bash
     22 
     23 cd $(dirname $0) ; CWD=$(pwd)
     24 
     25 PRGNAM=ksh-openbsd
     26 VERSION=${VERSION:-20190804}
     27 BUILD=${BUILD:-1}
     28 TAG=${TAG:-_SBo}
     29 PKGTYPE=${PKGTYPE:-tgz}
     30 
     31 if [ -z "$ARCH" ]; then
     32   case "$( uname -m )" in
     33     i?86) ARCH=i586 ;;
     34     arm*) ARCH=arm ;;
     35        *) ARCH=$( uname -m ) ;;
     36   esac
     37 fi
     38 
     39 if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
     40   echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
     41   exit 0
     42 fi
     43 
     44 TMP=${TMP:-/tmp/SBo}
     45 PKG=$TMP/package-$PRGNAM
     46 OUTPUT=${OUTPUT:-/tmp}
     47 
     48 if [ "${ARCH}" == "i586" ];then
     49   SLKCFLAGS='-march=i586 -mtune=i686'
     50   LIBDIRSUFFIX=""
     51 elif [ "$ARCH" == "i686" ]; then
     52   SLKCFLAGS="-march=i686 -mtune=i686"
     53   LIBDIRSUFFIX=""
     54 elif [ "${ARCH}" == "x86_64" ];then
     55   SLKCFLAGS='-fPIC'
     56   LIBDIRSUFFIX="64"
     57 else
     58   SLKCFLAGS="-O2"
     59   LIBDIRSUFFIX=""
     60 fi
     61 
     62 set -e
     63 
     64 rm -Rf $PKG
     65 mkdir -p $TMP $PKG $OUTPUT
     66 cd $TMP
     67 rm -Rf $PRGNAM-$VERSION
     68 tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
     69 cd $PRGNAM-$VERSION
     70 chown -R root:root .
     71 find -L . \
     72  \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 -o -perm 511 \) \
     73  -exec chmod 755 {} \+ -o \
     74  \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
     75  -exec chmod 644 {} \+
     76 
     77 CFLAGS="$SLKCFLAGS $(getconf LFS_CFLAGS)" make
     78 
     79 case "$(ps -o stat= -p $$)" in
     80   *+*) make check ;;   # running in foreground
     81   *)   echo '*** Not running "make check" because we are in the background.' ;;
     82 esac
     83 
     84 make install DESTDIR=$PKG
     85 
     86 if [ -n "${PDKSH_BINNAME}" ];then
     87   mv $PKG/bin/pdksh $PKG/bin/"${PDKSH_BINNAME}"
     88   mv $PKG/usr/man/man1/pdksh.1 $PKG/usr/man/man1/"${PDKSH_BINNAME}".1
     89   mv $PKG/usr/man/man1/pdksh-sh.1 $PKG/usr/man/man1/"${PDKSH_BINNAME}"-sh.1
     90 fi
     91 BINNAME=${PDKSH_BINNAME:-pdksh}
     92 
     93 strip --strip-unneeded $PKG/bin/"${BINNAME}"
     94 gzip -9 $PKG/usr/man/man1/"${BINNAME}".1
     95 gzip -9 $PKG/usr/man/man1/"${BINNAME}"-sh.1
     96 
     97 mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
     98 cp -a \
     99   Changelog.ksh-openbsd LEGAL README \
    100   $PKG/usr/doc/$PRGNAM-$VERSION
    101 cp $CWD/README $PKG/usr/doc/$PRGNAM-$VERSION/README.ksh-openbsd
    102 cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
    103 
    104 mkdir -p $PKG/install</code></pre>
    105 <p>Tras el <i>shebang</i> definimos las variables principales del paquete, como son <emb>PRGNAM</emb> (nombre del paquete, o sea, <emb>ksh-openbsd</emb>), <emb>VERSION</emb> (versión del software), <emb>BUILD</emb> (número de build del paquete Slackware, por defecto 1), <emb>TAG</emb> (etiqueta que se añade al paquete, como <emb>_SBo = SlackBuilds.org</emb>) y <emb>PKGTYPE</emb> (tipo de paquete, <emb>tgz</emb> en este caso).</p>
    106 <pre><code>if [ -z "$ARCH" ]; then
    107   case "$( uname -m )" in
    108     i?86) ARCH=i586 ;;
    109     arm*) ARCH=arm ;;
    110        *) ARCH=$( uname -m ) ;;
    111   esac
    112 fi</code></pre>
    113 <p>Detectamos automáticamente la arquitectura del equipo si el usuario no la tiene 
    114 definida.</p>
    115 <pre><code>if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
    116   echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
    117   exit 0
    118 fi</code></pre>
    119 <p>Es una parte muy útil para herramientas de gestión de paquetes como <emb>sbopkg</emb> o <emb>sbotools</emb>. Si la variable <emb>PRINT_PACKAGE_NAME</emb> está definida, aunque vacía, el script imprimirá el nombre completo del paquete (<emb>ksh-openbsd-20190804-x86_64-1_SBo.tgz</emb>). Esto permite a los gestores de paquetes saber el nombre sin tener que construir todo.</p>
    120 <p>Después definirá los entornos de trabajo en <emb>TMP</emb> (por defecto <emb>/tmp/SBo</emb>), <emb>PKG</emb> (directorio donde se va a instalar el software en la fase de compilación) y <emb>OUTPUT</emb> (dónde se almacenará el <emb>.tgz</emb> final).</p>
    121 <pre><code>if [ "${ARCH}" == "i586" ];then
    122   SLKCFLAGS='-march=i586 -mtune=i686'
    123   LIBDIRSUFFIX=""
    124 elif [ "$ARCH" == "i686" ]; then
    125   SLKCFLAGS="-march=i686 -mtune=i686"
    126   LIBDIRSUFFIX=""
    127 elif [ "${ARCH}" == "x86_64" ];then
    128   SLKCFLAGS='-fPIC'
    129   LIBDIRSUFFIX="64"
    130 else
    131   SLKCFLAGS="-O2"
    132   LIBDIRSUFFIX=""
    133 fi</code></pre>
    134 <p>En este punto definimos las variables <emb>SLKCFLAGS</emb> y <emb>LIBDIRSUFFIX</emb>, utilizadas para optimización en función de la arquitectura previamente reconocida; y para la toma de decisión del uso del directorio <emb>/usr/lib</emb> o <emb>/usr/lib64</emb>, en función -de nuevo- de la arquitectura.</p>
    135 <p>A partir de aquí podemos decir que la técnica se inicia, una vez realizadas las parametrizaciones técnicas iniciales. La línea que contiene <emb>set -e</emb> indica al intérprete que si cualquier comando devuelve un error (código de salida distinto de 0), el script se detiene inmediatamente. Es una medida de seguridad muy común en este tipo de scripts.</p>
    136 <pre><code>rm -Rf $PKG
    137 mkdir -p $TMP $PKG $OUTPUT
    138 cd $TMP
    139 rm -Rf $PRGNAM-$VERSION
    140 tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
    141 cd $PRGNAM-$VERSION
    142 chown -R root:root .
    143 find -L . \
    144  \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 -o -perm 511 \) \
    145  -exec chmod 755 {} \+ -o \
    146  \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
    147  -exec chmod 644 {} \+</code></pre>
    148 <p>Entonces elimina el directorio <emb>$PKG</emb>, por si hubiera una compilación anterior fallida o lo que fuera. Después, crea -si no existen- los directorios de trabajo previamente definidos. Nos movemos a <emb>/tmp/SBo</emb>, borra cualquier directorio que pudiera haber de código fuente, extrae con <emb>tar xvf</emb> el tarball que debe estar en la misma carpeta que el SlackBuild (<emb>$CWD</emb>) y accedemos a la carpeta del código fuente.</p>
    149 <p>Entonces, aplicamos una "reparación de permisos", que inicia cambiando el propietario recursivamente a <emb>root:root</emb> y, mediante el comando <emb>find</emb>, buscamos archivos y carpetas con permisos inusuales, o demasiado permisivos. Los ejecutables o directorios se pondrán en permiso 755 (<emb>rwxr-xr-x</emb>), el resto de archivos en 644 (<emb>rw-r--r--</emb>).</p>
    150 <p>Después, con <emb>CFLAGS="$SLKCFLAGS $(getconf LFS_CFLAGS)" make</emb> definimos variables de entorno para el comando <emb>make</emb>, utilizando los parámetros del inicio y ejecutando <emb>getconf</emb> para obtener otros parámetros necesarios.</p>
    151 <pre><code>case "$(ps -o stat= -p $$)" in
    152   *+*) make check ;;   # running in foreground
    153   *)   echo '*** Not running "make check" because we are in the background.' ;;
    154 esac</code></pre>
    155 <p>Es entonces cuando iniciamos la fase de compilación. En términos generales se realiza directament el <emb>make</emb>, pero se ve que el programador de este paquete de ejemplo le añadió algo de complejidad: a veces, parece qu eel paquete en instalación (<emb>ksh-openbsd</emb>, recuerdo) se cuelga durante el <emb>make check</emb>, que indica una fase de testing, cuando se ejecuta en segundo plano. Esto ocurre con más frecuencia cuando se usa <emb>sbopkg</emb>, <emb>queue</emb> o scripts de compilación masiva. El test se quedaría esperando algo de terminal/entrada y bloquea toda la cola. ¿La solución? sencilla: si estoy ejecutando el SlackBuild manualmente en una términal, haga los test; si no, ignórelos.</p>
    156 <p>Entonces, sí hacemos el make con <emb>make install DESTDIR=$PKG</emb> sobre el directorio de trabajo final.</p>
    157 <pre><code>if [ -n "${PDKSH_BINNAME}" ];then
    158   mv $PKG/bin/pdksh $PKG/bin/"${PDKSH_BINNAME}"
    159   mv $PKG/usr/man/man1/pdksh.1 $PKG/usr/man/man1/"${PDKSH_BINNAME}".1
    160   mv $PKG/usr/man/man1/pdksh-sh.1 $PKG/usr/man/man1/"${PDKSH_BINNAME}"-sh.1
    161 fi
    162 BINNAME=${PDKSH_BINNAME:-pdksh}</code></pre>
    163 <p>Si el usuario define la variable de entorno <emb>PDKSH_BINNAME</emb> antes de ejecutar el script, entonces renombra todo para que el shell no se llame <emb>pdksh</emb>. Por ejemplo, si el usuario ha ejecutado antes <emb>PDKSH_BINNAME=ksh ./ksh-openbsd.SlackBuild</emb>, el binario pasaría a llamarse <emb>ksh</emb> en lugar de <emb>pdksh</emb> (renombrando a su vez las páginas de manual correspondientes, claro está).</p>
    164 <pre><code>strip --strip-unneeded $PKG/bin/"${BINNAME}"
    165 gzip -9 $PKG/usr/man/man1/"${BINNAME}".1
    166 gzip -9 $PKG/usr/man/man1/"${BINNAME}"-sh.1</code></pre>
    167 <p>El comando <emb>strip</emb> sobre el binario principal elimina todos los símbolos de depuración y sesiones innecesarias del ejecutable, pero sin romper las funciones necesarias (de ahí que se use <emb>--strip-unneeded</emb> en lugar de <emb>--strip-all</emb>). Esto reduce considerablemente el tamaño del binario final. Es una práctica estándar en todos los paquetes de Slackware.</p>
    168 <p>Después, comprime las páginas de manual con <emb>gzip</emb> usando el nivel máximo de compresión (<emb>-9</emb>).</p>
    169 <pre><code>mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
    170 cp -a \
    171   Changelog.ksh-openbsd LEGAL README \
    172   $PKG/usr/doc/$PRGNAM-$VERSION
    173 cp $CWD/README $PKG/usr/doc/$PRGNAM-$VERSION/README.ksh-openbsd
    174 cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
    175 
    176 mkdir -p $PKG/install</code></pre>
    177 <p>Y finalmente, creamos el directorio con la documentación, copiamos ésta y, encima, copiamos el propio SlackBuild dentro de dicha carpeta. Esto está encarecidamente recomendado por las buenas prácticas de un SlackBuild, puesto que permite al usuario final ver cómo se compiló el paquete en cualquier momento. Es útil además para depuraciónh y para reproducción, en caso necesario.</p>
    178 <p>Además, crea el directorio <emb>/install</emb> dentro del propio paquete. Aquí almacenará los archivos de metadatos del paquete, como <emb>slack-desc</emb>, <emb>doinst.sh</emb>, <emb>slack-required</emb>, <emb>slack-conflicts</emb>, etcétera.</p>
    179 <p>Como hemos visto, el contenido de un SlackBuild es muy completo, contando con todas las fases de despliegue de un software: preparación, parametrización, configuración de compilación o pre-compilación, extracción y limpieza, compilación, instalación, optimización, documentación, empaquetado final... Se trata de un guión y hoja de ruta poderosa para el usuario de Slackware, desde luego, y muy útil y práctica en el día a día de la administración de este sistema.</p>
    180 </body>
    181 </html>