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>