miércoles, 1 de abril de 2009

Creando un .rpm a partir de binarios

Esta entrada se sale un poco del contexto del blog (ya que aquí solemos tratar ubuntu), pero me parece correcto tratarla, ya que es un tema que puede que algún día os interese si cambiáis de distribución. Esta entrada es más una experiencia personal al realizar cierta tarea que un tutorial. Como no todo el mundo está familiarizado con rpm, haré antes una pequeña introducción.

¿Qué es rpm?

Rpm es una herramienta de administración de paquetes desarrollada por RedHat y usada en su sistema operativo. Actualmente se usa en muchas distribuciones como Fedora, Mandriva y OpenSuSE. Digamos que rpm es similar a dpkg (que es el que usan Ubuntu y Debian entre otras).

___________________________

La culpa de esta entrada la tiene el creador de VerTV, Alberto, que como muchos sabéis empaquetó este archivo en formato .deb. Como mi distro (Mandriva) no acepta archivos deb (ya que usa rpm, y de eso va este asunto), Alberto me lo convirtió a rpm muy amablemente con alien, una utilidad que permite pasar de deb a rpm y viceversa en segundos. El problema estaba en que, al convertirlo, las dependencias habían desaparecido. Entonces, se me ocurrió que podía hacer un paquete para las distribuciones que usaran rpm y que, además, reconociera esa dependencia. Lo que os estoy contando lo planeé el Lunes, y hoy, Miércoles, ya he terminado el paquete rpm y funciona a la perfección (o eso parece :P ).

La mayor complicación de todo esto ha sido que casi todos los documentos que explicaban el proceso suponían que disponías de un código fuente que podías compilar y que ya llevaba las instrucciones de instalación. Por lo tanto, ha sido una odisea (para mí), el conseguir que sin compilar código, llegase a hacer el rpm.

___________________________

Notas básicas sobre la creación de archivos rpm

  • Para crear archivos rpm se necesita el paquete rpm-devel, que contiene todas las herramientas necesarias para fabricar un rpm. Si el paquete que vamos a compilar necesitara dependencias adicionales, también tendríamos que instalarlas, pero como no es nuestro caso, nos lo ahorramos.
  • Para generar un archivo rpm necesitamos un archivo .spec, que es el que le dice al programa que lo creará qué es lo que tiene que hacer (rpmbuild).

____________________________

Nuestro caso particular: VerTV

Como hemos dicho en el apartado anterior, necesitaremos crear un archivo con extensión .spec en donde deberemos colocar toda la información requerida sobre el paquete que vamos a construir. Para ello, cogeremos un archivo .spec ya creado y lo editaremos según nuestras necesidades. Para editar todo esto es necesario saber para qué vale cada cosa, así que tenemos que ir comprobando qué secciones necesitamos y qué secciones no. Por ejemplo, todos los %define podemos borrarlos puesto que en nuestro caso no nos valdrán. Nuestro paquete es demasiado pequeño y no necesitamos definir variables. Una vez eliminemos las variables que no necesitamos, llegaremos a la zona de descripción del programa, que es ésta:

Name: kmymoney
Icon: kmymoney.xpm
Summary: The Personal Finances Manager for KDE.
Version: 0.8
Release: 1.%{disttag}%{distver}
License: GPL
Vendor: The KMyMoney development team
Packager: %packer
Group: Productivity/Office/Finance
Source0: %{name}2-%version.tar.bz2
BuildRoot: %{_tmppath}/%{name}2-%{version}-%{release}-build
BuildRequires: kdebase3-devel
Prereq: /sbin/ldconfig

Aquí podemos editar los apartados según nuestras necesidades (Name, Summary, Version, etc.) y borrar los que creamos innecesarios (Icon, BuildRoot, BuildRequires, etc.). Además, añadiremos unos propios (Requires, Provides y Obsoletes), quedándo finalmente así:

Name: vertv
Version: 1.0.1
Release: 0
URL: http://diariodeunlinux3ro.es/
Summary: Front-end para Sopcast
License: GPL
Group: Internet/Remote Access
Packager: Alejandro Sanchez
Vendor: Alberto Jimenez
Source: vertv-1.0.1.tar.bz2
Requires: zenity >= 2.20, totem >= 2.18, mplayer >= 0.99, vlc >= 0.8.0
Provides: %{name}, ld-linux.so.2(GLIBC_PRIVATE),libc.so.6(GLIBC_PRIVATE)
Obsoletes: %{name}

Aclaro lo más importante:

  • Requires. Aquí debemos poner las dependencias del paquete. Hay que poner el nombre del paquete y además indicar con símbolos qué versión es necesario tener.
  • Provides. Indicaremos qué nos aporta el paquete. %{name} se reemplazará por lo que hayamos puesto en Name más arriba. Además, he añadido esas dos entradas (ld-linux.so.2(GLIBC_PRIVATE) y libc.so.6(GLIBC_PRIVATE)) porque sin ellas no me dejaba crear el RPM. Pertenecen al paquete glibc, pero aunque éste esté instalado no los reconoce.
  • Source. He creado un paquete con el contenido de todo el programa (todos los archivos en el mismo directorio), lo he comprimido en formato .tar.bz2 y lo he puesto en /usr/src/rpm/SOURCES.

Una vez hecho esto, la primera parte del fichero .spec está completa. Ahora seguimos:

  • %description. Una descripción algo más larga del programa. Será la que se vea en el gestor de paquetes.
  • %prep, %setup, %build. Estos tres apartados están puestos para configurar cosas antes de la compilación y para hacer la compilación (%build). Como nosotros no vamos a compilar no los necesitamos.
  • %install. En este apartado pondremos las instrucciones correspondientes a la instalación del paquete. Hay que remarcar que es una instalación virtual. Es decir, aquí no debemos poner el directorio donde queremos que vaya, sino, conservando la misma estructura de directorios, referirla al directorio en el que se construye el paquete (%{buildroot}).
  • %clean. En esta sección debemos limpiar la zona en la cual hemos estado trasteando con el paquete. Con un simple %{__rm} -rf %{buildroot} bastará.
  • %post. Aquí podemos poner lo que queremos que se haga justo después de la instalación.
  • %files. La parte más importante. Aquí deben nombrarse los archivos que forman parte del paquete con respecto a un directorio raíz (que es %{buildroot}). O sea que, como antes los instalamos teniendo en cuenta que el directorio raíz era %{buildroot}, lo único que tenemos que hacer es poner su ubicación real, es decir, que todos los directorios empezarán con /.
  • %changelog. Nada importante. Simplemente sirve para llevar un control de lo que se va haciendo en el paquete.

Ahora os pongo como ha quedado la segunda parte del fichero vertv.spec:

%description
VerTV es un front-end realizado por Alberto Jimenez (http://diariodeunlinux3ro.es) mediante zenity gracias al cual podremos visualizar vídeos de Sopcast. El objetivo de este proyecto es construir una interfaz potente y bonita, aunque zenity no sea muy apropiado para ello. Sin embargo, zenity hace que sea muy intuitivo el manejo del programa.

Más información en: http://diariodeunlinux3ro.es

%install
mkdir %{buildroot}
mkdir %{buildroot}/usr
mkdir %{buildroot}/usr/bin
mkdir %{buildroot}/usr/bin/sp-auth
mkdir %{buildroot}/usr/share
mkdir %{buildroot}/usr/share/applications
mkdir %{buildroot}/usr/share/pixmaps
cp vertv.sh %{buildroot}/usr/bin/
cp sp-sc-auth %{buildroot}/usr/bin/sp-auth/
cp vertv.desktop %{buildroot}/usr/share/applications/
cp vertv.png %{buildroot}/usr/share/pixmaps/
cp postinst %{buildroot}/usr/bin/sp-auth/

%clean
%{__rm} -rf %{buildroot}

%post
sh /usr/bin/sp-auth/postinst
rm -f /usr/bin/sp-auth/postinst

%files
%defattr(-,root,root)
/usr/bin/vertv.sh
/usr/bin/sp-auth/sp-sc-auth
/usr/share/applications/vertv.desktop
/usr/share/pixmaps/vertv.png
/usr/bin/sp-auth/postinst

%changelog
* Wed Sep 17 2008 Alejandro Sanchez
- Primer fichero spec
- Conseguido que pregunte por la dependencia de Zenity
- Contiene lo mismo que el .deb creado por Alberto

Como podéis ver, aquí está hecho todo manualmente, pues son pocos archivos y es fácil instalarlos, pero en el caso de que llegaran a ser muchos, esta tarea sería realmente complicada. Como podéis ver, para que no compile, lo único que hay que hacer es eliminar las órdenes %setup y %build y listo. A partir de ahí, si uno no se lía con los directorios, esto es bastante fácil.

___________________________________

Preparando materiales y fabricando el rpm

A estas alturas lo que debemos tener es:

  1. El paquete de desarrollo rpm-devel, en el cual van todas las utilidades necesarias para fabricar paquetes rpm.
  2. Un archivo con la información necesaria para que rpmbuild pueda fabricar el rpm satisfactoriamente (vertv.spec)
  3. Un archivo con todos los componentes binarios del programa, perteneciendo todos al mismo directorio (no es necesario tener todos los archivos en el mismo directorio pero en el fichero vertv.spec aquí puesto está hecho así). El archivo debe llamarse tal y como diga en el apartado Source, en la primera parte del fichero spec (vertv-1.0.1.tar.bz2 en este caso) y estar obligatoriamente situado en /usr/src/rpm/SOURCES.

Si tenemos todo esto podemos pasar a fabricar el archivo rpm. Esto es lo más sencillo (si no nos da ningun error). Nos situamos en el directorio que esté el fichero spec (en un terminal) como superusuario y escribimos:

rpmbuild -bb vertv.spec

Tardará unos segundos y, si lo hemos hecho bien, podremos recoger nuestro rpm en /usr/src/rpm/RPMS/i586. La parte i586 puede variar dependiendo de vuestra arquitectura de sistema. De todas formas, podéis compilar para un tipo determinado de arquitectura usando la opción –target y diciéndole la arquitectura final que queréis. Como VerTV es independiente de la arquitectura del sistema le daremos la opción noarch, es decir, válido para todas las arquitecturas (noarch no tiene nada que ver con la distro archlinux :P ). Así que en un terminal escribimos:

rpmbuild -bb --target noarch vertv.spec

Y una vez termine, encontraremos nuestro rpm en el directorio /usr/src/rpm/RPMS/noarch.

__________________________

La verdad es que en estos tres días he aprendido mucho sobre cómo funciona rpm y cómo fabricar archivos rpm. Pero, también es verdad que he cogido cabreos monumentales con el tema de un error que no significaba nada para mí, y que al final era una cosa muy absurda. También me gustaría aclarar que he leído en algunos foros que lo que estaba intentando era imposible. Bien, a mí, imposible no me parece (teniendo en cuenta que el paquete funciona) pero jodido sí que es.

Por si os interesa, aquí os dejo el enlace de descarga al archivo vertv.spec (el necesario para generar el rpm) y el rpm de VerTV.

Espero que os sirva

Un saludo

No hay comentarios:

Publicar un comentario