Siguiendo con la serie de creación de paquetes para las distintas distros GNU/linux, ahora le toca el turno a Debian :)
Antes de comenzar, aclaro que este articulo nace motivado por mi curiosidad personal y en ningún caso pretende ser mas que un articulo para quien quiera aprender a empaquetar aplicaciones para Debian -y porque no Ubuntu-. No soy usuario de Debian ni Ubuntu, tampoco mantenedor o desarrollar, así que léase este como una bitácora personal sobre el tema. Y ya hechas las aclaraciones... comencemos!
Primero es necesario hacernos de las herramientas necesarias, para esto instalamos
- build-essential
- debian-builder
- dh-make
- lintian
- debian-policy
# aptitude install build-essential debian-builder dh-make lintian debian-policy
Con esto ya vamos a tener lo necesario. Ahora solo nos resta elegir la aplicación que queremos empaquetar. Yo elegí un programa llamado Internet Dj Console (Idjc). El motivo de esta elección tiene su pequeña historia familiar, se las cuento para torturarlos un poco mas aun, -jeje- resulta que mi querida hermana hace unos días me preguntó cómo hacer una radio online. Como no tenia ni la menor idea, me dediqué a buscar información y eso me llevó a conocer esta aplicación, el problema surgió cuando abro mi consola en Debian Testing y ejecuto:
# aptitude search idjc
Extrañamente no me arrojó ningún resultado, hecho que me llamó la atención, el motivo de que no este en los repos no lo sé (aclaro que no agrego repositorios extras, imagino que debe estar en sid). Así que este fue el hecho que motivó este tuto. Originalmente pensaba hablar sobre hacer el paquete para amsn-0.98beta, pero, ese ejemplo me parece menos didáctico, comparado con este, así que este ejemplo me vino como anillo al dedo medio. Y ya para dejar de torturarlos, volvemos a lo que nos reúne xD
Ya elegida la aplicación a empaquetar, creamos un directorio de trabajo
$ mkdir idjc
$ cd idjc
Descargamos el tarball de la aplicación, en este caso desde acá:
Idjc-0.7.10 y lo movemos al directorio de trabajo:
$ mv idjc-0.7.10.tar.gz idjc/
Ahora nos toca extraer y compilar normalmente para comprobar que no tiene errores de compilación:
$ tar xvf idjc-0.7.10.tar.gz
$ cd idjc-0.7.10/
$ ./configure --help
Y vemos las opciones de compilación que queremos que tenga nuestra aplicación, en mi caso no necesito mucho, solo
$ ./configure --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --disable-ffmpeg
Osea solo quiero que lea mp3 y nada de formatos como wma, avi o m4a. Pasado el
configure sin errores, lanzamos el
make $ make
Y por ultimo, el
make install pero como no queremos instalar la aplicación, sino solo comprobar que no vamos a tener errores a la hora de compilar el paquete, instalamos en un directorio temporal de esta forma:
# make install DESTDIR=/tmp/idjc
Si todo esto sale bien y sin errores (o con errores solucionables) entonces ya podemos empezar a crear nuestro .deb :)
Nota: Ya podemos limpiar lo que no necesitamos
# rm -r /tmp/idjc
# make distclean
Debianizando la aplicación
Como ya comprobamos que tenemos todo lo necesario para crear nuestro paquete, ahora nos toca debianizar la aplicación. Para esto copiamos el tarball original dentro del directorio descomprimido y ejecutamos dh_make
$ cp idjc-0.7.10.tar.gz idjc-0.7.10/
$ cd idjc-0.7.10/
$ dh_make -e tutoslibres@gmail.com -f idjc-0.7.10.tar.gz
Obviamente cada uno escribirá su mail. Esto nos va entregar algo así:
Type of package: single binary, multiple binary, library, kernel module or cdbs?
[s/m/l/k/b] s
## Especificamos el tipo de paquete y damos enter ##
Maintainer name : Asclepio
Email-Address : tutoslibres@gmail.com
Date : Wed, 05 Nov 2008 06:29:23 -0300
Package Name : idjc
Version : 0.7.10
License : blank
Using dpatch : no
Type of Package : Single
Hit
to confirm:
## Enter ##
Done. Please edit the files in the debian/ subdirectory now. amsnsvn
uses a configure script, so you probably don't have to edit the Makefiles.
(Nota:
Aca tenemos que recordar que podemos setear nuestro mail y nombre en caso de necesitarlo, para esto seguimos de la siguiente forma:
$ export DEBEMAIL=tu@email.com
$ export DEBFULLNAME=”"Tu nombre”"”
O agregandolo a nuestra configuracion de bash en .bashrc de nuestro Home.)
Lo que va a generar un directorio llamado debian dentro del árbol de archivos de la aplicación que estamos empaquetando y además nos va a hacer una copia del tarball original llamado idjc_0.7.10.orig.tar.gz como ven solo cambia el guión medio por uno bajo y le agrega la palabra orig, antes del tar.gz, nada del otro mundo. Luego vamos a tener un directorio mas llamado debian con los siguientes archivos:
changelog
compat
control
copyright
cron.d.ex
dirs
docs
emacsen-install.ex
emacsen-remove.ex
emacsen-startup.ex
init.d.ex
init.d.lsb.ex
manpage.1.ex
manpage.sgml.ex
manpage.xml.ex
menu.ex
postinst.ex
postrm.ex
preinst.ex
prerm.ex
README.Debian
rules
watch.ex
Para crear nuestro deb tenemos que editar cada una de estos archivos, según lo que necesitemos y bien con las características que queramos para nuestro paquete. Una breve explicación acerca de cada uno de los archivos:
debian/changelogComo el nombre nos lo indica son simplemente los cambios que vayamos haciendo a medida que modificamos o actualizamos la versión de nuestro paquete precompilado. Ojo, no es lo mismo que el Changelog de la aplicación.
debian/compatTiene relación con el estado de compatibilidad con debhelper, por ejemplo, supongamos que este paquete es compatible con la versión 7 de debhelper, entonces en este archivo solo se escribiría el numero 7. (Mas adelante vamos a ver que en el archivo control también hace un llamado a la versión de debhelper compatible, mas precisamente en el archivo debian/control)
debian/controlEste es uno de los archivos mas importantes dentro del directorio, acá vamos a reunir muchas indicaciones como las dependencias, prioridad de instalación, mantenedor, nombre de la aplicación, descripción, etc...
En este caso en particular tenemos algo así:
Source:
idjcSection:
x11Priority:
optionalMaintainer:
Asclepio Build-Depends:
debhelper (>= 7), autotools-dev, python (>=2.5), python-gtk2, jack, vorbis-tools, libsndfile1, libsamplerate0, libshout3,Standards-Version: 3.7.3
Homepage:
http://www.onlymeok.nildram.co.ukPackage:
idjcArchitecture:
anyDescription:
Shoucast and Icecast Client. Internet DJ console is a graphical shoutcast and icecast client that runs under GTK+ and the JACK audio connection kit. In short, it's an Internet radio app for making a live radio show.Lo editamos según corresponda al programa que queramos empaquetar, en source ponemos el nombre del programa, section, es el lugar donde va dentro de los repositorios de Debian... Para aclarar un poco mas es necesario saber que los repositorios de debian los paquetes se ordenan en main, contrib y non-free, como lo indica su nombre main es la sección donde van los paquetes que son software libre, en contrib las aplicaciones libres pero que para su ejecución depende de software no libre y en non-free las aplicaciones que directamente no son libres. Ahora dentro de estas secciones hay otras "sub-secciones" que pueden ser admin, base, lib, x11, net, devel, doc, etc con las que etiquetamos cada programa. Una descripción sencilla podría ser que en admin van las aplicaciones que usa el administrador del sistema, en base, las aplicaciones que son consideradas de uso básicas, lib las librerías o bibliotecas, x11 las herramientas que ocupan entorno gráfico (X11), devel las aplicaciones de desarrollo, entiéndase estas como las que necesitamos para programar, doc la documentación, etc... Para nuestro ejemplo lo vamos a poner en la section x11.
En Priority debemos indicar cuan importante es instalar el paquete, para nuestro paquete usamos optional ya que no es un paquete extremadamente importante ni mucho menos :o
Otra linea importante es Build-Depends, acá debemos indicar cuales son las dependencias del paquete, osea que paquetes deben estar instaladas para poder instalar nuestra aplicación.
Standards-Version, hace referencia a la versión de los estándares de debian para el empaquetamiento, el dh_make nos va a dejar por defecto lo necesario en esa linea :)
Es importante en Description, escribir primero una linea con una descripción corta de la aplicación, mientras que bajo esta escribir una descripción mas detallada de la aplicación, a veces incluso podemos escribir en este apartado la pagina oficial, etc. Esta descripción no debe ser mayor que 60 caracteres de largo.
debian/copyrightAcá incluimos información sobre la licencia y derechos de autor con que esta liberada la aplicación, de donde la descargamos, el autor(es) de la aplicación, etc. En nuestro ejemplo, podría ser algo así:
This package was debianized by Asclepio
on
Wed, 29 Oct 2008 22:11:10 -0300.
It was downloaded from http://www.onlymeok.nildram.co.uk/download.html
Upstream Author(s):
Author: Stephen Fairchild s-fairchild@users.sourceforge.net
Metadata: Dario Abatianni eisfuchs@users.sourceforge.net
Copyright:
Copyright (C) 2007 Free Software Foundation, Inc.
License:
GNU General Public License
The Debian packaging is (C) 2008, Asclepio and
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.
debian/cron.d.ex
Este archivo solo lo utilizamos en caso de que nuestro paquete necesite hacer uso de cron. Como nuestro programa no lo necesita lo podemos borrar:
$ rm debian/cron.d.ex
debian/dirs
Aca debemos incluir la ruta de los directorios que va a usar la aplicacion, pero que no se van crear por defecto, en otras palabras directorios especiales para la aplicacion. Por lo general los paquetes que se crean a traves de un Makefile, ya esta indicado cuales son los directorios que va a necesitar, como es en caso de nuestro caso. Ahora cuando empaquetamos aplicaciones escritos en lenguajes como python, perl, etc, este archivo por lo general es muy necesario para indicarle a la aplicacion cosas como donde estan los iconos, entre otras cosas. En nuestro ejemplo no lo necesitamos:
$ rm debian/dirs
debian/docs
Los ficheros de documentacion que vamos a incluir, para el ejemplo:
NEWS
README
AUTORS
ChangeLog
doc
debian/emacs*
Ficheros relacionados con Emacs, no los necesitamos:
$ rm debian/emacs*
debian/init.d*
En el caso de que necesitemos o queramos que nuestro programa se inicie cada vez que reiniciamos o prendemos nuestro pc, entonces editamos estos archivos. Para el ejemplo no los necesitamos:
$ rm debian/init.d*
debian/manpage.*
Las paginas man :)
El programa del ejemplo traia su propia documentacion man asi que con un
$ rm debian/manpage.*
$ cp Man/idjc.1 debian/idjc.1
$ cp Man/idjcctrl.1 debian/idjcctrl.1
En caso de que no tengamos paginas man, debemos crearlas nosotros mismo, para esto podemos escribirlas con nroff que es la aplicacion mas comun para escribir paginas man o bien usando otros como sgml u xml y para eso dh_make nos entrega los ejemplos llamados manpage.sgml.ex y manpage.xml.ex, ya escritas tenemos que rebautizarlas como nombreaplicacion.*:
$ mv debian/manpage.sgml.ex debian/idjc.1
El sufijo .1 es porque pertenece a la seccion man 1 que es la de ordenes de usuario, un grafico:
Sección | Descripción | Notas
1 Ordenes de Usuario Programas o guiones ejecutables.
2 Llamadas al Sistema Funciones que ofrece el núcleo.
3 Llamadas a Bibliotecas Funciones dadas por las bibliotecas del sistema.
4 Ficheros Especiales Generalmente se encuentran en /dev.
5 Formatos de Fichero Por ejemplo, el formato del /etc/passwd.
6 Juegos U otros programas frívolos.
7 Paquetes de Macros Como las macros de man.
8 Administración del Sist. Programas que sólo suele ejecutar el superusuario.
9 Rutinas del Núcleo Llamadas al sistema no estándar.
Para mas informacion: man 7 man
debian/menu.ex
Es la descripcion de la entrada que va a quedar en nuestro menu de aplicaciones. Lo podemos dejar asi:
?package(roaddemo):needs=”x11″ section=”Apps/Multimedia” \
title=”Internet DJ Console” command=”idjc” \
icon=”/usr/share/pixmaps/idjc.xpm”
En section va la ruta donde queremos dejar el icono en el menu, osea en aplicaciones-multimedia, en title el titulo de la aplicacion en el menu, puede ser el que queramos, no así en command que ahi debe ir si o sí el nombre con que se ejecuta la aplicacion, al final podemos indicarle la ruta donde se encuentra el icono de la aplicacion.
Y renombramos a menu
$ mv debian/menu.ex /debian/menu
debian/postinst.ex
Literalmente son las intrucciones que ejecuta despues de instalar el paquete creado. En este punto me parece interesante ver un pequeño esquema con la secuencia de instalacion de un paquete deb:
dpkg -i > Corre preinstalacion > Descomprime paquete > Corre postinstalacion
Como se puede ver, este script postinst.ex seria el que correria una vez instaldo el paquete. En general, una vez instalado un paquete no necesitamos cosas muy especiales (como en el ejemplo), solo actualizar algunas cosas como el menu y los documentos entre otras cosas, entonces nuestro ejemplo puede quedar asi:
#!/bin/sh
set -e
# Instala los documentos
if [ "$1" = configure ] && which install-docs >/dev/null 2>&1; then
install-docs -i /usr/share/doc-base/idjc
fi
# Actualiza el menu de nuestro escritorio
if [ "$1" = "configure" ] && [ -x "`which update-menus 2>/dev/null`" ]; then
update-menus
fi
# Fin
Y ahora movemos el archivo a su nombre original (sacamos el .ex que son los ejemplos)
$ mv debian/postinst.ex debian/postinst
debian/postrm.ex
El script que se ejecuta cuando desintalamos el paquete. Veamos un pequeño esquema con la secuencia de desintacion:
dpkg -r > Corre prerm > Corre postrm > Corre postrm purge
Durante postrm elimina los archivos del programa, si por algun motivo eliminamos con purge -osea eliminamos todo rastro del programa, con sus configuraciones- corre postrm purge.
Para nuestro ejemplo, vamos a llamar al comando que nos actualiza los menu:
#!/bin/sh
set -e
# Actualiza el menu
if [ -x "`which update-menus 2>/dev/null`" ]; then update-menus ; fi
# Fin
Luego renombramos el ejemplo (.ex) a su nombre final
$ mv debian/postrm.ex debian/postrm
debian/preinst.ex y debian/prerm.ex
Son ejemplos de script que se ejecutarian antes de instalar y antes de desintalar el paquete. Para el ejemplo no los necesitamos por lo tanto los eleminamos:
$ rm debian/pre*
debian/README.Debian
Es un archivo de avisos de modificaciones o detalles especiales que se hicieron cuando se debianizo el paquete. No lo necesitamos
$ rm debian/README.Debian
debian/watch.ex
Este archivo nos sirve para verificar si hay actualizaciones del paquete. Para esta tarea se usa el programa llamado uscan
$ man uscan
Una vez editado el archivo hay que renombrarlo
$ mv debian/watch.ex debian/watch
debian/rules
Quizá el archivo mas importante del proceso, en este escribimos las reglas con que se va a crear el paquete. En otras palabras es un Makefile pero que nos crea el deb. Cuando ejecutamos el dh_make nos generó un archivo debian/rules completo, el que podemos editar segun las necesidades que tengamos, osea podemos descomentar, comentar, agregar comandos o quitar comandos, para que debhelpers nos genere un paquete deb como el que queramos.
Para el ejemplo, como ya habia dicho, no necesito que tenga soporte para cosas raras como wma o avi, por lo tanto en las reglas donde corre el configure del paquete, le agregué esta linea:
./configure $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --disable-ffmpeg CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs"
Esta linea se encuentra en el "item" donde dice config.status: configure, dentro del archivo debian/rules. La idea de que este archivo tenga tantas instrucciones no es la confundir al que empaqueta la aplicacion -aunque mal no lo hace xD- sino que tiene como idea principal el de hacer un instrumendo muy flexible y configurable para poder crear nuestros paquetes.
Creacion de paquete deb
Y ya casi esta listo nuestro paquete deb, solo nos falta crearlo, para esto tenemos que correr el script con las reglas debian/rules, lo que quiere decir que tenos que darle permisos de ejecucion
$ chmod 750 debian/rules
Y ahora armanos el paquete con la palabra magica
$ debuild
Y si todo esta en orden nos va a crear el paquete deb junto a otros archivos con distintas informacion del paquete y la compilacion :)
Comprobar la "salud" del paquete
Una herramienta muy interesante y que nos permite comprobar si todo esta en orden con nuestro nuevo paquetes es lintian. Este lo ejecutamos de esta forma:
$ lintian paquete.deb
El que nos va a arrojar los warning (W) o errores (E) del paquete, recordar que un warning no es un error!
Y si todo salio bien, ya podemos instalar nuestro paquete
# dpkg -i paquete.deb
Una vez instalado y ya testeado (osea que corre sin problemas), el siguiente paso es subir el paquete a los repositorios de debian, claro, en el caso de que seamos desarroladores Debian. Como ya dije, este no es mi caso, así que hasta llego yo :)... pero siempre esta la guia oficial que se las dejo al final.
Consideraciones Finales
Y para terminar algunas consideraciones:
- Para ver las politicas de empaquetamiento de Debian, podemos ir al siguiente directorio: file:///usr/share/doc/debian-policy
de nuestro pc, ya que instalamos el paquete debian-policy cuando comenzamos :)
- Si estas interesado en ser un desarrollador oficial de Debian, puedes ver la lista de paquetes que necesitan trabajo y adoptar uno en el siguiente link
http://www.debian.org/devel/wnpp/
- Como ven crear un paquete deb no es un trabajo trivial, pero tampoco es algo tan dificil, en lo personal creo que es un tema digno de ser practicado por todos lo que esperamos conocer un poco mas de nuestras distros, incluso sin ser nuestra distro preferido y aca me pongo me ejemplo ya que soi un slacker debianizando aplicaciones xDD.
- Como siempre les dejo la fotito de la aplicación funcionando perfectamente en mi Debian Lenny
Mas info: Guia Oficial del nuevo Desarrollador
PackagingTutorial - Woman Debian Wiki