Traducciónes: Español - English - Italiano - Català



Introducción al empaquetamiento en Debian

Tutorial en IRC de Debian-Women por Lars Wirzenus: 18-Nov-2010

Esto es un tutorial de introducción de como hacer paquetes en Debian: no profundiza demasiado en los detalles mas pequeños de el empaquetamiento en Debian, pero te mostrará como hacer paquetes Debian para software que es simple de empaquetar.

Para este propósito, sólo se usara el comando dh de debhelper 7.

Requerimientos

En este tutorial asumimos que:

Requerimientos técnicos:

Los tres conceptos principales

Los tres conceptos principales son el código original, el paquete fuente y el paquete binario. La mayoría de la gente empaqueta software que otra persona escribió: esta otra persona es el autor original (upstream developer, en inglés). El autor original publicará su programa y el resultado concreto será el código original comprimido en un fichero, también llamado «tarball».

Un «tarball» es un archivo .tar.gz o .tgz que el autor crea («tarball» pertenece a la jerga informática y es un término díficil de traducir). El «tarball» es exactamente lo que Debian utiliza para construir un paquete. Cuando tienes el código original el próximo paso es crear el paquete fuente de Debian. De este puedes construir un paquete binario de Debian que es el que en verdad instalas.

Los paquetes fuente consisten, en su forma más simple, de tres archivos:

  1. El código original renombrado para seguir un patrón sistemático.
  2. El archivo parche (patch file), con cualquier cambio al upstream source, más todos los archivos creados para el paquete Debian. Este termina con una extensión .diff.gz
  3. Un archivo de descripción (con una extensión .dsc), que nombra los otros dos archivos.

Esto todo suena mas complicado de lo necesario a primera vista parece mas simple tenerlo todo en un solo archivo. Resulta que ahorras mucho espacio de disco y ancho de banda para mantener el código original separado de cualquier cambio específico de Debian. También es mas fácil recordar que fue necesario cambiar para Debian.

El proceso de empaquetamiento

El proceso se podría dividir en las siguientes seis (6) etapas:

  1. Renombrar el código original para que siga un patrón de nombres específico
  2. Descomprimir el código original
  3. Agregar Debian archivos de empaquetamiento (en un subdirectorio llamado debian), y produce cualquier otro cambio necesario.
  4. Construir el paquete fuente (source package)
  5. Construir el paquete binario.
  6. Subir los paquetes fuente y binario a Debian

Para este tutorial Lars uso este tarball.

Paso 1: Renombrar el tarball

Las herramientas de Debian asumen que el código original tiene un nombre muy específico.

El nombre consiste de el nombre del paquete fuente, un subrayado, el número de la versión upstream , seguido por .orig.tar.gz. El nombre del paquete fuente debería estar todo en letras minúsculas y puede contener letras, dígitos y guiones. Otros caracteres también son aceptados.

Si el "upstream developer" usa un nombre que parece ser un buen nombre para un paquete fuente Debian entonces úsalo. Si no cámbialo lo menos posible, pero lo suficiente para que pueda ser usado en Debian. En este caso el, upstream ha sabiamente escogido un buen nombre, "hithere", así que no hay que preocuparse.

Deberíamos crear un archivo llamado hithere_1.0.orig.tar.gz.

Nota: Es un subrayado, no un guión, en el nombre. Esto es importante porque las herramientas de empaquetamiento son estrictas.

# mv hithere-1.0.tar.gz hithere_1.0.orig.tar.gz

Paso 2: descomprimir el tarball

Deberíamos tener un directorio llamado "hithere-1.0". En general, las fuentes deberían ir en un directorio llamado después del paquete fuente y la versión con un guión (no un subrayado) en el medio.

Esto, repito, es porque las herramientas de Debian son estrictas.

En este caso en particular el autor ha sido sabio otra vez y comprimió el código original en el subdirectorio correcto.

 # tar xf hithere_1.0.orig.tar.gz

Paso 3: Agregar los archivos al paquete Debian

Todos estos archivos van dentro el subdirectorio "debian/" dentro del las carpeta madre "source tree".

# cd hithere-1.0
# mkdir debian

Hay un montón de archivos que necesitamos proveer. Vamos a verlos en orden:

debian/changelog

El primer archivo es debian/changelog. Este es un documento que contiene todos los cambios hechos en el paquete Debian.

No necesita tener todo lo que ha cambiado en el código upstream, pero sería útil para resumir esos cambios. Ya que estamos haciendo la primera versión no hay nada que anotar en el archivo de cambios (changelog). Aun así necesitamos hacer una entrada para el archivo de cambios (changelog entry) porque algunas herramientas leen cierta información del archivo de cambios. También leen la versión del paquete, mucho más importante.

debian/changelog Tiene un formato particular. La manera mas fácil de crear un "changelog" es con la herramienta dch.

# dch --create -v 1.0-1 --package hithere

Esto resultará en un archivo así:

hithere (1.0-1) UNRELEASED; urgency=low

  * Initial release. (Closes: #XXXXXX)

 -- Lars Wirzenius <liw@liw.fi>  Thu, 18 Nov 2010 17:25:32 +0000

Un par de notas:

debian/compat

Este archivo debería contener el número 7. Este es un número mágico. No pongas más números ahí. debian/compat specifica el nivel de compatibilidad con la herramienta debhelper. No vamos a llegar a ver que significa eso por ahora.

debian/control

El archivo de control describe los paquetes fuente y binario y da cierta información sobre ellos como sus nombres, el mantenedor del paquete y así sucesivamente. Aquí hay un ejemplo de cómo se podría ver.

Source: hithere
Maintainer: Lars Wirzenius <liw@liw.fi>
Section: misc
Priority: optional
Standards-Version: 3.9.0
Build-Depends: debhelper (>= 7.3.8)

Package: hithere
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: greet user
 hithere greets the user, or the world.

Hay muchos campos requeridos, pero por el momento no vamos a profundizar en ellos En debian/control, hay dos párrafos

El primer párrafo describe al paquete fuente:

"Source:"
Da el nombre del paquete fuente.
"Maintainer:"
Da el nombre y la dirección de correo del responsable del paquete.
"Build-Depends:"
Nombra los paquetes que necesitan ser installados para construir el paquete. Pueden o no pueden ser necesarios para realmente usar el paquete.

El segundo parafo describe al paquete binario creado de esta fuente. inclusive pueden haber varios paquetes binarios creados de la misma fuente.

"Package:"
Es el nombre del paquete binario. pude que tenga un nombre distinto que el paquete fuente.
"Architecture:"
Nos dice en que arquitectura de computadora se espera que el paquete binario trabaje: i386 para CPUs 32-bit Intel , amd64 para 64-bit, armel para procesadores y así sucesivamente. Debian trabaja en como una docena de arquitecturas en total así que este soporte arquitectónico es crucial. El campo "Arquitectura:" puede contener nombres de arquitecturas particulares, pero generalmente uno de estos dos valores especiales.
"any"
(El cual podemos ver en el ejemplo) significa que el paquete puede ser construido para cualquier arquitectura. En otras palabras, el código ha sido escrito portablemente así que no importa mucho cual es el hardware de el ordenador. De todas formas el paquete binario va a tener que ser construido para cada arquitectura separada.
"all"

Significa que el mismo paquete binario funciona en todas las arquitecturas, sin tener que construir por separado para cada una. Por ejemplo, un paquete consistiendo en sólo shell scripts sería all. Shell scripts funcionan igual y no necesitan ser compilado.

"Depends:"
Campo que nombra los paquetes que necesitan ser instalados para que el programa instalado en el paquete binario funcione. Nombrando estas dependencias manualmente es un trabajo difícil y fácil de equivocarse. Para hacer este trabajo el comando mágico ${shlibs:Depends} necesita estar allí. las otras cosas mágicas estan en debhelper. El comando {misc:Depends}. La magia es compartida para dependencias de librería, la magia misc es una cosa que debhelper hace por otras dependencias, vas a tener que agregarlas manualmente a las dependencias "Depends" o a las "Build-Depends" y el comando mágico ${...} sólo funciona en Depends
"Description:"
Es una descripción del paquete. Es útil para los usuarios

debian/copyright

Es un archivo bien importante, pero por ahora estaremos felices con un archivo vacío.

Para Debian este archivo mantiene un registro de la información legal y los derechos de autor del paquete. Esto no es importante desde un punto de vista técnico así que olvidaremos esto por ahora y nos concentramos en lo técnico.

debian/rules

Debería verse así:

#!/usr/bin/make -f
%:
    dh $@

debian/rules puede ser muy complicado, Sin embargo, el comando dh en dephelper versión 7 ha simplificado su utilización substancialmente.

debian/source/format

El último archivo que necesitamos debian/source/format, y debería contener el número de versión 1.0.

Esta es el número de la versión para el formato del paquete fuente y aunque resulta que es el mismo que la versión upstream eso sólo es una coincidencia.

Pasos 4 y 5: construir el paquete

Ahora podemos construir el paquete. El comando para hacer esto es:

debuild -us -uc

Hay muchos comandos que podríamos usar para esto, pero usamos este. Si corres el comando tendrás un resultado parecido a este:

make[1]: Entering directory `/home/liw/debian-packaging-tutorial/x/hithere-1.0'
install hithere /home/liw/debian-packaging-tutorial/x/hithere-1.0/debian/hithere/usr/local/bin
install: cannot create regular file `/home/liw/debian-packaging-tutorial/x/hithere-1.0/debian/hithere/usr/local/bin': No such file or directory
make[1]: *** [install] Error 1
make[1]: Leaving directory `/home/liw/debian-packaging-tutorial/x/hithere-1.0'
dh_auto_install: make -j1 install DESTDIR=/home/liw/debian-packaging-tutorial/x/hithere-1.0/debian/hithere returned exit code 2
make: *** [binary] Error 29
dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2
debuild: fatal error at line 1325:
dpkg-buildpackage -rfakeroot -D -us -uc failed

Algo salió mal. Esto suele pasar. Haces lo mejor que puedes para crear archivos debian/* , pero siempre algo sale mal. Lo que salió mal está en este pedazo:

install hithere /home/liw/debian-packaging-tutorial/x/hithere-1.0/debian/hithere/usr/local/bin

El upstream Makefile está tratando de instalar el programa compilado en la localización incorrecta.

Hay un par de cosas que suceden aquí. La primera tiene que ver con como Debian funciona.

Cuando el programa ha sido construido y está instalado no es instalado en el local /usr or /usr/local, como siempre, sino en el subdirectorio debian/

Creamos todo un sistema de archivos bajo la carpeta debian/hithere, y luego ponemos eso en el paquete binario. Así que la parte de .../debian/hithere/usr/local/bin está bien sólo que no debería estar instalado en usr/local sino directamente en usr.

Debemos hacer algo para que lo instale en el lugar correcto (debian/hithere/usr/bin).

La manera correcta de arreglarlo es cambiando debian/rules para que le diga a Makefile donde instalar las cosas.

#!/usr/bin/make -f
%:
        dh $@

override_dh_auto_install:
        $(MAKE) DESTDIR=$$(pwd)/debian/hithere prefix=/usr install

De nuevo es un poquito de magia y lo entenderás cuando tengas que saber cómo Makefiles funciona y las muchas estaciones de debhelper.

Por ahora vor a resumir diciendo que hay un commando debhelper que se encarga de installar los upstream files, y esta estación se llama dh_auto_install.

Necesitamos saltar esta etapa, y para hacer esto debemos añadir una regla en debian/rules llamada override_dh_auto_install.

Esa última línea es de tecnologia de los años 70 para invocar Makefile de debian/rules con los argumentos validos.

Vamos ha tratar de construirlo de nuevo. ¡Aún falla!

Esta vez, este es el commando que falló:

install hithere /home/liw/debian-packaging-tutorial/x/hithere-1.0/debian/hithere/usr/bin

Ahora lo estamos tratando de instalar en el lugar correcto, pero este no existe. Para arreglar esto tenemos que decirle a las herramientas de empaquetamiento que creen el directorio

Las herramientas de empaquetamiento (especificamente, debhelper) dan una manera para hacer esto.

Crea un archivo llamado debian/hithere.dirs, y hazlo verse así:

usr/bin
usr/share/man/man1

La segunda línea crea el directorio de la página del manual. La necesitaremos luego. Ahora si se construye, pero hay unos cuantos problemitas.

debuild corre la herramienta lintian la cual revisa si el paquete tiene errores comunes. Nos reporta varios en este paquete nuevo:

Now running lintian...
W: hithere source: out-of-date-standards-version 3.9.0 (current is 3.9.1)
W: hithere: copyright-without-copyright-notice
W: hithere: new-package-should-close-itp-bug
W: hithere: wrong-bug-number-in-closes l3:#XXXXXX
Finished running lintian.

Esto debería ser arreglado eventualmente, pero ninguno parece que traería problemas para probar el paquete así que los ignoraremos por ahora.

Mira el directorio inicial para encontrar el paquete que acabamos de construir.

 # ls ..

hithere-1.0          hithere_1.0-1_amd64.deb  hithere_1.0.orig.tar.gz
hithere_1.0-1_amd64.build    hithere_1.0-1.diff.gz
hithere_1.0-1_amd64.changes  hithere_1.0-1.dsc

El siguiente commando instalará el paquete construido. NO lo corras en una computadora que no te importe dañar.

En general es mejor instalar el paquete en una maquina que tenga toda su información resguardada, y que no te importe reinstalar si todo sale muy mal.

Máquinas virtuales son un buen lugar para hacer esto

# sudo dpkg -i ../hithere_1.0-1_amd64.deb

Y esto es lo que obtenemos:

liw@havelock$ sudo dpkg -i ../hithere_1.0-1_amd64.deb
[sudo] password for liw:
Selecting previously deselected package hithere.
(Reading database ... 154793 files and directories currently installed.)
Unpacking hithere (from ../hithere_1.0-1_amd64.deb) ...
Setting up hithere (1.0-1) ...
Processing triggers for man-db ...
liw@havelock$

¿Cómo probamos el paquete? Podemos correr este commando:

# hithere

Funciona! Pero no es perfecto. Recuerda, lintian nos mecionó unos cuantos errores, debian/copyright está vacío, etc.

Tenemos un paquete que funciona, pero tiene la calidad que esperaríamos de un paquete Debian.

Conclusiones

Una vez que ya hallas construido tus propios paquetes, eventualmente querrás aprender como montar tu repositorio apt, para que tus paquetes sean fáciles de instalar. La mejor herramienta para eso que conozco es reprepro.

Para probar tus paquetes querrás buscar una herramienta llamada piuparts. (Yo la escribí originalmente así que es perfecta y no tiene bugs).

Finalmente si vas a empezar a hacer cambios al upstream source, querrás aprender más sobre la herramienta quilt.

Otras cosas que podrías querer leer están en la página web http://www.debian.org/devel/

Preguntas y respuestas

PREGUNTA: ¿Puedo generar un paquete multi-arch?

RESPUESTA: No creo que con Debian se puedan hacer paquetes multi-arch. Sin embargo, pronto escribiré la sección "Architecture: all".

PREGUNTA: Por favor clarifique como puedo hacer paquetes de paquetes que ya se encuentran en forma binaria. i.e nvidia blobs.

RESPUESTA: Para los paquetes blob que se encuentran en forma binaria. (binary blob packages), debes tratar el tarball con los bloBs como el paquete fuente (source package) y evitar copilarlos desde la fuente. Aunque, yo nunca he tenido que hacer esto.

PREGUNTA: ¿Hay algo parecido a ppa en ubuntu?

RESPUESTA: Debian no corre el servicio PPA como lo hace Ubuntu, sin embargo todos los programas pertinentes para hacer repositorios apt están presentes en Ubuntu, solo hay que saber configurarlos debidamente.

PREGUNTA: ¿Tendría que rehacer el tarball original si en este no se encuentra una carpeta llamada foo-1.0 ?

RESPUESTA: Creo que ya hoy en día no es necesario. Antiguamente solía ser necesario, pero ahora el comando "dpkg-source -x" crea la carpeta en el caso de que sea necesario.

PREGUNTA: Veo paquetes DEB "oficiales" en /var/cache/apt/archives sin los archivos "changelog" y "compat". ¿Por qué?

RESPUESTA: el paquete .deb que se encuentra en la carpeta /var/cache/apt/archives es un paquete binario; El archivo "changelog" esta incluido dentro de el paquete (aunque con un nombre diferente). El archivo "compat" solo se puede encontrar en el paquete fuente (source package).

PREGUNTA: Liw dijo que el archivo "compat" debería contener el numero mágico 7, asumo que esto significa un simple y singular caracter, similar al que se produce con el comando 'echo 7 >deabian/compat'.

RESPUESTA: Si, un simple caracter "7" es suficiente para tener en el archivo "debian/compat"

PREGUNTA: He escuchado que hay un formato especifico para los números de revisión de los paquetes de debían que deben seguir los no-mantenedores.

RESPUESTA: Creo que te refieres a el formato del paquete nativo (en el cual el número de versión solo sería 1.0 en vez de 1.0-1). En el caso que te refieras a el formato para los uploads de los no-mantenedores, en la mayoría de los casos un "1.0-1.1" estaría bien.

PREGUNTA: ¿Cuando es que corre el commando "dpkg-source -x"? ¿Hay que correrlo manualmente?

RESPUESTA: "dpkg-source -x" es el commando que descomprime el paquete fuente de Debian luego de que este ya fue copilado (generalmente por alguien mas); no es común utilizar este comando cuando se esta creando el paquete.

PREGUNTA: ¿Cómo podemos determinar que paquetes necesitamos para ser usados por las Build-Depends?

RESPUESTA: Yo usualmente lo hago por a) ensayo y error. b) leyendo la fuente del programa. Generalmente, las dos maneras son necesarias.

PREGUNTA: ¿Puedo copilar un programa para armel desde mi i386? ¿Hay alguna manera sencilla para hacer esto?

RESPUESTA: Eso seria "cross-compilation" (compilación entre distintas plataformas). Lamentablemente, no creo que exista ninguna manera sencilla de hacer esto; Aunque si hay programas y herramientas para eso, pero yo no estoy familiarizado con estas.

PREGUNTA: ¿Cuál es la diferencia entre Depends y Build-Depends y en que caso tengo que usar Depends en vez de Build-Depends?

RESPUESTA: Build-Depends lo necesitas sólo mientras construyes el paquete, mientras está siendo compilado y cuando lo están probando. Depends sólo se usa cuando ya está instalado y en uso. Some things might be both build and runtime dependencies, and in that case you need to put them into both Build-Depends and Depends.

Por ejemplo, si un paquete tiene guiones PHP (PHP scripts), pero estos no suponen correr mientras el paquete se esta construyendo, entonces estos guiones PHP deben ir en Depends, no en Build-Depends.

Sin embargo, en el caso de que si se deban ejecutar estos guiones, entonces deben colocarse en Build-Depends.

PREGUNTA: ¿Pueden haber dependencias en Build-Depends que no tengan correspondientes en Depends? Estoy refiriendome a "Statistical Linked Librarys".

RESPUESTA: Los Build-Depends y Depends son separados entre si, y es perfectamente posible que hayan dependencias en uno que no tengan correlación con el otro.

PREGUNTA: ¿Si quisiera hacer mas NMU, debería escribir mi nombre en el espacio de "Uploader", el espacio de "Mantainer" o en ninguno de los dos?

RESPUESTA: (por dapal) En ninguno de los dos, pero si lo puedes agregar en la primera línea de el changelog, agregando también la frase "Non-maintainer upload"

PREGUNTA: Cuando construyo un paquete con el campo de"Architecture: all" alguno de los archivos resultantes como (b.build.changes) todavía tienen el nombre de la arquitectura como su nombre. ¿Es este comportamiento comun?

RESPUESTA: Si. No hay nada de que preocuparse

PREGUNTA: ¿Hay algun otro paquete para los paquetes fuentes o es el mismo para los paquetes binarios? ¿Debo generar y mantener dos paquetes (el binario y el fuente)?

RESPUESTA: Uno edita el paquete fuente y luego corre un comando ( el cual luego expondré) para compilar el paquete binario.

PREGUNTA: No me quedo completamente claro si el las opciones de "Architecture" (referentes a la arquitectura del paquete) afectan el paquete fuente en su proceso de compilación o el paquete binario en su proceso de instalación.

RESPUESTA: La opciones de "Architecture:" le dicen a quien sea que vaya a compilar el paquete si hay que construir el paquete en algún tipo de arquitectura de pc en especifico. Por ejemplo si la opción dice i386, entonces se sabe que no hay ningun punro en tratar de compilarlo en una computadora con arquitectura de amd64.

PREGUNTA: es ejemplo de debian/rules contiene solo un "#!make -f" , ¿que se hace con ./configure, cmake, scons o cualquier otra parte?

RESPUESTA: Un paquete con un guion .configure, o en cualquiera de las otras maneras comunes para construir paquetes usualmente se compilara de manera similar y sin ningún problema.

PREGUNTA: ¿Puede heuristics trabajar con source packages que necesitan ./waf o otras herramientas para construir?

RESPUESTA:(dapal): usando dh7,si quiers pasar algo a ./configure, solo has añade una linea como: override_dh_auto_configure <TAB>dh_auto_configure -- --your-params. dh tiene una manera para añadir extesiones o reemplazar partes particulares de manera sencilla. Para mas información lee los manuales de dh.

PREGUNTA: Donde puedo encontrar los manuales para reemplazar partes particulares con debhelper 7?

RESPUESTA: dh corre comandos en una secuencia especifica. Cada comando se llama dh_ejemplo y cada comando puede ser remplazado añadiendo a las debian/rules una regla llamada override dh_ejemplo. Si quieres saber cuales son estos distintos comandos, utiliza el comando --no-act de dh en debian/rules para ver que comandos esta corriendo.

PREGUNTA: ¿De donde se deberían correr estos comandos? ¿Desde el directorio hithere-1.0 o afuera?

RESPUESTA: Yo siempre lo corro desde el directorio hithere-1.0 y usualmente tengo ese directorio dentro de otro llamado hithere. Hace que las cosas se vean mas limpias y claras.

PREGUNTA: Yo tengo un upstream que necesita gmake (usa Qt) antes de compilarse. ¿Puedo añadirlo a debian/rules?¿Como?

RESPUESTA: (by gregoa) debhelper apoya a qmake desde la versión 7.4.12 (asi que nada adicional es necesario). Si usas una versión anterior, entonces añade la regla override_dh_auto_configure :\n\tqmake

PREGUNTA: ¿Que pasos a seguir son los mejores para generar una nueva versión de un paquete upstream ?

RESPUESTA: Ah! no estoy seguro de cuales serán los mejores pasos a seguir pero, básicamente son estos: 1. descomprime el tarball a un nuevo directorio. 2. copia el nuevo directorio debian/* del paquete anterior. 3. Renueva el debian/changelog ("dch -v 1.2.3-4") y trata de compilarlo. 4. Si algo no necesita ser arreglado, arréglalo. Para hacer esto de manera más sencilla te sugiero profundizar en un programa llamado quilt.

PREGUNTA: Hice un paquete debian que depende de otros paquetes. Lo único que mi paquete hace es modificar o configurar otros paquetes para que estos funcionen de cierta manera. Para esto, hago algunos cambios críticos al sistema. ¿Hay algún reglamento de lo que un paquete oficial puede o no hacer?¿Podría un programa como el mio llegar a tener un paquete oficial?

RESPUESTA: http://www.debian.org/doc/debian-policy/ contiene todas las reglas que regulan lo que un paquete Debian puede o no hacer.

Usualmente, los paquetes Debian no suponen cambiar la configuración de otros paquetes, al ments que los otros paquetes provean un interfaz documentado para esto.

Véase también