Seleccione su idioma

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:

{codecitation style="brush: Bash/shell;"}

%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

{/codecitation}

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.

{codecitation style="brush: Bash/shell;"}

%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 

{/codecitation}

 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:

{codecitation style="brush: Bash/shell;"}


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

  {/codecitation}

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.

{codecitation}

%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}/

{/codecitation}

 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

{codecitation}


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

{/codecitation}

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í.

{codecitation}

%clean
rm -rf %{buildroot}

%files  
%defattr(-,root,root)  
%dir %{_datadir}/RegExpTester   
%{_datadir}/applications/RegExpTester.desktop  
%{_bindir}/RegExpTester
%{_datadir}/%{name}/%{name}.png

%changelog

{/codecitation}

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: