1. rpm: prefacio.
  2. rpm: conceptos basicos
  3. rpm: uso
  4. rpm: empaquetando aplicaciones
  5. rpm: empaquetando aplicaciones++

1. rpm: prefacio.

La presente guía constituye un intento personal por diseminar, en lo que fuera posible, el conocimiento sobre rpm y las ventajas y desventajas que le son inherentes.

De ninguna manera intenta ser una guía completa sobre rpm y su uso, ni mucho menos, sino más bien, un intento de volcar el magro conocimiento propio sobre el tema, en la esperanza de que en un futuro inmediato le sea de ayuda a alguien.

La idea que subyace en estas líneas es que el lector, al terminar de leer el texto, sea capaz de comprender:

Esto es, que en lineas generales, quede introducido al uso de esta util herramienta y sea capaz de, eventualmente, poder desenvolverse solo a la hora de resolver aquellos problemas que por motivos obvios no se encuentran descriptos en esta página.

2. rpm: conceptos basicos

2.1. Que es rpm?

Sin entrar en demasiado detalle, y contando siempre con que el detalle puede ser hallado por el lector en internet sin mayor esfuerzo, podemos decir que rpm es una herramienta de línea de comandos, cuya finalidad principal es la de administrar al nivel más bajo posible, el software instalado en nuestro sistema.

Para ello, rpm posee un amplio conjunto de opciones que nos permitirán llevar acabo tareas que van desde las más simples (como instalar, actualizar o remover un paquete) hasta las mas complejas (como empaquetar software o analizar el conjunto de dependecias de un paquete determinado aún si éste no se encuenra instalado en el sistema, entre muchas otras).

2.2. Que son los archivos *.rpm?

Los archivos *.rpm son, en principio, software compilado, comprimido, empaquetado y listo para ser instalado y usado en un sistema Linux.

Son similares a cualquier otro archivo comprimido (como un archivo .zip, o un archivo .rar, o .tar.gz, etc.) pero, a diferencia del resto, los archivos rpm contienen un amplio conjunto de información extra. Esto es, los archivos *.rpm no solo contienen todos los archivos que componen a un progama en su forma binaria, sino que además contienen metainformación sobre el software en cuestión (como la URL desde donde se descargo el software, el tipo de licencia bajo la cual se distribuye, el nombre de quien lo empaqueto, etc) así como también todas las instrucciones necesarias para que rpm pueda instalar el paquete de forma correcta, llevando a cabo todas las operaciones que se requieren para que el software empaquetado se instale de forma completamente funcional.

En suma, al desempaquetar e instalar un archivo *.rpm en su sistema, usted obtendrá como resultado a la totalidad de los archivos binarios y no binarios que componen a un programa de software, junto con toda la información administrativa sobre al mismo.

2.3. Que son los archivos *.src.rpm?

Los archivos *.src.rpm son paquetes compuestos por el código fuente (source) de un software más todos los parches que fueran necesarios, sin compilar ni parchear ni comprimir, y en conjunto con el archivo *.spec que es el que contiene todas las instrucciones necesarias para que usted pueda compilar, parchear, comprimir y empaquetar dicho software, creando como resultado un paquete *.rpm que se ajuste a sus necesidades.

A diferencia de lo que ocurre con los paquetes *.rpm, al desempaquetar un archivo *.src.rpm usted obtendrá como resultado un archivo *.tar.gz o *.tar.bz2, o lo que fuera que constituye al source de un software, y un archivo *.spec que es el que contiene la rutina a ser ejecutada para convertir el código fuente (source) de ese software en un paquete *.rpm.

3. rpm: uso

3.1. rpm: uso basico

En esta sección, veremos cuales son los opciones mas comunes a la hora de usar rpm en un sistema Linux.

Dado que estas son las opciones que usted usará en el 95% de las oportunidades en las que tenga que usar rpm, dejaremos las mas complejas o inusuales para mas adelante.

Para tener una visión mas clara de qué es lo que hace cada una de ellas, veremos primero como se usa la opción en cuestión, luego tendremos una breve explicación de qué es lo que hace cada una de las opciones que se le pasan a rpm, y luego veremos un ejemplo práctico de su uso (para lo cual usaremos el paquete kima que es un software para KDE y cuya finalidad es la de monitorear varias fuentes de temperatura de nuestro hardware).

3.1.1. instala paquetes

Para instalar un paquete *.rpm, introducimos el siguiente comando (solo root):

# rpm -ivh paquete.rpm

-i (install)
instala el paquete *.rpm
-v (verbose)
de uso optativo, informa cuales son los pasos que se estan llevando a cabo
-h (hash)
de uso optativo también, muestra una hilera de "#" a medida que se instala el paquete

ejemplo de uso:

[gonzalo@inferna ~]$ su -
Contraseña:
[root@inferna ~]# cd /home/gonzalo/Descarga/
[root@inferna Descarga]$ pwd
/home/gonzalo/Descarga
[root@inferna Descarga]$ ls
kima-0.7.1-2mdv2007.0.i586.rpm
[root@inferna Descarga]# rpm -ivh kima-0.7.1-2mdv2007.0.i586.rpm
Preparing...                ########################################### [100%]
   1:kima                   ########################################### [100%]
[root@inferna ~]#

3.1.2. actualiza paquetes

Para actualizar un paquete, introducimos el siguiente comando (solo root):

# rpm -Uvh paquete.rpm

-U (update)
actualiza un paquete *.rpm
-v (verbose)
-h (hash)

3.1.3. elimina paquetes

Para eliminar un paquete, introducimos el siguiente comando (solo root):

# rpm -e paquete

-e (erase)
elimina un paquete *.rpm del sistema

ejemplo de uso:

[gonzalo@inferna ~]$ su -
Contraseña:
[root@inferna ~]# rpm -e kima

Nota: para eliminar un paquete, debe usarse el nombre del paquete SIN la extensión .rpm.

3.1.4. consulta base de datos de paquetes

Para saber si un paquete determinado se encuentra instalado en nuestro sistema, introducimos el siguiente comando:

$ rpm -qa | grep paquete

-q (query)
realiza un query o consulta sobre la base de datos que rpm mantiene con información sobre todos los paquetes instalados en nuestro sistema
-a (all)
devuelve los nombres de todos los paquetes instalados en nuestro sistema

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -qa | grep kima
kima-0.7.1-2mdv2007.0

3.1.5. consulta que archivos instaló un paquete

Para saber que archivos instaló en nuestro sistema un *.rpm determinado, introducimos el siguiente comando:

$ rpm -ql paquete

-q (query)
-l (list)
lista los archivos instalados por el paquete

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -ql kima
/usr/lib/kde3/libkima.la
/usr/lib/kde3/libkima.so
/usr/share/apps/kicker/applets/kima.desktop
/usr/share/doc/HTML/en/kima/common
/usr/share/doc/HTML/en/kima/index.cache.bz2
/usr/share/doc/HTML/en/kima/index.docbook
/usr/share/doc/kima-0.7.1
/usr/share/doc/kima-0.7.1/AUTHORS
/usr/share/doc/kima-0.7.1/COPYING
/usr/share/doc/kima-0.7.1/ChangeLog
/usr/share/doc/kima-0.7.1/INSTALL
/usr/share/doc/kima-0.7.1/NEWS
/usr/share/doc/kima-0.7.1/README
/usr/share/doc/kima-0.7.1/TODO
/usr/share/locale/de/LC_MESSAGES/kima.mo
/usr/share/locale/es/LC_MESSAGES/kima.mo
/usr/share/locale/hu/LC_MESSAGES/kima.mo

3.1.6. consulta que archivos instalará un paquete

Para saber que archivos instalará en nuestro sistema un *.rpm determinado, introducimos el siguiente comando:

$ rpm -qpl paquete.rpm

-q (query)
-p (package)
le avisa a rpm que "paquete.rpm" NO está instalado en nuestro sistema
-l (list)
lista los archivos contenidos en el paquete

ejemplo de uso:

[gonzalo@inferna ~]$ cd Descarga
[gonzalo@inferna Descarga]$ pwd
/home/gonzalo/Descarga
[gonzalo@inferna Descarga]$ ls
kima-0.7.1-2mdv2007.0.i586.rpm
[gonzalo@inferna Descarga]$ rpm -qpl kima-0.7.1-2mdv2007.0.i586.rpm
/usr/lib/kde3/libkima.la
/usr/lib/kde3/libkima.so
/usr/share/apps/kicker/applets/kima.desktop
/usr/share/doc/HTML/en/kima/common
/usr/share/doc/HTML/en/kima/index.cache.bz2
/usr/share/doc/HTML/en/kima/index.docbook
/usr/share/doc/kima-0.7.1
/usr/share/doc/kima-0.7.1/AUTHORS
/usr/share/doc/kima-0.7.1/COPYING
/usr/share/doc/kima-0.7.1/ChangeLog
/usr/share/doc/kima-0.7.1/INSTALL
/usr/share/doc/kima-0.7.1/NEWS
/usr/share/doc/kima-0.7.1/README
/usr/share/doc/kima-0.7.1/TODO
/usr/share/locale/de/LC_MESSAGES/kima.mo
/usr/share/locale/es/LC_MESSAGES/kima.mo
/usr/share/locale/hu/LC_MESSAGES/kima.mo

3.1.7. consulta archivos presentes en el sistema

Para saber a que paquete pertenece un archivo instalado en nuestro sistema, introducimos el siguiente comando:

$ rpm -qf /ruta/al/archivo

-q (query)
-f (file)
devuelve el nombre del paquete al que pertenece el archivo dado

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -qf /usr/lib/kde3/libkima.la
kima-0.7.1-2mdv2007.0

3.1.8. consulta metainfo de paquete instalado

Para obtener información general sobre un paquete instalado en nuestro sistema, introducimos el siguiente comando:

$ rpm -qi paquete

-q (query)
-i (info)
muestra info general sobre un paquete

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -qi kima
Name        : kima                         Relocations: (not relocatable)
Version     : 0.7.1                             Vendor: Mandriva
Release     : 2mdv2007.0                    Build Date: mié 21 mar 2007 15:48:48 ART
Install Date: mié 21 mar 2007 15:49:48 ART      Build Host: inferna
Group       : Graphical desktop/KDE         Source RPM: kima-0.7.1-2mdv2007.0.src.rpm
Size        : 337220                           License: GPL
Signature   : (none)
Packager    : Gonzalo Raúl Nemmi
URL         : http://www.elliptique.net/~ken/kima/
Summary     : Kicker Monitoring Applet.
Description :
This applet monitors various temperature, frequency and fan sources in your kicker panel.
Make sure you have enabled a supported kernel module.

3.1.9. consulta metainfo de paquete no instalado

Para obtener información general sobre un paquete que aun NO se encuentra instalado en nuestro sistema, pero que tenemos guardado en algun directorio (ya sea en nuestro HD o en un CD o DVD), introducimos el siguiente comando:

$ rpm -qpi paquete.rpm

-q (query)
-p (package)
le avisa a rpm que el "paquete.rpm" NO está instalado en el sistema
-i (info)

ejemplo de uso:

[gonzalo@inferna ~]$ cd Descarga
[gonzalo@inferna Descarga]$ pwd
/home/gonzalo/Descarga
[gonzalo@inferna Descarga]$ ls
kima-0.7.1-2mdv2007.0.i586.rpm
[gonzalo@inferna Descarga]$ rpm -qpi kima-0.7.1-2mdv2007.0.i586.rpm
Name        : kima                         Relocations: (not relocatable)
Version     : 0.7.1                             Vendor: Mandriva
Release     : 2mdv2007.0                    Build Date: mié 21 mar 2007 15:48:48 ART
Install Date: (not installed)               Build Host: inferna
Group       : Graphical desktop/KDE         Source RPM: kima-0.7.1-2mdv2007.0.src.rpm
Size        : 337220                           License: GPL
Signature   : (none)
Packager    : Gonzalo Raúl Nemmi
URL         : http://www.elliptique.net/~ken/kima/
Summary     : Kicker Monitoring Applet.
Description :
This applet monitors various temperature, frequency and fan sources in your kicker panel.
Make sure you have enabled a supported kernel module.

Como hemos visto en esta primera parte, rpm nos da un gran control sobre la administración del software instalado en nuestro sistema Linux. Nos permite instalar, actualizar y eliminar paquetes *.rpm presentes en nuestro sistema, saber a que paquete *.rpm pertenece cada uno de los archivos que componen nuestro sistema, saber que archivos instaló un paquete *.rpm determinado, que archivos instalará un paquete *.rpm determinado, que archivos desaparecerán al eliminar un *.rpm determinado, etc, etc.

3.2. rpm: uso intermedio

En esta sección vamos a ver algunas de las opciones de uso menos frecuente en rpm, pero que no por ello son menos utiles.

Para familiarizarnos un poco más con el uso de rpm, y para poder ver como funcionan estas opciones, usaremos para los ejemplos de esta sección el programa ifplugd (un daemon que monitorea el estado de las conexiones de red y las activa o desactiva según sea necesario) o hplip (Hewlett-Packard Linux Imaging and Printing) o ambos dos, según sea mas conveniente a los efectos de ejemplificar mejor las opciones de rpm, además de kima.

3.2.1. instala desde ftp

Para instalar un paquete que se encuentra ubicado en un servidor ftp, introducimos el siguiente comando (solo root):

# rpm -ivh ftp://USER:PASSWORD@HOST:PORT/ruta/al/paquete.rpm

-i (install)
-v (verbose)
-h (hash)

ejemplo de uso:

rpm -ivh ftp://****:****@ftp.inferna.com.ar:21/inferna.com.ar/wwwroot/rpm/kima-0.7.2-3mdv2007.0.i586.rpm

NOTA: si se omite la parte ":PASSWORD", rpm le solicitará que ingrese la password; si se omiten ambas partes (USER:PASSWORD), rpm usará acceso anonimo. En ambos casos se utilizará PASV para realizar la transferencia

3.2.2. instala desde http

Para instalar un paquete que se encuentra ubicado en un servidor http, introducimos el siguiente comando (solo root):

# rpm -ivh http://www.algunsitio.com/ruta/al/paquete.rpm

-i (install)
-v (verbose)
-h (hash)

ejemplo de uso:

[root@inferna ~]# rpm -e kima
[root@inferna ~]# rpm -q kima
package kima is not installed
[root@inferna ~]# rpm -ivh http://www.inferna.com.ar/rpm/kima-0.7.2-3mdv2007.0.i586.rpm
Retrieving http://www.inferna.com.ar/rpm/kima-0.7.2-3mdv2007.0.i586.rpm
Preparing...                ########################################### [100%]
   1:kima                   ########################################### [100%]
[root@inferna ~]# rpm -q kima
kima-0.7.2-3mdv2007.0
[root@inferna ~]#

NOTA: si necesita usar USER:PASSWORD, todo lo dicho para ftp se aplica a este caso también

3.2.3. reinstala paquetes

Para reinstalar un paquete *.rpm (esto es, para volver a instalar un paquete que ya se encuentra instalado, sobreescribiendo así los archivos que ya están presentes en nuestro sistema), introducimos el siguiente comando (solo root):

# rpm -i --replacepkgs paquete

-i (install)
--replacepkgs
reinstala el paquete sobreescribiendo el paquete que ya se encuentra instalado previamente

ejemplo de uso:

[root@inferna ~]# rpm -q kima
kima-0.7.1-2mdv2007.0
[root@inferna ~]# rpm -ivh /home/gonzalo/Descarga/kima-0.7.1-2mdv2007.0.i586.rpm
Preparing...                ########################################### [100%]
        package kima-0.7.1-2mdv2007.0 is already installed
[root@inferna ~]# rpm -ivh --replacepkgs /home/gonzalo/Descarga/kima-0.7.1-2mdv2007.0.i586.rpm
Preparing...                ########################################### [100%]
   1:kima                   ########################################### [100%]
[root@inferna ~]#

NOTA: a la opción -i puede agregarsele el uso de -v y -h (-ivh --replacepkgs) para obtener una salida más descriptiva sobre la actividad de rpm como se hizo en el ejemplo.

3.2.4. intalación forzada de paquetes

Para forzar la instalación de un paquete, introducimos el siguiente comando (solo root):

# rpm -i --force paquete

NOTA: se recomiendo enfaticamente no utilizar esta opción salvo que sepa exactamente lo que está haciendo y tenga la certeza de que es absolutamente necesario hacerlo.

3.2.5. consulta archivo de configuración

Para saber cual es el archivo de configuración de un software empaquetado en rpm, introducimos el siguiente comando:

$ rpm -qc paquete

-q (query)
-c (config)
nos muestra la ruta completa al archivo de configuración del software instalado por el paquete

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -qc ifplugd
/etc/ifplugd/ifplugd.conf
[gonzalo@inferna ~]$ rpm -qc hplip
/etc/hp/hplip.conf
/etc/rc.d/init.d/hplip
[gonzalo@inferna ~]

3.2.6. consulta sobre documentación

Para saber cuales son los archivos de documentación de una aplicación empaquetada en un archivo *.rpm, introducimos el siguiente comando:

rpm -qd paquete

-q (query)
-d (docfiles)
devuelve solamente los archivos de documentación

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -qd ifplugd
/usr/share/doc/ifplugd-0.28/LICENSE
/usr/share/doc/ifplugd-0.28/NEWS
/usr/share/doc/ifplugd-0.28/README
/usr/share/doc/ifplugd-0.28/README.html
/usr/share/doc/ifplugd-0.28/style.css
/usr/share/man/man5/ifplugd.conf.5.bz2
/usr/share/man/man8/ifplugd.8.bz2
/usr/share/man/man8/ifplugstatus.8.bz2

3.2.7. consulta changelog del paquete

Para saber cuales fueron los cambios que se introdujeron en la ultima versión de un paquete *.rpm, introducimos el siguiente comando:

$ rpm -q --changelog paquete

-q (query)
--changelog
muestra el changelog completo del paquete (usualmente se usa junto con | head -10)

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -q --changelog ifplugd | head -10
* mar jul 25 2006 Olivier Blin <blino@mandriva.com> 0.28-5mdv2007.0
- do not abort if mdv-network-event fails

* jue jul 20 2006 Olivier Blin <blino@mandriva.com> 0.28-4mdv2007.0
- Patch1: send link up/down events using mdv-network-event
- Patch2: fix include conflict with linux headers by defining __KERNEL_STRICT_NAMES

* vie ene 27 2006 Olivier Blin <oblin@mandriva.com> 0.28-3mdk
- remove included libdaemon (thus making Laurent's fix finally valid :-)
- remove man page path workaround

3.2.8. consulta dependencias

Para saber de que software (ya sea programas o librerias) depende un paquete determinado, introducimos el siguiente comando:

$ rpm -q --requires paquete

-q (query)
--requires
devuelve la lista de dependencias (ó requerimientos) del programa empaquetado

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -q --requires ifplugd
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1
bash
libc.so.6
libc.so.6(GLIBC_2.0)
libc.so.6(GLIBC_2.1)
libc.so.6(GLIBC_2.3)
libc.so.6(GLIBC_2.3.4)
libdaemon.so.0
[gonzalo@inferna ~]$

3.2.9. consulta scripts de instalación

Para saber cuales son los scripts y rutinas que rpm ejecutará a la hora de instalar, actualizar o eliminar un paquete *.rpm de nuestro sistema, introducimos el siguiente comando:

rpm -q --scripts paquete

-q (query)
--scripts
muestra los scripts que se ejecutan al instalar, actualizar o eliminar un paquete *.rpm

ejemplo de uso:

[gonzalo@inferna ~]$ rpm -q --scripts hplip
postinstall scriptlet (using /bin/sh):
# Let HPLIP daemons be automatically started at boot time
/usr/share/rpm-helper/add-service hplip $1 hplip
# Menu update
if [ -x /usr/bin/update-menus ]; then /usr/bin/update-menus || true ; fi

# Restart CUPS to make the Fax PPD known to it
/sbin/service cups condrestart > /dev/null 2>/dev/null || :
preuninstall scriptlet (using /bin/sh):
# Let HPLIP daemons not be automatically started at boot time any more
/usr/share/rpm-helper/del-service hplip $1 hplip
postuninstall scriptlet (using /bin/sh):
## Menu update
if [ -x /usr/bin/update-menus ]; then /usr/bin/update-menus || true ; fi

# Restart CUPS to make the removal of the Fax PPD known to it
/sbin/service cups condrestart > /dev/null 2>/dev/null || :
[gonzalo@inferna ~]$

3.2.10. reconstruye la base de datos

Para reconstruir la base de datos que utiliza rpm para guardar toda la información relativa a los paquetes *.rpm instalados en nuestro sistema, introducimos el siguiente comando:

# rpm --rebuilddb

--rebuilddb (rebuild data base)
reconstruye la base de datos de rpm

ejemplo de uso:

[root@inferna ~]# rpm --rebuilddb
[root@inferna ~]#

4. rpm: empaquetando aplicaciones

En esta parte, vamos a ver como es que se crea un archivo .*rpm de principio a fin.

Para ejemplificar el procedimiento, vamos a empaquetar un software que encontre hace unos dias en kde-apps y que se llama kuftp (un cliente de FTP para KDE); nos bajamos el source y lo guardamos en nuestro directorio /home

4.1. config inicial

Previo a todo, y para poder crear exitosamente un paquete *.rpm como un usuario común del sistema (y nunca como root), son necesarias dos cosas:

4.1.1. el arbol de directorios

El arbol de directorios es el lugar en el cual rpm va a llevar a cabo todas las operaciones necesarias para convertir un paquete *.tar.gz o *.tar.bz2 en un paquete *.rpm.

Para poder llevar a cabo estas operaciones, rpm necesita de una serie de directorios especificos, estos son los directorios: BUILD/ BUILDROOT/ SOURCES/ SPECS/ SRPMS/ RPMS/.

Y para que sirve cada uno de estos directorios?

BUILD/
directorio en el que se descomprime y compila el contenido del *.tar.gz

BUILDROOT/
directorio en el que se instalará temporariamente el soft a empaquetar

SOURCES/
directorio en el que se ubica el *.tar.gz/*.tar.bz2 que contiene el código fuente del programa a empaquetar

SPECS/
directorio en el que se ubica el *.spec

SRPMS/
directorio al que van a parar los *.srpm

RPMS/
directorio al que van a parar los *.rpm una vez que fueron creados

Vamos entonces a crear un directorio cualquiera, al que en nuestro caso llamaremos misrpm pero usted puede elegir ese o cualquier otro nombre que se le antoje como mispaquetes o misaplicaciones o rpm si así lo prefiere, que será aquel al cual más adelante rpm se referirá como %{_topdir}, y bajo este directorio vamos a crear el resto de los directorios que rpm necesita.

[gonzalo@inferna ~]$ pwd
/home/gonzalo
[gonzalo@inferna ~]$ mkdir -p misrpm/{BUILD{ROOT,},RPMS,S{OURCE,RPM,PEC}S}
[gonzalo@inferna ~]$ ls misrpm/
BUILD/  BUILDROOT/  RPMS/  SOURCES/  SPECS/  SRPMS/
[gonzalo@inferna ~]$

Listo, ya tenemos el arbol de directorios completo y ya sabemos para que sirve cada uno de los directorios, asi que aprovechamos y movemos el source de la aplicación que vamos a empaquetar dentro del directorio que corresponde.

[gonzalo@inferna ~]$ mv kuftp-0.8.0.tar.bz2 misrpm/SOURCES/
[gonzalo@inferna ~]$ ls misrpm/SOURCES/
kuftp-0.8.0.tar.bz2

Ahora solo hace falta indicarle a rpm donde están ubicados esos directorios, y algunas informaciones más que veremos a continuación.

4.1.2. el archivo .rpmmacros

Para informarle a rpm donde esta ubicado en nuestro sistema el arbol de directorios que usará para crear los paquetes *.rpm, vamos a crear el archivo de configuración de rpm.

Para esto, tendremos que crear en nuestro directorio home (/home/~), un archivo llamado ".rpmmacros", con el siguiente contenido:

[gonzalo@inferna ~]$ pwd
/home/gonzalo
[gonzalo@inferna ~]$ cat <<EOF > /home/gonzalo/.rpmmacros
># macros obligatorias:
>%_topdir       /home/gonzalo/misrpm    # directorio root ó "/" para construir rpm
>%_specdir      %_topdir/SPECS          # directorio en el que se ubica el *.spec
>%_sourcedir    %_topdir/SOURCES        # directorio en el que se ubica el *.tar.gz
>%_builddir     %_topdir/BUILD          # directorio en el que se descomprime y compila el contenido del *.tar.gz
>%_tmppath      %_topdir/BUILDROOT      # directorio en el que se instalará el soft a empaquetar
>%_rpmdir       %_topdir/RPMS           # directorio al que van a parar los *.rpm una vez que fueron creados
>%_srcrpmdir    %_topdir/SRPMS          # directorio al que van a parar los *.srpm
>
># macros optativas (si queremos firmar digitalmente los paquetes)
>%_signature    gpg                     # tipo de llave, si se usare alguna
>%_gpg_path     /home/gonzalo/.gnupg    # ubicacion de la llave si la hubiere
>%_gpg_name     Mandrivalinux
>
># mas macros optativas
>%packager      Gonzalo Raul Nemmi  # nombre del empaquetador, sin acentos
>%distribution  Mandriva Linux      # distro para la cual se crea el paquete
>%vendor        Mandriva
>EOF

NOTA: cuando una linea comienza con un simbolo "#", rpm considerará que todo lo que le sigue es un comentario y (como en bash) no interpretará más nada hasta que encuentre el caractér de fin de línea.

Notesé que a %_topdir le asigné el valor "/home/gonzalo/misrpm". Usted deberá modificar este valor y otros valores como %packager, %distribution, %vendor, etc, según su caso.

Y porque necesitamos el archivo .rpmmacros??

Bueno, al igual que un gran número de programas disponibles en nuestro sistema Linux, rpm tiene un archivo de configuración de macros general o "system wide" (que generalmente se encuentra ubicado en /usr/lib/rpm/macros) que lo provee de la información necesaria para poder funcionar y un archivo de configuración personal o "per user" (que es nuestro .rpmmacros) que es el que contiene información que rpm usará preferencialmente por sobre la del archivo "system wide".

Es siempre conveniente, y en algunos casos obligatorio, buscar en la documentacion de la distribucion para la cual deseamos crear el paquete en custión, información sobre cual debe ser el contenido del archivo .rpmmacros, dado que muchas distribuciones requieren, obligatoriamente, que los paquetes que los contribuidores construyen sean firmados digitalmente, otras requieren que la macro %vendor contenga el nombre de la distribución en lugar del nombre del autor del software que se empaqueta o que no se use la macro %packager y asi por delante.

Por eso, lo primero que tenemos que hacer cuando decidimos crear un paquete *.rpm con miras a poder distribuirlo para que todos los usuarios de una distribución puedan usarlo, es leer detenidamente la documentación que las distribuciones ponen a disposición de los colaboradores/empaquetadores y seguir los lineamientos y directivas descriptas en ella.

4.2. el archivo *.spec

El archivo *.spec es el archivo que contiene toda la informacion que rpm necesita para poder compilar y empaquetar un soft determinado. Es, basicamente, el equivalente a un script o rutina que le informará a rpm que hacer con un paquete (ya sea tar.gz, tar.bz2, etc) que contiene el código fuente de un programa de software y como hacerlo

A los fines de entender mejor la estructura de un archivo *.spec podemos decir que, a grandes rasgos, estos están compuesto por cuatro partes generales o secciones.

La primera parte o header de un archivo *.spec contiene el conjunto de informaciónes administrativas propias del paquete, como ser el nombre del software, la version del software, el release del paquete, el tipo de licensia bajo la cual se distribuye el software en su estado fuente, la dirección desde donde puede descargarse el archivo fuente, el nombre del empaquetador, las dependencias del paquete, etc; para ser mas claros: la primera parte del archivo *.spec, contiene toda la información que rpm nos devuelve cada vez que ejecutamos el comando rpm -qi sobre un paquete y algunos datos mas.

La segunda parte, a la que llamaremos prep del archivo *.spec, está compuesta por una serie de directivas (algunas son scripts de shell, otras son macros) que le indicarán a rpm como compilar y empaquetar el soft en cuestión, que hacer luego de haber empaquetado exitosamente el software, que scripts o rutinas deben llevarse a cabo antes o despues de instalar, actualizar o eliminar el paquete, y algunos datos más.

La tercera parte o files del archivo *.spec, está compuesta por una lista que enumera a la totalidad de los archivos que serán empaquetados para su posterior instalación en el sistema. Además, contiene también información que describe la naturaleza de cada uno de estos archivos, como por ejemplo si estos son archivos de configuración, o archivos de documentación, o si son directorios, o cuales son los permisos con los cuales deben ser instalados en el sistema, etc.

La cuarta parte o changelog del archivo *.spec está compuesta por un relato, lo más detallado posible, sobre qué es lo que el empaquetador hizo, tanto con el software empaquetado como con el archivo *.spec en cada una de las releases que empaquetó, esto es, por ejemplo, porqué se aplicó tal o cual parche, porqué se modificaron los parametros de la macro %configure, porqué se cambio el nombre del paquete, porqué se creó un subpaquete, etc. En súma, en el changelog debe estar detalladamente descripta toda la vida del paquete, desde que se lo creo por primera vez.

Veamos ahora un archivo *.spec, simple pero completo, para que sepamos de lo que estamos hablando y luego pasemos a analizarlo en detalle.

[gonzalo@inferna ~]$ cat misrpm/SPECS/kuftp.spec
Name:           kuftp
Version:        0.8.0
Release:        1
Summary:        KuFtp is a graphical FTP client for the K Desktop Environment.
License:        GPL
Group:          Networking/File transfer
URL:            http://www.kde-apps.org/content/show.php/kuftp?content=58933
Source:         %{name}-%{version}.tar.bz2
BuildRequires:  libkdecore4-devel >= 3.5.4
BuildRequires:  libqt3-devel >= 3.3.6
BuildRequires:  libopenssl0.9.8-devel
Requires:       libkdecore4
Requires:       libqt3
Requires:       libopenssl0.9.8
Buildroot:      %{_tmppath}/%{name}-%{version}

%description
KuFtp is a graphical FTP client for the K Desktop Environment. Most
notable features is Tab Sessions like Konqueror or Firefox, that is, you can have multiple
simultaneous FTP session in separate tabs.

#----------------------------------------------------------

%prep

%setup -q

%build
./configure \
        --prefix=/usr

make -j ${NRPROC:-1}

%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install

%clean
rm -rf %{buildroot}

#----------------------------------------------------------

%files
%defattr (-,root,root)
%attr(0755,root,root) /usr/bin/kuftp
/usr/share/applnk/Utilities/kuftp.desktop
/usr/share/apps/kuftp/kuftpui.rc
/usr/share/icons/hicolor/128x128/apps/kuftp.png
/usr/share/icons/hicolor/16x16/apps/kuftp.png
/usr/share/icons/hicolor/22x22/apps/kuftp.png
/usr/share/icons/hicolor/32x32/apps/kuftp.png
/usr/share/icons/hicolor/48x48/apps/kuftp.png
/usr/share/icons/hicolor/64x64/apps/kuftp.png
/usr/share/locale/zh_CN/LC_MESSAGES/kuftp.mo
%doc AUTHORS ChangeLog COPYING INSTALL NEWS README TODO
/usr/share/doc/HTML/en/kuftp/common
/usr/share/doc/HTML/en/kuftp/index.cache.bz2
/usr/share/doc/HTML/en/kuftp/index.docbook

#----------------------------------------------------------

%changelog
* Sat Jun 30 2007 Gonzalo Raul Nemmi <gnemmi@gmail.com>
- first release

NOTA: a los efectos de que el archivo *.spec sea mas claro a los ojos del lector, he separado las distintas secciones usando líneas del tipo "#---"; cabe en consecuencia aclarar que no es necesario que haga esto en su *.spec, aunque si es normal hacerlo, y hasta es recomendable, ya que nuestro propio *.spec puede llegar a ser leido por alguien más en algún momento.

Vale la pena aclarar que los archivos *.spec deben ser creados usando el nombre de la aplicación que vamos a empaquetar seguida por la extension .spec. En nuestro caso, nuestro *.spec se llamará kuftp.spec.

Sientase libre ahora de abrir su editor de textos favorito, copiar el contenido de este ejemplo, pegarlo en su editor y guardarlo con el nombre kuftp.spec en del directorio SPECS/ que creamos dentro del arbol de directorios de rpm.

Listo, terminamos de crear nuestro archivo *.spec.

Pasemos ahora a analizar parte por parte nuestro flamante kuftp.spec para entender porque lo creamos de esta manera.

4.2.1. *.spec: header

4.2.1.1. Name:

El tag Name: se usa para definir el nombre del paquete.

Para mantener la uniformidad entre todos los paquetes que forman parte de una distribución, es recomendable que el nombre este siempre en minusculas, aún cuando el nombre original del software que estamos empaquetando tenga alguna o todas sus letras en mayusculas.

Este tag es de uso obligatorio y siempre debe estar presente.

En nuestro ejemplo:

Name:           kuftp

NOTA: se hace oportuno aclarar en este momento, que cada distribución tiene sus propias politicas sobre como debe "nombrarse" un paquete *.rpm. Por favor consulte la documentación de su distribución a este respecto. A modo de ejemplo, pongo a su alcance la politica de nombres de Mandriva Linux

4.2.1.2. Version:

El tag Version: se usa para definir la version del software que estamos empaquetando.

Este tag es de uso obligatorio y siempre debe estar presente.

En nuestro ejemplo:

Version:        0.8.0

4.2.1.3. Release:

El tag Release: se usa para definir el release del paquete que estamos creando.

El tag Release: es similar al tag Version:, solo que mientras Version: se usa para describir la versión del software que estamos empaquetando, Release: se usa para describir la versión del paquete en si mismo (siendo que podemos tener varios releases del mismo paquete, como acontece cuando tenemos que aplicar un parche de seguridad a algún software, reempaquetarlo y redistribuirlo como actualización o update.)

Al respecto cabe aclarar que cada distribución tiene politicas propias sobre como debe usarse este tag, aunque en lineas generales, es suficiente con agregar un numero, pero si quiere crear seriamente un paquete, deberá buscar en la documentación de su distribución las indicaciones sobre como completar este tag. Una vez más y a modo de ejemplo, pongo a su alcance la politica de versionado de Mandriva Linux

En nuestro ejemplo:

Release:        1

4.2.1.4. Summary:

El tag Summary: se usa para brindar una descripción breve del software que estamos empaquetando.

Este tag es de uso obligatorio y siempre debe estar presente.

En nuestro ejemplo:

Summary:        KuFtp is a graphical FTP client for the K Desktop Environment.

4.2.1.5. License:

El tag License: se usa para definir el tipo de licencia bajo la cual se distribuye el software que estamos empaquetando.

Los tipos de licencia son varios, como ser: GPL, LGPL, BSD, etc. Será necesario también, revisar la documentación de su distribución para saber si el software en cuestión se encuentra bajo los tipos de licencia autorizados por la misma. A modo de ejemplo, pongo a su alcance la politica de Licencias de Mandriva Linux

Este tag es de uso obligatorio y siempre debe estar presente en todo archivo *.spec..

En nuestro ejemplo:

License:        GPL

4.2.1.6. Group:

El tag Group: se usa para definir el nombre del grupo o conjunto de aplicaciónes al que pertenece el programa que estamos empaquetando

Cabe aclarar aquí que cada distribución tiene sus grupos propios, y en consecuencia, es necesario revisar la documentación de su distribución para saber a que grupo pertenecerá el software en cuestión. A modo de ejemplo, pongo a su disposición la lista de grupos de Mandriva Linux, y siendo que en este caso estamos empaquetando un cliente de ftp para KDE, el grupo que corresponde usar es Networking/File transfer.

En nuestro ejemplo:

Group:          Networking/File transfer

4.2.1.7. URL:

El tag URL: se usa para indicar la dirección o url de la pagina o home del software que estamos empaquetando.

En nuestro ejemplo:

URL:            http://www.kde-apps.org/content/show.php/kuftp?content=58933

4.2.1.8. Source:

El tag Source: se usa para indicar la dirección o url en la cual se encuentran alojados el o los archivos que componen al código fuente (source) del software que estamos empaquetando.

Si no tuvieramos a nuestra dispocición la dirección o url desde donde puede descargarse el source del software que estamos empaquetando (cosa que sucede habitualmente cuando el servidor usa PHP por ejemplo), entonces será suficiente con escribir tan solo el nombre completo del source (como en el ejemplo que usamos en este caso).

En resumen, ésta es la ubicación, ya sea local (en nuestro disco rígido) o remota (en alguna pagina o servidor de internet) en la cual se encuentra el source del software que vamos a empaquetar.

En nuestro ejemplo:

Source:         kuftp-0.8.0.tar.bz2

Vale la pena aclarar que si el software que estamos empaquetando está formado por más de un source, solo tendremos que enumerarlos de la siguiente manera:

Source:
Source1:
Source2:
...

4.2.1.9. Patch

El tag Patch: se usa para definir el nombre del archivo *.diff que vamos a utilizar para parchear el código fuente del software, si es que fuera necesario hacerlo.

Si fuera necesario aplicar más de un patch, solo tendremos que enumerarlos de la siguiente manera:

Patch0:
Patch1:
Patch2:
...

En nuestro ejemplo, no fue necesario aplicar ningún parche al software que vamos a empaquetar, y por eso no lo hemos usado.

4.2.1.10. BuildRequires:

El tag BuildRequires: puede o no estar presente, y puede o no repetirse ya que es el mismo sirve para definir el/los nombres de el/los paquetes que haga falta tener instalados en el sistema para poder compilar el software en cuestion; como por ejemplo, ciertas librerias.

En nuestro ejemplo:

BuildRequires:  libkdecore4-devel >= 3.5.4
BuildRequires:  libqt3-devel >= 3.3.6
BuildRequires:  libopenssl0.9.8-devel

4.2.1.11. Requires:

El tag Requires: es similar al campo anterior (BuildRequires:) siendo que al igual que el otro, este también puede o no estar presente, y puede o no repetirse ya que es el tag que sirve para definir el/los nombre de el/los paquetes que haga falta tener instalados antes de poder instalar en nuestro sistema el paquete en cuestión.

En suma, es este el tag que se utiliza para describir cuales son las dependencias, si las hubiere, del paquete que estamos creando.

En nuestro ejemplo:

Requires:       libkdecore4
Requires:       libqt3
Requires:       libopenssl0.9.8

NOTA: si usted no conoce cuales son las dependencias del software que esta empaquetabdo, no utilice este tag, no coloque ninguna dependencia y rpm las detectará y declarará por usted.

4.2.1.12. Buildroot:

El tag Buildroot: se usa para informarle a rpm el nombre del directorio que deberá utilizar para instalar temporariamente el software (como si se tratase del directorio /) para luego poder empaquetarlo.

En nuestro ejemplo:

Buildroot:      %{_tmppath}/%{name}-%{version}

NOTA: el valor asignado a este tag (%{_tmppath}/%{name}-%{version}) no debe cambiar nunca y debe usarse siempre de la misma manera, sin importar que sea lo que estemos empaquetando.

4.2.1.13. %description

La directiva %description sirve para que escribimos una descripción completa (a diferencia del tag Summary: que solo contiene una descripcion breve) del software que estamos empaquetando.

La directiva %description es de uso obligatorio y siempre debe estar presente en todo archivo *.spec..

En nuestro ejemplo:

%description
KuFtp is a graphical FTP client for the K Desktop Environment. Most
notable features is Tab Sessions like Konqueror or Firefox, that is, you can have multiple
simultaneous FTP session in separate tabs.

4.2.2. *.spec: prep y build

4.2.2.1. %prep

Esta directiva contiene todas las instrucciones necesarias para descompactar y preparar el source de la aplicación que queremos empaquetar.

En nuestro ejemplo:

%prep

Al leerla, rpm ejecuta:

Executing(%prep): /bin/sh -e /home/gonzalo/misrpm/BUILDROOT/rpm-tmp.59785
+ umask 022
+ cd /home/gonzalo/misrpm/BUILD
+ '[' 1 -eq 1 ']'
+ '[' 1 -eq 1 ']'
+ '[' 1 -eq 1 ']'
+ exit 0

4.2.2.2. %setup

Esa macro contiene todas las instrucciones necesarias para descomprimir el source.

En nuestro ejemplo:

%setup -q

Al leerla, rpm ejecuta:

+ cd /home/gonzalo/misrpm/BUILD
+ rm -rf kuftp-0.8.0
+ /usr/bin/bzip2 -dc /home/gonzalo/misrpm/SOURCES/kuftp-0.8.0.tar.bz2
+ tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd kuftp-0.8.0
+ exit 0

La opción -q (quiet) sirve para que, en lugar de ejecutar el comando tar -xvvf - y mandar al stdout el listado de todos los archivos que descomprime, ejecute el comando tar -xf - y no mande nada al stdout.

4.2.2.3. %build

Esta directiva es la que recibe y ejecuta todas las instrucciones necesarias para configurar y compilar el source de la aplicación que queremos empaquetar.

Por debajo de ella, vamos a ubicar al script ./configure (con todos los parámetros que fueran necesario pasarle) y al comando make.

En nuestro ejemplo:

%build
./configure \
        --prefix=/usr

make -j ${NRPROC:-1}

Al leerla, rpm ejecuta:

Executing(%build): /bin/sh -e /home/gonzalo/misrpm/BUILDROOT/rpm-tmp.76420
+ umask 022
+ cd /home/gonzalo/misrpm/BUILD
+ cd kuftp-0.8.0
+ '[' 1 -eq 1 ']'
+ '[' 1 -eq 1 ']'
+ ./configure --prefix=/usr
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... i686-pc-linux-gnu
...
...
Good - your configure finished. Start make now

+ make -j 1

4.2.2.4. %install

Esta es la directiva que se encarga de ejecutar la instalación del software en el sistema (que usualmente se lleva a cabo con la ejecución del comando make install), solo que en lugar de instalar el software en el sistema (o sea, bajo el directorio /), lo instalará temporariamente bajo el directorio definido en el campo BuildRoot:, para luego empaquetarlo. Es por eso que siempre hay que pasarle el comando rm -rf %{buildroot} (para asegurarnos de que no haya quedado en el %{buildroot} algún archivo que pertenezca a algun paquete anterior) antes de realizar el make DESTDIR=%{buildroot} install.

En nuestro ejemplo:

%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install

4.2.2.5. %clean

Esta directiva se encarga de limpiar el contenido del directorio definido por el campo BuildRoot: para asegurarnos de que no quede en él absolutamente nada que pueda interferir con la construcción de algún otro paquete posterior.

En nuestro ejemplo:

%clean
rm -rf %{buildroot}

4.2.3. *.spec: files

4.2.3.1. %files

Esta es la directiva que determina cuales son los archivos que habrán de instalarse en el sistema. Esto es, bajo esta directiva encontraremos la lista de los archivos que serán copiados a nuestro sistema cuando instalemos un paquete *.rpm.

Se acuerda de los comando rpm -ql paquete y rpm -qpl paquete?

Bueno, ahora ya sabe como es que rpm sabe cuales son los archivos que instaló (o instalará) un paquete *.rpm determinado =)

4.2.3.2. %defattr

Esta es la directiva que se utiliza para establecer cuales serán los permisos que tendrán todos los archivos que instalará el paquete.

4.2.3.3. %attr

Esta es la directiva que se utiliza para establecer cuales serán los permisos que tendrá un archivo en particular de los que instalará el paquete.

4.2.3.4. %doc

Esta es la directiva que le indica a rpm que todos los archivos que esten a continuación, son archivos de documentación.

Se acuerda de los comando rpm -qd paquete y rpm -qpd paquete?

Bueno, ahora ya sabe como es que rpm identifica a los archivos de documentación de entre todos los archivos que instalá un *.rpm =)

4.2.4. *.spec: changelog

4.2.4.1. %changelog

Esta es la directiva que se utiliza para llevar un detallado registro de todos los cambios que tienen lugar a lo largo del proceso de creación y manutención de un paquete *.rpm.

Todo el texto que se encuentra por debajo de la misma tiene la unica finalidad de documentar, en forma clara y objetiva, todos los cambios que fue sufriendo el paquete desde que fue creado por primera vez y hasta su ultimo release, ya sea por actualización del software empaquetado o por alteraciónes de datos como fechas, horarios, nombres de archivos, scripts, cambio de empaquetador, etc

Su existencia es obligatoria y siempre debe estar compuesta por:

1) Una primera linea que contiene:

en nuestro ejemplo

* Sat Jun 30 2007 Gonzalo Raul Nemmi <gnemmi@gmail.com>

2) La descripción de los cambios, en lineas de un solo renglon que comienzan con el signo "-"

en nuestro ejemplo:

- first release

En suma:

%changelog
* Sat Jun 30 2007 Gonzalo Raul Nemmi <gnemmi@gmail.com>
- first release

4.3. empaquetando

Finalmente y habiendo creado nuestro arbol de directorios y nuestro archivo de configuración .rpmmacros, con nuestro kuftp.spec ubicado dentro del directorio misrpm/SPECS y con el source del software que vamos a empaquetar ubicado dentro del directorio misrpm/SOURCES, podemos decir que estamos listos para crear nuestro primer paquete *.rpm.

Verificamos que todo este en su lugar:

[gonzalo@inferna ~]$ ls -R misrpm/
misrpm/:
BUILD/  BUILDROOT/  RPMS/  SOURCES/  SPECS/  SRPMS/

misrpm/BUILD:

misrpm/BUILDROOT:

misrpm/RPMS:

misrpm/SOURCES:
kuftp-0.8.0.tar.bz2

misrpm/SPECS:
kuftp.spec

misrpm/SRPMS:

Y ahora si, para crear un paquete *.rpm, introducimos el siguiente comando:

$ rpmbuild -ba /ruta/al/archivo/spec

-b (build)
indica a rpmbuild que deberá construir un paquete.
-a (all)
indica a rpmbuild que deberá ejecutar todas las etapas de la construcción.

en nuestro caso:

[gonzalo@inferna ~]$ rpmbuild -ba misrpm/SPECS/kuftp.spec
Executing(%prep): /bin/sh -e /home/gonzalo/misrpm/BUILDROOT/rpm-tmp.51276
+ umask 022
+ cd /home/gonzalo/misrpm/BUILD
+ '[' 1 -eq 1 ']'
+ '[' 1 -eq 1 ']'
+ '[' 1 -eq 1 ']'
+ cd /home/gonzalo/misrpm/BUILD
+ rm -rf kuftp-0.8.0
+ /usr/bin/bzip2 -dc /home/gonzalo/misrpm/SOURCES/kuftp-0.8.0.tar.bz2
+ tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd kuftp-0.8.0
+ exit 0
Executing(%build): /bin/sh -e /home/gonzalo/misrpm/BUILDROOT/rpm-tmp.49491
+ umask 022
+ cd /home/gonzalo/misrpm/BUILD
+ cd kuftp-0.8.0
+ '[' 1 -eq 1 ']'
+ '[' 1 -eq 1 ']'
+ ./configure --prefix=/usr
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
...
...
Good - your configure finished. Start make now
+ make -j 1
make  all-recursive
make[1]: se ingresa al directorio `/home/gonzalo/misrpm/BUILD/kuftp-0.8.0'
...
...
make[1]: se sale del directorio `/home/gonzalo/misrpm/BUILD/kuftp-0.8.0'
+ exit 0
Executing(%install): /bin/sh -e /home/gonzalo/misrpm/BUILDROOT/rpm-tmp.27564
+ umask 022
+ cd /home/gonzalo/misrpm/BUILD
+ cd kuftp-0.8.0
+ '[' 1 -eq 1 ']'
+ rm -rf /home/gonzalo/misrpm/BUILDROOT/kuftp-0.8.0
+ make DESTDIR=/home/gonzalo/misrpm/BUILDROOT/kuftp-0.8.0 install
Making install in doc
make[1]: se ingresa al directorio `/home/gonzalo/misrpm/BUILD/kuftp-0.8.0/doc'
Making install in .
...
...
Processing files: kuftp-0.8.0-1
Executing(%doc): /bin/sh -e /home/gonzalo/misrpm/BUILDROOT/rpm-tmp.55025
+ umask 022
+ cd /home/gonzalo/misrpm/BUILD
+ cd kuftp-0.8.0
+ DOCDIR=/home/gonzalo/misrpm/BUILDROOT/kuftp-0.8.0/usr/share/doc/kuftp-0.8.0
+ export DOCDIR
...
...
Executing(%clean): /bin/sh -e /home/gonzalo/misrpm/BUILDROOT/rpm-tmp.1292
+ umask 022
+ cd /home/gonzalo/misrpm/BUILD
+ cd kuftp-0.8.0
+ rm -rf /home/gonzalo/misrpm/BUILDROOT/kuftp-0.8.0
+ exit 0
[gonzalo@inferna ~]$

Si todo sale bien y la ejecución del comando culmina con un + exit 0 como podemos ver en el ejemplo, nuestros flamantes *.rpm y *.src.rpm estarán ubicados en misrpm/RPMS/ARCH y misrpm/SRPMS:

[gonzalo@inferna ~]$ ls -R misrpm/
misrpm/:
BUILD/  BUILDROOT/  RPMS/  SOURCES/  SPECS/  SRPMS/

misrpm/BUILD:

misrpm/BUILDROOT:

misrpm/RPMS:
i586/

misrpm/RPMS/i586:
kuftp-0.8.0-1.i586.rpm

misrpm/SOURCES:
kuftp-0.8.0.tar.bz2

misrpm/SPECS:
kuftp.spec

misrpm/SRPMS:
kuftp-0.8.0-1.src.rpm

Hacemos algunas pruebas sobre nuestro flamante kuftp-0.8.0-1.i586.rpm:

[gonzalo@inferna ~]$ rpm -qpi misrpm/RPMS/i586/kuftp-0.8.0-1.i586.rpm
Name        : kuftp                        Relocations: (not relocatable)
Version     : 0.8.0                             Vendor: Mandriva
Release     : 1                             Build Date: sáb 30 jun 2007 22:59:13 ART
Install Date: (not installed)               Build Host: inferna.com.ar
Group       : Networking/File transfer      Source RPM: kuftp-0.8.0-1.src.rpm
Size        : 307040                           License: GPL
Signature   : (none)
Packager    : Gonzalo Raul Nemmi <gnemmi@gmail.com>
URL         : http://www.kde-apps.org/content/show.php/kuftp?content=58933
Summary     : KuFtp is a graphical FTP client for the K Desktop Environment.
Description :
KuFtp is a graphical FTP client for the K Desktop Environment. Most
notable features is Tab Sessions like Konqueror or Firefox, that is, you can have multiple
simultaneous FTP session in separate tabs.
[gonzalo@inferna ~]$ rpm -qpd misrpm/RPMS/i586/kuftp-0.8.0-1.i586.rpm
/usr/share/doc/HTML/en/kuftp/common
/usr/share/doc/HTML/en/kuftp/index.cache.bz2
/usr/share/doc/HTML/en/kuftp/index.docbook
/usr/share/doc/kuftp-0.8.0/AUTHORS
/usr/share/doc/kuftp-0.8.0/COPYING
/usr/share/doc/kuftp-0.8.0/ChangeLog
/usr/share/doc/kuftp-0.8.0/INSTALL
/usr/share/doc/kuftp-0.8.0/NEWS
/usr/share/doc/kuftp-0.8.0/README
/usr/share/doc/kuftp-0.8.0/TODO
[gonzalo@inferna ~]$ rpm -qpl misrpm/RPMS/i586/kuftp-0.8.0-1.i586.rpm
/usr/bin/kuftp
/usr/share/applnk/Utilities/kuftp.desktop
/usr/share/apps/kuftp/kuftpui.rc
/usr/share/doc/HTML/en/kuftp/common
/usr/share/doc/HTML/en/kuftp/index.cache.bz2
/usr/share/doc/HTML/en/kuftp/index.docbook
/usr/share/doc/kuftp-0.8.0
/usr/share/doc/kuftp-0.8.0/AUTHORS
/usr/share/doc/kuftp-0.8.0/COPYING
/usr/share/doc/kuftp-0.8.0/ChangeLog
/usr/share/doc/kuftp-0.8.0/INSTALL
/usr/share/doc/kuftp-0.8.0/NEWS
/usr/share/doc/kuftp-0.8.0/README
/usr/share/doc/kuftp-0.8.0/TODO
/usr/share/icons/hicolor/128x128/apps/kuftp.png
/usr/share/icons/hicolor/16x16/apps/kuftp.png
/usr/share/icons/hicolor/22x22/apps/kuftp.png
/usr/share/icons/hicolor/32x32/apps/kuftp.png
/usr/share/icons/hicolor/48x48/apps/kuftp.png
/usr/share/icons/hicolor/64x64/apps/kuftp.png
/usr/share/locale/zh_CN/LC_MESSAGES/kuftp.mo
[gonzalo@inferna ~]$

Y si usted llegó hasta acá, completando exitosamente todos los pasos: Felicitaciones mi amigo, usted es ahora un RPM packager!!

5. rpm: empaquetando aplicaciones++

Bueno, llegado este punto, podemos asumir que usted ya conoce como es el procedimiento para crear un archivo *.spec, y como se hace para crear un archivo *.rpm apartir de él, asi que lo que vamos a hacer ahora es mejorar la escritura de nuestro archivo *.spec usando las herramientas que rpm pone a nuestra dispocición.

Como ya conocemos gran parte de ellas, vamos a acelerar un poco el paso y vamos a ver más código y menos charla ;)

5.1. afinando el lapiz

Nuestro primer ejemplo funciona, sí ... pero es muy mejorable y dista mucho de ser el ideal.

Veamos ahora como deberia quedar escrito nuestro archivo kuftp.spec, y luego pasemos a ver todo lo no vimos hasta ahora y algunas cosas más:

%define name            kuftp
%define version         0.8.0
%define release         %mkrel 2
%define summary         KuFtp is a graphical FTP client for the KDE
%define url             http://www.kde-apps.org/content/show.php/kuftp?content=58933

Name:           %{name}
Version:        %{version}
Release:        %{release}
Summary:        %{summary}
License:        GPL
Group:          Networking/File transfer
URL:            %{url}
Source:         %{name}-%{version}.tar.bz2
BuildRequires:  libkdecore4-devel >= 3.5.4
BuildRequires:  libqt3-devel >= 3.3.6
BuildRequires:  libopenssl0.9.8-devel
Buildroot:      %{_tmppath}/%{name}-%{version}

%description
KuFtp is a graphical FTP client for the K Desktop Environment. Most
notable features is Tab Sessions like Konqueror or Firefox, that is, you can have multiple
simultaneous FTP session in separate tabs.

#----------------------------------------------------------

%package        doc
Summary:        %{name} documentation
Group:          Documentation

%description    doc
%{name} documentation 

#----------------------------------------------------------

%prep

%setup -q

%build

%configure

%make

%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install

%clean
rm -rf %{buildroot}

#----------------------------------------------------------

%files
%defattr (-,root,root)
%{_bindir}/kuftp
%{_datadir}/applnk/Utilities/kuftp.desktop
%{_datadir}/apps/kuftp/kuftpui.rc
%{_datadir}/icons/hicolor/*/apps/%{name}.png
%{_datadir}/locale/zh_CN/LC_MESSAGES/kuftp.mo

#----------------------------------------------------------

%files doc
%defattr (-,root,root)
%doc AUTHORS ChangeLog COPYING INSTALL NEWS README TODO
%{_datadir}/doc/HTML/en/kuftp/*

#----------------------------------------------------------

%changelog
* Sun Jul 01 2007 Gonzalo Raul Nemmi <gnemmi@gmail.com>
- created kuftp-doc package
- cosmetic changes on spec file
* Sat Jun 30 2007 Gonzalo Raul Nemmi <gnemmi@gmail.com>
- first release

5.2. más directivas

5.2.1. %define

Como ya hemos visto, a lo largo de nuestro nuevo archivo kuftp.spec, hemos usado varias "macros" de las que se encuentran definidas ya sea en nuestro .rpmmacros o en /usr/lib/rpm/macros, pero también podemos crear nuestras propias macros dentro del archivo *.spec.

Crear nuestras propias macros dentro del archivo *.spec es muy simple. Para ello solo hará falta colocar la siguiente linea:

%define nombre_de_la_macro valor_que_le_asignamos

Asi, por ejemplo, podemos crear una macro para definir una sola vez la "Version" del software que estamos empaquetando, evitandonos de esa manera el tener que estar editando todo el *.spec cada vez que empaquetemos una nueva version del mismo programa.

Veamos:

%define name            kuftp
%define version         0.8.0
%define release         %mkrel 2
%define summary         KuFtp is a graphical FTP client for the KDE
%define url             http://www.kde-apps.org/content/show.php/kuftp?content=58933

Una vez definida la macro, la podemos usar tantas veces como sea necesario. Para usarla, solo necesitamos encerrar su nombre entre %{ }. Veamos la sintaxis de uso:

Name:           %{name}
Version:        %{version}
Release:        %{release}
Summary:        %{summary}
Version:        %{version}
...
URL:            %{url}
Source:         %{name}-%{version}.tar.bz2
...

De esta manera, cada vez que tengamos que actualizar nuestro *.rpm con una nueva version del software que estamos empaquetando, solo hará falta cambiar los valores de los 3 ó 4 %define que, previsoramente, colocamos al principio del .*spec en lugar de tener que bucear por todo el *.spec actualizando tags perdidos entre montones de líneas.

Lo mismo podemos hacer con un comando si quisieramos, aunque la sintaxis varia levemente. Para crear una macro que se expanda como el resultado de la ejecución de un comando, necesitamos encerrar el comando entre %( ) como en el siguiente ejemplo:

%define hoy %(date)

5.2.2. %configure

Siendo que es normal (y altamente aconsejable) que todo software que forma parte de una distro se configure usando un conjunto estandar de parámetros con valores predeterminados según la arquitectura y plataforma de la que se trate, no sería buena idea crear una macro %configure que se encargue de esto?

Sí, lo es.

Y es por ello que tenemos a nuestra disposición la macro %configure.

rpm la interpretará (en Mandriva Linux) como si se le hubiera pasado el siguiente conjunto de instrucciones:

[gonzalo@inferna ~]$ rpm --eval '%configure'

  CONFIGURE_TOP="${CONFIGURE_TOP:-.}";
  CFLAGS="${CFLAGS:--O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fomit-frame-pointer \
  -march=i586 -mtune=pentiumpro -fasynchronous-unwind-tables}" ; \
  export CFLAGS ;
  CXXFLAGS="${CXXFLAGS:--O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \
  -fomit-frame-pointer -march=i586 -mtune=pentiumpro -fasynchronous-unwind-tables}" ;\
  export CXXFLAGS ;
  FFLAGS="${FFLAGS:--O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fomit-frame-pointer \
  -march=i586 -mtune=pentiumpro -fasynchronous-unwind-tables}" ; \
  export FFLAGS ;
  cputoolize -c $CONFIGURE_TOP ;
  (cd $CONFIGURE_TOP; [ -f configure.in -o -f configure.ac ] && libtoolize --copy --force) ;
  [ -f $CONFIGURE_TOP/configure.in -o -f $CONFIGURE_TOP/configure.ac ] &&
  CONFIGURE_XPATH="--x-includes=/usr/include --x-libraries=/usr/lib"
  $CONFIGURE_TOP/configure i586-mandriva-linux-gnu \
        --program-prefix= \
        --prefix=/usr \
        --exec-prefix=/usr \
        --bindir=/usr/bin \
        --sbindir=/usr/sbin \
        --sysconfdir=/etc \
        --datadir=/usr/share \
        --includedir=/usr/include \
        --libdir=/usr/lib \
        --libexecdir=/usr/lib \
        --localstatedir=/var/lib \
        --sharedstatedir=/usr/com \
        --mandir=/usr/share/man \
        --infodir=/usr/share/info \
    $CONFIGURE_XPATH
[gonzalo@inferna ~]$ 

Desde ya, demás esta decir que estas son opciones de configuración "estandar", y que si usted necesita pasar más opciones, o sobreescribir alguna de ellas, no hay nada que le impida hacerlo.

Para el caso en que usted necesite pasarle algún argumento más a ./configure, solo necesitara agregarselo a la macro de la siguiente manera:

%configure \
        --otroparametro=valor

Tenga en cuenta que esta macro es, en principio, de uso opcional aunque en algunas distribuciones sea de uso obligatorio. Así que si usted quiere, puede no usarla y pasar el comando ./configure como mejor le paresca, tal y como hicimos en nuestro primer ejemplo.

5.2.3. %make

Al igual que %configure, la macro %make garantiza que todo el software se compilara con el siguiente comando:

make -j ${NRPROC:-1}

Todo lo que fue dicho en relación a la macro %configure, es aplicable a este caso también.

5.2.4. %makeinstall

Similar a la macro %configure pero con make como comando objeto:

[gonzalo@inferna ~]$ rpm --eval '%makeinstall'

  make \
        prefix=/usr \
        exec_prefix=/usr \
        bindir=/usr/bin \
        sbindir=/usr/sbin \
        sysconfdir=/etc \
        datadir=/usr/share \
        includedir=/usr/include \
        libdir=/usr/lib \
        libexecdir=/usr/lib \
        localstatedir=/var/lib \
        sharedstatedir=/usr/com \
        mandir=/usr/share/man \
        infodir=/usr/share/info \
  install
[gonzalo@inferna ~]$ 

5.2.5. %pre, %preun, %post y %postun

Estas directivas sirven para ejecutar ciertas operaciones en momentos muy determinados.

Veamos:

%pre
Ejecuta acciones antes de instalar un paquete

%preun
Ejecuta acciones antes de desinstalar un paquete

%post
Ejecuta acciones luego de instalar un paquete

%postun
Ejecuta acciones luego de desinstalar un paquete

Así por ejemplo, si estuvieramos instalando una libreria, deberiamos agregar a nuestro *.spec las siguientes líneas:

# ejecuta ldconfig agregando la libreria luego de instalar el paquete
%post
/sbin/ldconfig -n %{_libdir}

# ejecuta ldconfig quitando la libreria luego de deinstalar el paquete
%postun
/sbin/ldconfig -n %{_libdir}

Y si en lugar de una libreria, estuvieramos instalando un servidor o un deamon?

Bueno, ahi se complica un poco más, ya que deberiamos saber si es la primera vez que instalamos el server/deamon (install) o si estamos haciendo una actualización (update), o si lo estamos desinstalando por completo de nuestro sistema (erase).

Para verificar cual de estas condiciones es cierta, rpm lleva una cuenta sobre la operación que realizamos con un paquete y guarda un valor dentro de la variable $1. Así que para saber de que caso se trata, solo tendremos que verificar cual es el valor almacenado en $1.

Los valores posibles son:

instalando por primera vez: 1

Actualización:              2 ( o mayor a 2)

Desinstalación definitiva:  0

De esta manera, es simple saber que es lo que se esta haciendo con el paquete, y en consecuencia podemos preveer todos los escenarios posibles y decidir que hacer en cada uno.

Supongamos ahora que vamos a instalar un servidor, que además, tiene su propia libreria, la cual estamos instalando en conjunto con él:

%post
/sbin/ldconfig -n %{_libdir}
# first install, so add service to chkconfig, keeping it enabled (on)
if [ "$1" = "1" ]; then
        if [ -x /sbin/chkconfig ]; then
                chkconfig --add hplip ; \
                chkconfig hplip on ; \
                service hplip start ; \
                service cups condrestart ; \
        fi
        
fi


%preun
# this is an uninstall, so, lets stop the server and delete it with chkconfig
if [ "$1" = "0" ]; then
        if [ -x /sbin/chkconfig ]; then
                service hplip stop ; \
                chkconfig --del hplip ; \
                service cups condrestart ; \
        fi
fi


%postun
/sbin/ldconfig -n %{_libdir}
# we are updating, so, lets restart everything we need
if [ "$1" -ge "1" ]; then
        if [ -x /sbin/chkconfig ]; then
                service hplip condrestart ; \
                service cups condrestart ; \
        fi
fi

NOTA: sea extremadamente cauteloso con lo que hace con estas directivas, ya que las mismas serán ejecutadas como root cuando usted o cualquier persona instale el paquete en su sistema. Un simple descuido en el uso de estas directivas puede resultar en un sistema inutilizable

y por cierto .. si .. ya se que eso se puede escribir mejor usando el operador && (Y LÓGICO) de Bash en lugar de un nested if, pero en el ejemplo lo que importa es la claridad en cuanto al procedimiento, y no la eficiencia del código =P

5.2.6. %package

La directiva %package se utiliza para indicarle a rpm que debe crear un sub-paquete a partir del paquete original.

Esto es, en lugar de empaquetar todos los archivos en un solo paquete *.rpm, podemos hacer que rpm divida los archivos en dos o más paquetes usando como prefijo el nombre del paquete original.

Más adelante (creando sub-paquetes) vamos a ver su uso en detalle.

5.2.7. macros para la directiva %files

Como habrá podido apreciar en nuestro nuevo kuftp.spec, ya no usamos las rutas canonicas hacia los archivos que vamos a empaquetar, sino que reemplazamos parte de ellas por macros preestablecidas en el archivo /usr/lib/rpm/macros

En nuestro kuftp.spec, pasamos de:

/usr/bin/kuftp
/usr/share/applnk/Utilities/kuftp.desktop
/usr/share/apps/kuftp/kuftpui.rc
...

a:

%{_bindir}/kuftp
%{_datadir}/applnk/Utilities/kuftp.desktop
%{_datadir}/apps/kuftp/kuftpui.rc

Aquí tenemos la lista completa de las macros disponibles para los directorios del sistema:

%_prefix                /usr
%_exec_prefix           %{_prefix}
%_bindir                %{_exec_prefix}/bin
%_sbindir               %{_exec_prefix}/sbin
%_libexecdir            %{_exec_prefix}/libexec
%_datadir               %{_prefix}/share
%_sysconfdir            %{_prefix}/etc
%_sharedstatedir        %{_prefix}/com
%_localstatedir         %{_prefix}/var
%_lib                   lib
%_libdir                %{_exec_prefix}/%{_lib}
%_includedir            %{_prefix}/include
%_oldincludedir         /usr/include
%_infodir               %{_prefix}/info
%_mandir                %{_prefix}/man

Acostumbrese a ellas, ya que si bien su uso no es obligatorio, deben usarse siempre y así las verá en todos los archivos *.spec que lea.

5.3. creando sub-paquetes

Crear un sub-paquete es algo simple, y para hacerlo, solo hace falta usar la directiva %package como hicimos en nuestro nuevo kuftp.spec.

Veamos:

%package        doc
Summary:        %{name} documentation
Group:          Documentation

%description    doc
%{name} documentation 

De esta manera, le estamos diciendo a rpm, que deberá crear un sub-paquete llamado kuftp-doc.

Notese que hemos sobreescrito los tags Summary:, Group: y que le hemos dado una nueva %description a nuestro sub-paquete. Lo mismo deberemos hacer con el resto de los tags que fuera necesario cambiar, ya que de otra manera, rpm usará por defecto los tags definidos en el paquete original.

Resta ahora indicarle a rpm cual será la lista de los archivos que contendrá este nuevo paquete, y esto lo hacemos de la siguiente manera:

%files doc
%defattr (-,root,root)
%doc AUTHORS ChangeLog COPYING INSTALL NEWS README TODO
%{_datadir}/doc/HTML/en/kuftp/*

Como resultado de esto, y luego de crear nuestro *.rpm de la misma manera que hicimos antes (con el comando rpmbuild -ba misrpm/SPECS/kuftp.spec), obtendremos lo siguiente:

[gonzalo@inferna ~]$ ls misrpm/RPMS/i586
kuftp-0.8.0-2mdv2007.0.i586.rpm  kuftp-doc-0.8.0-2mdv2007.0.i586.rpm
[gonzalo@inferna ~]$

La directiva %package, agregará el prefijo kuftp- automaticamente al nombre de nuestro nuevo sub-paquete doc salvo que espesificamente le indiquemos que no lo haga.

Veamos como quedo la info del sub-paquete:

[gonzalo@inferna ~]$ rpm -qpi misrpm/RPMS/i586/kuftp-doc-0.8.0-2mdv2007.0.i586.rpm
Name        : kuftp-doc                    Relocations: (not relocatable)
Version     : 0.8.0                             Vendor: Mandriva
Release     : 2mdv2007.0                    Build Date: dom 01 jul 2007 21:52:50 ART
Install Date: (not installed)               Build Host: inferna.com.ar
Group       : Documentation                 Source RPM: kuftp-0.8.0-2mdv2007.0.src.rpm
Size        : 50623                            License: GPL
Signature   : (none)
Packager    : Gonzalo Raul Nemmi <gnemmi@gmail.com>
URL         : http://www.kde-apps.org/content/show.php/kuftp?content=58933
Summary     : kuftp documentation
Description :
kuftp documentation
[gonzalo@inferna ~]$

y que archivos contiene ...

[gonzalo@inferna ~]$ rpm -qpl misrpm/RPMS/i586/kuftp-doc-0.8.0-2mdv2007.0.i586.rpm
/usr/share/doc/HTML/en/kuftp/common
/usr/share/doc/HTML/en/kuftp/index.cache.bz2
/usr/share/doc/HTML/en/kuftp/index.docbook
/usr/share/doc/kuftp-doc-0.8.0
/usr/share/doc/kuftp-doc-0.8.0/AUTHORS
/usr/share/doc/kuftp-doc-0.8.0/COPYING
/usr/share/doc/kuftp-doc-0.8.0/ChangeLog
/usr/share/doc/kuftp-doc-0.8.0/INSTALL
/usr/share/doc/kuftp-doc-0.8.0/NEWS
/usr/share/doc/kuftp-doc-0.8.0/README
/usr/share/doc/kuftp-doc-0.8.0/TODO
[gonzalo@inferna ~]$

Ahora, si quisieramos crear un sub-paquete con un nombre totalmente distinto al nombre del paquete original (sin agregar el nombre del paquete original como prefijo), solo haria falta pasarle a %package la opción -n (name):

%package -n     documentacion
Summary:        %{name} documentation
Group:          Documentation

%description -n  documentacion
%{name} documentation 

De esta manera, habremos creado un sub-paquete documentacion.rpm cuyo nombre no tiene relación alguna con el nombre del paquete original.

5.4. ahora todo junto

Veamos ahora como queda todo junto, y no corra que no es para tanto ...

El ejemplo corresponde a mi archivo hplip.spec para Conectiva Linux 10.

Es complejo, pero es útil para ver como implementamos todo lo que vimos en este documento (y algunas cositas mas que le dejo al lector), en un solo *.spec.

%define hplip_name              hplip
%define hplip_ver               0.9.10
%define hplip_rel               16

%define hpijs_name              hpijs
%define hpijs_ver               2.1.9   

%define libhpip_major           0
%define libhpip_name            libhpip%{libhpip_major}

%define libsane_major           1
%define libsane_name            libsane-hpaio%{libsane_major}

Name:           %{hplip_name}
Version:        %{hplip_ver}
Release:        %{hplip_rel}
Summary:        The Hewlett-Packard Linux Imaging and Printing project (hplip) provides a
unified single and multi-function connectivity solution for Linux.
Summary(pt_BR): O projeto Hewlett-Packard Linux Imaging and Printing (hplip) oferece uma
solução unificada para conectividade single e multi-function no Linux.
Summary(es):    El proyecto Hewlett-Packard Linux Imaging and Printing (hplip) ofrece una
solución unificada para la conectividad single y multi-function en Linux.
Group:          Utilities
Group(pt_BR):   Utilitários
Group(es):      Utilitarios
License:        GNU, MIT, BSD
URL:            http://hpinkjet.sourceforge.net
Source:         http://hpinkjet.sourceforge.net/%{hplip_name}-%{hplip_ver}.tar.gz
#Patch1:                hplip-0.9.8-3.patch
PreReq: chkconfig
PreReq: initscripts
BuildRequires:  libucd-snmp-devel
BuildRequires:  net-snmp-devel
BuildRequires:  freetype2-devel
BuildRequires:  lcms-devel
BuildRequires:  libgcc
BuildRequires:  libjpeg-devel
BuildRequires:  libmng-devel
BuildRequires:  libpng-devel
BuildRequires:  libstdc++5.0-devel
BuildRequires:  libusb-devel
BuildRequires:  libz-devel
BuildRequires:  openssl-devel >= 0.9.7
BuildRequires:  qt3-devel >= 3.2.1
BuildRequires:  python-qt
BuildRequires:  xfree86-devel
Requires:       foomatic-filters
Requires:       ghostscript >= 7.05
Requires:       openssl0.9.7 >= 0.9.7c
Requires:       net-snmp >= 5.0.9
Requires:       %{hpijs_name} >= 2.1.7
Requires:       %{libsane_name}
Conflicts:      ghostscript < 7.05
Conflicts:      cups <= 1.1.14
Conflicts:      hplip <= 0.9.4
BuildRoot:      %{_tmppath}/%{hplip_name}-%{hplip_ver}-root

%description
The Hewlett-Packard Linux Imaging and Printing project (HPLIP) provides a unified single and
multi-function connectivity solution for Linux. The goal of this project is to provide
"radically simple" printing, faxing, scanning, photo-card access, and device management to
the consumer and small business desktop Linux users. This project is based open source
software and uses GPL compatible licenses.

http://hpinkjet.sourceforge.net/productssupported.php

%description -l pt_BR
O projeto Hewlett-Packard Linux Imaging and Printing (hplip) oferece uma solução unificada
para conectividade single e multi-function no Linux

http://hpinkjet.sourceforge.net/productssupported.php

%description -l es
El proyecto Hewlett-Packard Linux Imaging and Printing (hplip) ofrece una solución unificada
para la conectividad single y multi-function en Linux. EL objetivo de este proyecto es:
ofrecer un acceso "radicalmente simple" al manejo y administración de dispositivos de
impresión, fax, escaneo y fotografía para los usuarios finales y para las pequeñas empresas
que utilicen Linux en sus PCs de escritorio.
 
http://hpinkjet.sourceforge.net/productssupported.php

%files
%defattr(0755,root,root,0755)
%{_sysconfdir}/rc.d/init.d/hplip
%{_sbindir}/hpiod
%{_bindir}/hppgsz
%{_bindir}/hp-align
%{_bindir}/hp-check
%{_bindir}/hp-clean
%{_bindir}/hp-colorcal
%{_bindir}/hp-fab
%{_bindir}/hp-info
%{_bindir}/hp-levels
%{_bindir}/hp-makeuri
%{_bindir}/hp-photo
%{_bindir}/hp-print
%{_bindir}/hp-sendfax
%{_bindir}/hp-setup
%{_bindir}/hp-testpage
%{_bindir}/hp-toolbox
%{_bindir}/hp-unload
%dir %{_datadir}/hplip
%{_datadir}/hplip/*
%{_libdir}/cups/backend/hp
%{_libdir}/cups/backend/hpfax
%defattr(0644,root,root,0755)
%{_libdir}/kde3/share/applnk/Utilities/hplip.desktop
%{_libdir}/python*/site-packages/*
%dir %{_sysconfdir}/hp
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/hp/hplip.conf

#-----------------------------------------------------------

%package        doc
Summary:        %{name} documentation
Summary(pt_BR): Documentação de %{name}
Summary(es):    Documentación de %{name}
Group:          Documentation
Group(pt_BR):   Documentação
Group(es):      Documentación

%description    doc
%{name} documentation 

%description    doc -l pt_BR
Documentação do %{name}

%description    doc -l es
Documentación de %{name}

%files doc
%defattr(0644,root,root,0755)
%{_datadir}/doc/hplip-%{version}/*

#------------------------------------------------------------

%package        -n %{libhpip_name}
Summary:        Dynamic library needed by "%{name}" and/or "hpijs".
Summary(pt_BR): Libraria dinâmica necesaria para o "%{name}" e/ou o "hpijs".
Summary(es):    Libreria dinámica necesaria para "%{name}" y/o "hpijs".
Group:          Libraries
Group(pt_BR):   Bibliotecas
Group(es):      Bibliotecas
Requires:       net-snmp >= 5.0.9
Requires:       openssl0.9.7 >= 0.9.7c

%description    -n %{libhpip_name}
Dynamic library needed by "%{name}" and/or "hpijs".

%description    -n %{libhpip_name} -l pt_BR
Libraria dinâmica necesaria para o "%{name}" e/ou "hpijs".

%description    -n %{libhpip_name} -l es
Libreria dinámica necesaria para "%{name}" y/o "hpijs".

%files  -n libhpip0
%defattr(0644,root,root,0755)
%{_libdir}/libhp*.so.*

#------------------------------------------------------------

%package        -n libhpip-devel
Summary:        libhpip headers and development files.
Summary(pt_BR): Arquivos de cabeçalho e desenvolvimento do libhpip.
Summary (es):   Archivos de encabezado y desarrollo de libhpip.
Group:          Development
Group(pt_BR):   Desenvolvimento
Group(es):      Desarrollo
Requires:       %{libhpip_name} = %{version}-%{release}

%description    -n libhpip-devel
libhpip headers and development files.

%description    -n libhpip-devel -l pt_BR
Arquivos de cabeçalho e desenvolvimento do libhpip.

%description    -n libhpip-devel -l es
Archivos de encabezado y desarrollo de libhpip.

%files  -n libhpip-devel
%defattr(0644,root,root,0755)
%{_libdir}/libhp*.so
%{_libdir}/libhp*.la

#------------------------------------------------------------

%package        -n libhpip-devel-static
Summary:        Static libraries for libhpip.
Summary(pt_BR): Bibliotecas estáticas para desenvolvimento com o libhpip.
Summary (es):   Bibliotecas estáticas para desarrollo con libhpip.
Group:          Development
Group(pt_BR):   Desenvolvimento
Group(es):      Desarrollo
Requires:       libhpip-devel = %{version}-%{release}

%description -n libhpip-devel-static
This package contains static libraries for libhpip.

%description -n libhpip-devel-static -l pt_BR
Bibliotecas estáticas para desarrollo con libhpip.

%description -n libhpip-devel-static -l es
Bibliotecas estáticas para desarrollo con libhpip.

%files -n libhpip-devel-static
%defattr(0644,root,root,0755)
%{_libdir}/libhp*.a

#------------------------------------------------------------

%package        -n %{libsane_name}
Summary:        Dynamic library needed for SANE support in "%{name}".
Summary(pt_BR): Libraria dinâmica necesaria para ter suporte ao SANE no %{name}.
Summary (es):   Libreria dinámica necesaria para tener que %{name} tenga soporte para SANE.
Group:          Libraries
Group(pt_BR):   Bibliotecas
Group(es):      Bibliotecas
Requires:       %{libhpip_name}

%description    -n %{libsane_name}
Dynamic library needed for SANE support in "%{name}".

%description    -n %{libsane_name} -l pt_BR
Libraria dinâmica necesaria para ter suporte ao SANE no %{name}.

%description    -n %{libsane_name} -l es
Libreria dinámica necesaria para tener que %{name} tenga soporte para SANE.

%files          -n %{libsane_name}
%defattr(0644,root,root,0755)
%{_libdir}/sane/libsane-hp*.so.*

#------------------------------------------------------------

%package        -n libsane-hpaio-devel
Summary:        libsane-hpaio headers and development files.
Summary(pt_BR): Arquivos de cabeçalho e desenvolvimento do libsane-hpaio.
Summary (es):   Archivos de encabezado y desarrollo de libsane-hpaio.
Group:          Development
Group(pt_BR):   Desenvolvimento
Group(es):      Desarrollo
Requires:       %{libsane_name} = %{version}-%{release}

%description    -n libsane-hpaio-devel
libhpip headers and development files.

%description    -n libsane-hpaio-devel -l pt_BR
Arquivos de cabeçalho e desenvolvimento do libhpip.

%description    -n libsane-hpaio-devel -l es
Archivos de encabezado y desarrollo de libhpip.

%files          -n libsane-hpaio-devel
%defattr(0644,root,root,0755)
%{_libdir}/libsane-hp*.so
%{_libdir}/libsane-hp*.la

#------------------------------------------------------------

%package        -n libsane-hpaio-devel-static
Summary:        Static libraries for libsane-hpaio.
Summary(pt_BR): Bibliotecas estáticas para desenvolvimento com o libsane-hpaio.
Summary (es):   Bibliotecas estáticas para desarrollo con libsane-hpaio.
Group:          Development
Group(pt_BR):   Desenvolvimento
Group(es):      Desarrollo
Requires:       libsane-hpaio-devel = %{version}-%{release}

%description    -n libsane-hpaio-devel-static
This package contains static libraries for libsane-hpaio.

%description    -n libsane-hpaio-devel-static -l pt_BR
Bibliotecas estáticas para desarrollo con libsane-hpaio.

%description    -n libsane-hpaio-devel-static -l es
Bibliotecas estáticas para desarrollo con libsane-hpaio.

%files -n libsane-hpaio-devel-static
%defattr(0644,root,root,0755)
%{_libdir}/libsane-hp*.a

#-----------------------------------------------------------

%package        -n hpijs
Version:        %{hpijs_ver}
Summary:        HP drivers for inkjet printers
Summary(pt_BR): Drivers da HP para impressoras jato de tinta
Summary(es):    Drivers de HP para impresoras de chorro de tinta
Group:          Text
Group(es):      Texto
Group(pt_BR):   Texto
License:        BSD
URL:            http://hpinkjet.sourceforge.net/
Requires:       foomatic-filters
Requires:       ghostscript >= 7.05
Requires:       %{libhpip_name} >= %{hplip_ver}
Conflicts:      ghostscript < 7.05
BuildRequires:  libgcc
BuildRequires:  libstdc++5.0-devel

%description    -n hpijs
This package contains the HP drivers for about all the printers made by HP in the last years.
To see a complete list, please go to:

http://hpinkjet.sourceforge.net/productssupported.php

%description    -n hpijs -l pt_BR
Este pacote contém os drivers da HP para praticamente todas as impressoras da HP frabricadas
nos últimos anos. Para ver a lista completa, por favor vá para o site:

http://hpinkjet.sourceforge.net/productssupported.php

%description    -n hpijs -l es
Este paquete contiene los drivers de HP para practicamente todas las impresoras fabricadas
por HP en los últimos años. Para ver una lista completa, por favor dirijase a:

http://hpinkjet.sourceforge.net/productssupported.php

%files  -n hpijs
%defattr(0644,root,root,0755)
%attr(0755,root,root) %{_bindir}/hpijs

#-------------------------------------------------------------

%package        -n hpijs-doc
Version:        %{hpijs_ver}
Summary:        hpijs documentation
Summary(pt_BR): Documentação de hpijs
Summary(es):    Documentación de hpijs
Group:          Documentation
Group(pt_BR):   Documentação
Group(es):      Documentación

%description    -n hpijs-doc
hpijs documentation 

%description    -n hpijs-doc -l pt_BR
Documentação do hpijs

%description    -n hpijs-doc -l es
Documentación de hpijs

%files  -n hpijs-doc
%defattr(0644,root,root,0755)
%{_datadir}/doc/hpijs-*/*

#------------------------------------------------------------

%package        -n hpijs-ppd
Version:        %{hpijs_ver}
Summary:        ppd files for hpijs package
Summary(pt_BR): Arquivos .ppd para o pacote hpijs
Summary(es):    Archivos .ppd para el paquete hpijs
Group:          Text
Group(es):      Texto
Group(pt_BR):   Texto
Requires:       hpijs >= %{hpijs_ver}

%description    -n hpijs-ppd
This package has the .ppd files from the hpijs package. This is a legacy package and should
not be installed on new installations.
All that is here also is at foomatic-db-hpijs package, which should be used
instead.

%description    -n hpijs-ppd -l pt_BR
Este pacote contém os arquivos .ppd origináris do pacote hpijs. Este é um pacote para
compatilidade caso você não queria atualizar a sua configuração e não deve ser instalado em
instalações novas.
Todos os drivers aqui inclusos também estão disponíveis no pacote foomatic-db-hpijs, o qual
deve ser utilizado.

%description    -n hpijs-ppd -l es
Este paquete contiene los archivos .ppd de paquete hpijs. Este es un paquete que solo
satisface requisitos de compatibilidad para el caso en que usted no quiera actualizar su
configuración y no debe ser instalado en instalaciones nuevas.
Todos los driver que se encuentran incluidos en este paquete, también están disponibles en el
paquete foomatic-db-hpijs, que es el que debería ser utilizado.

%files  -n hpijs-ppd
%defattr(0644,root,root,0755)
%{_datadir}/ppd/HP/*
%{_datadir}/cups/model/foomatic-ppds

#------------------------------------------------------------

%prep

%setup -q

#%patch1 -p1

%build
./configure \
        --prefix=%{_prefix} \
        --sysconfdir=%{_sysconfdir} \
        --enable-static
        
make -j ${NRPROC:-1}

%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}

# the foomatic-rip script is also provided (the same one) by the
# foomatic-filters package. If we include it here, we'll have a conflict,
# so we remove it here and do a require on footmatic-filters.
rm -f %{buildroot}%{_bindir}/foomatic-rip
rm -rf %{buildroot}%{_libdir}/cups/filter/foomatic-rip

# we move the start-up scripts to the right place.
mkdir -p %{buildroot}%{_sysconfdir}/rc.d/init.d
mv %{buildroot}%{_sysconfdir}/init.d/hplip %{buildroot}%{_sysconfdir}/rc.d/init.d/hplip
rm -fr %{buildroot}%{_sysconfdir}/init.d

# the /etc/sane.d/dll.conf file is also provided by the sane package.
# If we include it here, we'll have a conflict, so we remove it here
# and let it be installed with the sane package if needed.
rm -fr %{buildroot}%{_sysconfdir}/sane.d/dll.conf

# we delete files that are available in the other packages (hplip-doc)
# or other places (/etc/rc.d/init.d/hplip, /etc/hp/hplip.conf)
rm -f %{buildroot}%{_datadir}/hplip/hplip
rm -f %{buildroot}%{_datadir}/hplip/hplip.conf
rm -f %{buildroot}%{_datadir}/hplip/hplip_overview.png
rm -f %{buildroot}%{_datadir}/hplip/hplip_readme.html
rm -f %{buildroot}%{_datadir}/hplip/COPYING

# we deal with libsane-hpaio* >=(
rm -f %{buildroot}%{_libdir}/sane/*
rm -f %{buildroot}%{_libdir}/libsane-hpaio.so
rm -f %{buildroot}%{_libdir}/libsane-hpaio.so.1
mv %{buildroot}%{_libdir}/libsane-hpaio.so.1.0.0 %{buildroot}%{_libdir}/sane/ 
ln -s %{_libdir}/sane/libsane-hpaio.so.1.0.0 %{buildroot}%{_libdir}/sane/libsane-hpaio.so.1 
ln -s %{_libdir}/sane/libsane-hpaio.so.1.0.0 %{buildroot}%{_libdir}/libsane-hpaio.so

# we have to create a kde menu entry in here
mkdir -p %{buildroot}%{_libdir}/kde3/share/applnk/Utilities
cat > %{buildroot}%{_libdir}/kde3/share/applnk/Utilities/hplip.desktop <<EOF
[Desktop Entry]
Version=0.6
Type=Application
Name=HP Device Manager
GenericName=HP Device Manager
Comment=View device status, ink levels and perform maintenance.
Encoding=UTF-8
Exec=%{_datadir}/hplip/toolbox
Icon=%{_datadir}/hplip/data/images/HPmenu.png
Terminal=false
Name[en]=HP Device Manager
Name[en_US]=HP Device Manager
Name[en_UK]=HP Device Manager
Name[es]=HP Device Manager
Name[pt]=HP Device Manager
Name[pt_BR]=HP Device Manager
Categories=Application;Utility;
X-KDE-StartupNotify=false
StartupNotify=false
EOF


%post
/sbin/ldconfig -n %{_libdir}
# first install, so add service to chkconfig, keeping it enabled (on)
if [ "$1" = "1" ]; then
        if [ -x /sbin/chkconfig ]; then
                chkconfig --add hplip ; \
                chkconfig hplip on ; \
                service hplip start ; \
                service cups condrestart ; \
        fi
        
fi


%preun
if [ "$1" = "0" ]; then
        if [ -x /sbin/chkconfig ]; then
                service hplip stop ; \
                chkconfig --del hplip ; \
                service cups condrestart ; \
        fi
fi


%postun
/sbin/ldconfig -n %{_libdir}

if [ "$1" -ge "1" ]; then
        if [ -x /sbin/chkconfig ]; then
                service hplip condrestart ; \
                service cups condrestart ; \
        fi
fi

%post -n %{libhpip_name}
/sbin/ldconfig -n %{_libdir}

%postun -n %{libhpip_name}
/sbin/ldconfig -n %{_libdir}


%post -n %{libsane_name}
/sbin/ldconfig -n %{_libdir}

if [ -f %{_sysconfdir}/sane.d/dll.conf ]; then
                if ! grep ^hpaio %{_sysconfdir}/sane.d/dll.conf >/dev/null 2>/dev/null ; then
                        echo hpaio >> %{_sysconfdir}/sane.d/dll.conf ; \
                        echo "Note: the hpaio backend has been added to /etc/sane.d/dll.conf" ; \
                fi
fi

%preun -n %{libsane_name}
if grep ^hpaio %{_sysconfdir}/sane.d/dll.conf >/dev/null 2>/dev/null ; then
                sed '/hpaio/d' %{_sysconfdir}/sane.d/dll.conf > /tmp/$$; \
                cp -f /tmp/$$ %{_sysconfdir}/sane.d/dll.conf; \
                rm -f /tmp/$$; \
                echo "Note: the hpaio backend has been removed from /etc/sane.d/dll.conf" ; \
fi

%postun -n %{libsane_name}
/sbin/ldconfig -n %{_libdir}

%clean
rm -rf %{buildroot}

%changelog
* Mon Mar 27 2006 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.10

* Thu Mar 09 2006 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.9

* Tue Feb 07 2006 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- apllied hplip-0.9.8-3.patch

* Thu Feb 02 2006 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.8
- apllied hplip-0.9.8-1.patch
- apllied hplip-0.9.8-2.patch

* Sat Nov 26 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- separated libhip from hplip-devel to satisfy a new hpijs dependency
- crated libhpip0\libhpip* packages
- crated libsane-hpaio1\libsane-hpaio* packages
- added some defines

* Thu Nov 22 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.7
- removed manually created %%{buildroot}%%{_bindir} (has been fixed in the Makefile)

* Wed Oct 12 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- manually create %%{buildroot}%%{_bindir}
- new upstream version: 0.9.6
- removed hplip-0.9.5-3.patch, no longer necesary

* Fri Sep 23 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- apllied hplip-0.9.5-3.patch

* Fri Sep 17 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.5
- added Conflitcs <= 0.9.4 in order to have a clean update
- now post, preun and postun work ok when updating

* Wed Jul 27 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- Changed service hplip start to service hplip condrestart

* Thu Jul 21 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.4

* Mon Jun 06 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- added add/remove hpaio backend to the sane.d/dll.conf file (Thanks goes to Till Kampeter and his Mandriva hplip.spec)

* Wed May 25 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- added a wilcard to %%{_libdir}/python* in order to keep compatibility with different python versions (MRL's advice!)

* Thu May 19 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- deleted -p flag from post/postun. Credit goes to Marcelo Ricardo Leitner =)

* Wed May 18 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.3
- deleted /etc/sane.d/dll.conf file since its originally provided by the sane package
- deleted unnecesary files on /usr/share/hplip (they are available on other packages or other places)
- Since make install DESTDIR=path works ok now, I'm using --sysconfdir=path instead of manually creating/moving .conf files

* Tue May 10 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- manually move libsane-hpaio* to /usr/lib/sane/
- added post service hplip start XD
- added preun service hplip stop =D

* Mon May 9 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- manually created /usr/lib/sane/
- added post and postun: service cups condrestart
- changed post /sbin/chkconfig hplip from *off* to *on* 
- all that according to what I talked to Marcelo Ricardo Leitner via e-mail, credit goes where credit is due =)

* Wed May 4 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- cosmetic changes
- created doc packages
- getting ready to public release on next upstream version

* Thu May 3 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.2

* Fri Apr 1 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9.1

* Wed Mar 30 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- new upstream version: 0.9

* Sun Feb 13 2005 Gonzalo Raúl Nemmi <caleb@linuxdicas.com.br>
- first release (after shamelessly stealing an awful lot of lines from Marcelo Ricardo Leitner's hpijs and hpoj .spec files !).

Copyright: Este manual se distribuye bajo licencia Reconocimiento-NoComercial-CompartirIgual 2.5 España


Última modificación: Tue Jul 03 2007 07:58
Valid CSS!

Mastodon