Después de ver de un modo general como funciona OBS intentaremos
mostrar ahora el caso práctico de creación de RPMs para varias
distribuciones.
Imaginemos que nuestra aplicación consta de un
archivo binario y de un .desktop, es un caso sencillo ya que no contamos
con archivos de traducción. Lo que tenemos que montar es un archivo de
descripción .spec y un .tar.gz de nuestro código fuente.
Entorno de trabajo:
Si
trabajamos con Subversion, o cualquier otro sistema de control de
versiones, haremos un "commit" de todo nuestro proyecto antes de
comenzar con la paquetización. Después de esto exportaremos una copia
limpia de archivos ocultos a un directorio de trabajo diferente. Sobre
esta nueva carpeta ya podremos crear nuestro tar.gz.
Tal como vimos en el
capítulo anterior
en nuestra cuenta en OBS habremos creado un proyecto, las
distribuciones para las que se construirá y el paquete correspondiente a
la versión sobre la que estamos trabajando. Una vez hecho todo esto,
para añadir nuestro código fuente navegamos hasta el paquete creado y
seleccionamos la pestaña Sources, donde clicaremos sobre el botón Add
files.
Se
nos despliegará un formulario en el que podemos cargar, en este caso,
nuestro código. Lo más cómodo es haber nombrado el tar.gz de la mejor
manera posible, especificando la versión, y ahorrarnos el rellenar el
campo nombre, de manera que OBS lo haga automáticamente. Más adelante
podremos subir el .spec del mismo modo.
El archivo spec
Ahora
toca montar el archivo spec con la información adecuada. Tenéis, a
continuación, todo el archivo apropiado para el proyecto de ejemplo.
Después desgranaremos lo más importante a destacar:
%if 0%{?fedora_version}
%define breq qt4-devel
%define reqs qt qt-x11
%define qmake /usr/bin/qmake-qt4
%endif
%if 0%{?mandriva_version}
%define breq libqt4-devel qt4-linguist
%define reqs libqtcore4 libqtgui4
%define qmake /usr/lib/qt4/bin/qmake
%endif
%if 0%{?suse_version}
%define breq libqt4-devel
%define reqs libqt4 libqt4-x11
%define qmake /usr/bin/qmake
%endif
Name: RegExpTester
Summary: RegExpTester is an application that lets you test regular expresions
Version: 1.0
Release: 1
License: GPL v3
Group: Productivity/Utility/TextTools
BuildRoot: %{_tmppath}/build-root-%{name}
Source0: /usr/src/packages/SOURCES/RegExpTester-1.0.tar.gz
Packager: Guillermo Amat
Url: https://www.deuteros.es
Vendor: Guillermo Amat
BuildRequires: gcc-c++, make, %{breq}
Requires: %{reqs} libc.so.6 libgcc_s.so.1 libgcc_s.so.1(GCC_3.0) libm.so.6 libpthread.so.0 libstdc++.so.6 libstdc++.so.6(CXXABI_1.3) libstdc++.so.6(GLIBCXX_3.4)
%description
RegExpTester is an application that lets you test regular expresions
RegExpTester is an application that lets you test regular expresions
%prep
rm -rf %{buildroot}
mkdir %{buildroot}
%setup -q
%build
mkdir -p %{buildroot}%{_bindir}
mkdir -p %{buildroot}%{_datadir}/%{name}
mkdir -p %{buildroot}%{_datadir}/applications
%{qmake} %{name}.pro
CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" \
make
%install
cp %{name} %{buildroot}%{_bindir}
cp %{name}.png %{buildroot}%{_datadir}/%{name}/
cat > $RPM_BUILD_ROOT%{_datadir}/applications/%{name}.desktop << EOF
[Desktop Entry]
Encoding=UTF-8
Name=%{name}
GenericName=%{name}
GenericName[de]=%{name}
Comment=Synchronize files between computers
Exec=%{_bindir}/regexptester
Icon=%{_datadir}/%{name}/%{name}.png
Terminal=false
Type=Application
StartupNotify=false
Categories=Qt;KDE;Utility;TextEditor;
EOF
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root)
%dir %{_datadir}/RegExpTester
%{_datadir}/applications/RegExpTester.desktop
%{_bindir}/RegExpTester
%{_datadir}/%{name}/%{name}.png
%changelog
Menudo rollo ¿no? Pues vamos a destriparlo paso a paso para que se entienda mejor:
El
primer bloque se corresponde con una serie de declaraciones
condicionales que dependerán de la maquina virtual en la que OBS ejecute
la construcción del rpm.
%if 0%{?fedora_version}
%define breq qt4-devel
%define reqs qt qt-x11
%define qmake /usr/bin/qmake-qt4
%endif
%if 0%{?mandriva_version}
%define breq libqt4-devel qt4-linguist
%define reqs libqtcore4 libqtgui4
%define qmake /usr/lib/qt4/bin/qmake
%endif
%if 0%{?suse_version}
%define breq libqt4-devel
%define reqs libqt4 libqt4-x11
%define qmake /usr/bin/qmake
%endif
Por ejemplo, en los requisitos de construcción (breq) para Mandriva y
Opensuse se necesitará el paquete libqt4-devel, mientras que el
equivalente en Fedora recibe el nombre qt4-devel. OBS instalara el
paquete adecuado en cada máquina virtual gracias a eso. En todo caso
para cada una de las distribuciones definimos tres variables que
usaremos mas tarde:
- breq: requisitos para la construcción
- reqs: dependencias para la ejecución de nuestro programa en el PC del usuario que se lo instale
- qmake: ruta al ejecutable qmake
El siguiente bloque que nos encontramos es el de la información general de
nuestra aplicación. Aquí y en todo el fichero spec hay que tener
cuidado con los saltos de línea y en concreto aquí con no equivocarse
con el valor del campo source0. Además, parte de esta información será
mostrada al usuario en el gestor de paquetes de su distribución:
Name: RegExpTester
Summary: RegExpTester is an application that lets you test regular expresions
Version: 1.0
Release: 1
License: GPL v3
Group: Productivity/Utility/TextTools
BuildRoot: %{_tmppath}/build-root-%{name}
Source0: /usr/src/packages/SOURCES/RegExpTester-1.0.tar.gz
Packager: Guillermo Amat
Url: https://www.deuteros.es
Vendor: Guillermo Amat
BuildRequires: gcc-c++, make, %{breq}
Requires: %{reqs} libc.so.6 libgcc_s.so.1 libgcc_s.so.1(GCC_3.0) libm.so.6 libpthread.so.0 libstdc++.so.6 libstdc++.so.6(CXXABI_1.3) libstdc++.so.6(GLIBCXX_3.4)
%description
RegExpTester is an application that lets you test regular expresions
RegExpTester is an application that lets you test regular expresions
En el bloque anterior también se aprecia la aparición de las
variables que hemos definido con anterioridad. Su valor se concatena al
de los nombres de los paquetes que aparecen definidos. Más claro:
BuildRequires contiene gcc-c++ y make porque se llaman así en todas las
distribuciones (menos mal) y el contenido de la variable breq que cambia
en función de la máquina virtual.
En description tenemos una
descripción corta y otra que puede ser más extensa. La linea en blanco
que separa a ambas es necesaria.
Vamos con el siguiente trozo.
Esto ya tiene que ver con la construcción del paquete y en el aparecen
nuevas variables. La diferencia es que estas no son nuestras, sino
predefinidas por el sistema:
- buildroot: el directorio donde se construirá el paquete en la MV
- _bindir: el directorio de los ejecutables
- _datadir: directorio de datos
- name: es el nombre que aparece en el campo Name (linea 17 del .spec)
Así
pues lo que se hace en este bloque es preparar todos los directorios
necesarios. Después se ejecuta qmake sobre el archivo .pro cosa que
creará el Makefile en la MV. La siguiente linea contiene opciones de
compilación específicas para la creación de rpms que, a su vez, son
usadas por el comando make.
Después de ejecutar make se procede
con la sección install que, en este caso, copia un par de archivos en
sus lugares correspondientes.
%prep
rm -rf %{buildroot}
mkdir %{buildroot}
%setup -q
%build
mkdir -p %{buildroot}%{_bindir}
mkdir -p %{buildroot}%{_datadir}/%{name}
mkdir -p %{buildroot}%{_datadir}/applications
%{qmake} %{name}.pro
CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" \
make
%install
cp %{name} %{buildroot}%{_bindir}
cp %{name}.png %{buildroot}%{_datadir}/%{name}/
En el siguiente bloque se crea el archivo .desktop que hará que
nuestro programa aparezca en el menú de inicio de KDE. No es necesario
crearlo así, podríamos haberlo escrito en un editor, empaquetado en el
tar.gz y por último tratarlo en el .spec de la misma forma que al png.
En todo caso, se debe saber que durante la construcción se comprobará
este archivo y que es muy importante que el contenido de Categories siga
las definiciones del
estándar de freedesktop.org
cat > $RPM_BUILD_ROOT%{_datadir}/applications/%{name}.desktop << EOF
[Desktop Entry]
Encoding=UTF-8
Name=%{name}
GenericName=%{name}
GenericName[de]=%{name}
Comment=Synchronize files between computers
Exec=%{_bindir}/regexptester
Icon=%{_datadir}/%{name}/%{name}.png
Terminal=false
Type=Application
StartupNotify=false
Categories=Qt;KDE;Utility;TextEditor;
EOF
Y para acabar se define el paso de limpieza y se enumeran los archivos
generados para la creación del paquete. Cualquier inconsistencia entre
esta lista y lo que se encuentre realmente generará un error, por
ejemplo: si nuestro tar.gz contiene un segundo png que no hayamos
nombrado aquí.
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root)
%dir %{_datadir}/RegExpTester
%{_datadir}/applications/RegExpTester.desktop
%{_bindir}/RegExpTester
%{_datadir}/%{name}/%{name}.png
%changelog
El archivo tar.gz
Como se ha dicho antes, lo mejor
es generar el tar.gz desde una copia limpia de nuestro código fuente. Si
trabajamos con Subversion haremos un "svn export" y después
comprimiremos el resultado.
A parte de eso, habrá que llevar
cuidado con incluir todo lo necesario y especificar correctamente las
rutas de todo lo que aparezca en el .spec
El resultado
Si
todo va bien en nuestro panel de resumen del paquete tendremos indicado
que el proceso ha finalizado con éxito y podremos navegar hasta el
repositorio de descarga de cada una de las distribuciones.
Si por ejemplo pulsamos sobre
openSuse_11_3 llegaremos a la página donde tenemos todos sus binarios disponibles:
Si
algo falla, desde la pantalla de resumen veremos que se nos indica un
error (failed en vez de success) y haciendo clic sobre la palabra failed
accederemos al log de la máquina virtual donde veremos el error.
Una imagen vale más que mil palabras
Y un par de enalces y de archivos de ejemplo también, así que allá va: