Actualización del paquete a una nueva versión del programa

Cada cierto tiempo, deberemos de actualizar nuestro repositorio con los cambios realizados en el código. Para ello, disponemos de la orden svn-upgrade, a la que le pasaremos un fichero tar.gz con el nuevo código fuente del paquete.

Ahora probaremos a actualizar nuestro paquete con el código correspondiente a la última versión en el repositorio Subversion del equipo de ZSNES. Primero, prepararemos el tarball con el código original. Descargamos el código fuente, y lo exportamos a otro directorio, para retirar los ficheros usados por Subversion:

svn checkout https://svn.bountysource.com/zsnes/trunk zsnes-svn
svn export zsnes-svn zsnes-1.510.SVN5215

He decidido usar el esquema 1.510.SVN5215 para indicar que se trata de la revisión 5215 del repositorio. De esta forma, si sale una nueva versión oficial, o si empleo una revisión más reciente del repositorio Subversion, como 1.520 o 1.510.SVN5216, éstas serán considerada más recientes, y la actualización se podrá hacer de forma correcta. Podemos comprobar que es efectivamente así mediante la siguiente orden:

dpkg --compare-versions "1.510-0ubuntu1" gt "1.510.SVN5215-0ubuntu1" && \
  echo "1.510-0ubuntu1 mayor que 1.510.SVN5215-0ubuntu1" || \
  echo "1.510-0ubuntu1 menor que 1.510.SVN5215-0ubuntu1"

Ahora que ya tenemos el código, inspeccionaremos un momento para ver si todos los ficheros importantes se hallan en su sitio. Normalmente, no se suelen almacenar ficheros generados automáticamente en el repositorio, así que pueden que falten algunas cosas importantes. Mirando en src, vemos que falta el guión configure que necesitamos para compilar. Lo generaremos ejecutando las siguientes órdenes bajo src, el mismo directorio donde se halla su fichero fuente, configure.in:

aclocal
autoconf

También faltan los directorios docs/readme.txt y docs/readme.htm, que añadiremos en su sitio. Con esto tenemos los ficheros fuente listos. Vamos a crear el tarball que necesitamos:

/tmp$ tar -czf zsnes-1.510.SVN5215.tar.gz zsnes-1.510.SVN5215

El siguiente paso es añadir dicho código a nuestra área de trabajo, e indicar que vamos comenzar a empaquetar una nueva versión del programa. Volvemos al directorio con la versión actual de nuestro paquete y ejecutamos:

~/packages/zsnes/trunk$ svn-upgrade /tmp/zsnes-1.510.SVN5215.tar.gz

Se harán los cambios necesarios en debian/changelog y el resto del repositorio. Cambiaremos el número de versión del paquete a 0ubuntu1 y confirmamos dichos cambios antes de volver a reconstruir el paquete:

~/packages/zsnes/trunk$ svn commit -m \
  "Actualizado con rev 5215 upstream"
~/packages/zsnes/trunk$ svn-b

Sin embargo, la reconstrucción falla. Buscando entre los distintos mensajes, podemos ver una línea del estilo:

Trying patch 01-man-fhs.patch at level 1 ... 0 ... 2 ... failed.

En resumen: el parche que antes hicimos para corregir el problema de Makefile.in no se ha podido aplicar. Tras inspeccionar sus contenidos, vemos que efectivamente Makefile.in ha cambiado demasiado:

install:
	@INSTALL@ -d -m 0755 $(DESTDIR)/@bindir@
	@INSTALL@ -m 0755 @ZSNESEXE@ $(DESTDIR)/@bindir@
	@INSTALL@ -d -m 0755 $(DESTDIR)/@mandir@/man1
	@INSTALL@ -m 0644 linux/zsnes.1 $(DESTDIR)/@mandir@/man1

Vaya, parece que ellos mismos han corregido ya el problema que teníamos antes. Ésta es precisamente la razón por la que usamos un parche, en vez de cambiar directamente el código. Sólo tenemos que eliminar el parche, confirmar los cambios y reconstruir:

~/packages/zsnes/trunk$ svn rm debian/patches
D  debian/patches/01-man-fhs.patch
~/packages/zsnes/trunk$ svn commit -m \
  "01-man-fhs.patch: Retirado (corregido por upstream)"
Deleting       zsnes/trunk/debian/patches/01-man-fhs.patch
Transmitting file data .
Committed revision 11.
~/packages/zsnes/trunk$ svn-b

Esta vez ya no da el fallo del parche, pero indica que faltan las bibliotecas de desarrollo de Qt para la nueva interfaz. Añadiremos la dependencia en libqt4-dev al fichero control y volveremos a intentarlo tras confirmar otra vez nuestros cambios.

Esta vez falla diciendo que no puede construir el fichero ui_zsnes.h, que hace falta para compilar. Probaremos a compilar sobre el directorio /tmp/zsnes-1.510.SVN5215/src tras instalar las dependencias en nuestro propio sistema:

./configure
make

Da el mismo problema, así que no es culpa de nuestro paquete. Vamos a mirar con grep, a ver qué puede ser:

grep -R ui_zsnes.h *
makefile.ms:${GUI_D}/gui.cpp: ${GUI_D}/ui_zsnes.h
src/gui/gui.h:#include "ui_zsnes.h"
Makefile.in:GUI_QO=$(GUI_D)/moc_gui.cpp $(GUI_D)/ui_zsnes.h
Makefile:GUI_QO=$(GUI_D)/moc_gui.cpp $(GUI_D)/ui_zsnes.h
makefile.dep:gui/gui.o: gui/gui.cpp gui/gui.h ui_zsnes.h

Si nos fijamos, se puede ver que en makefile.dep la ruta no se corresponde con la de las anteriores entradas, por lo que seguramente ahí estará el fallo. Esta vez buscamos por este fichero:

grep -R makefile.dep *
src/configure:touch -t 198001010000 makefile.dep
src/Makefile.in:main: makefile.dep $(Z_QOBJS) $(Z_OBJS)
src/Makefile.in:include makefile.dep
src/Makefile.in:makefile.dep: $(TOOL_D)/depbuild Makefile
src/Makefile.in: $(TOOL_D)/depbuild @CC@ "@CFLAGS@" @NASMPATH@
"@NFLAGS@" $(Z_OBJS) > makefile.dep
src/Makefile.in: rm -f makefile.dep $(Z_OBJS) $(Z_QOBJS) $(PSR)
$(PSR_H) @ZSNESEXE@
src/Makefile:main: makefile.dep $(Z_QOBJS) $(Z_OBJS)
src/Makefile:include makefile.dep
src/Makefile:makefile.dep: $(TOOL_D)/depbuild Makefile
src/Makefile: $(TOOL_D)/depbuild gcc " -pipe -I. -I/usr/local/include
-I/usr/include -D__UNIXSDL__ -I/usr/include/SDL -D_GNU_SOURCE=1
-D_REENTRANT -D__OPENGL__ -DNO_DEBUGGER -DNDEBUG -march=athlon-xp -O2
-fomit-frame-pointer -s -DQT_SHARED -I/usr/include/qt4
-I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui " nasm "
-w-orphan-labels -D__UNIXSDL__ -f elf -DELF -D__OPENGL__ -DNO_DEBUGGER
-O1" $(Z_OBJS) > makefile.dep
src/Makefile: rm -f makefile.dep $(Z_OBJS) $(Z_QOBJS) $(PSR) $(PSR_H)
zsnes
src/autom4te.cache/output.0:touch -t 198001010000 makefile.dep
src/autom4te.cache/output.1:touch -t 198001010000 makefile.dep
src/configure.in:touch -t 198001010000 makefile.dep

Puede verse que en src/Makefile es donde se crea a través de una herramienta propia de los desarrolladores de ZSNES, que obtiene automáticamente las dependencias. Recordando la lista anterior de ficheros que mencionaban a ui_zsnes.h, se nos viene a la cabeza gui/gui.h. Vamos a probar a cambiar la ruta de inclusión a gui/ui_zsnes.h:

cd ~/packages/zsnes/trunk
svn-buildpackage --svn-export
cd ../build-area/zsnes-1.510.SVN5215
cdbs-edit-patch 02-fix-depbuild.patch

Hacemos el cambio antes mencionado con el editor vim y salimos del shell, tras lo cual reintentaremos la construcción del paquete:

vim src/gui/gui.h
exit

Ahora la reconstrucción ha tenido éxito. Ya sólo tendríamos que seguir los mismos pasos anteriores de verificación, validación manual, marcado en el repositorio (tras retirar el aviso “NOT RELEASED YET” añadido automáticamente a debian/changelog, claro), y envío. Cualquiera de nuestros usuarios será notificado eventualmente de la actualización y podrá instalar la versión más reciente del paquete.

Una última nota: si se quiere, se puede integrar la verificación y publicación en la función svn-b antes definida, cambiando las líneas correspondientes en ~/.bashrc por:

function svn-b () {
    buildarea="`pwd`/../build-area";
    rutapaquete="${buildarea}/\${package}_\${debian_version}*.deb";
    rutadsc="${buildarea}/\${package}_\${debian_version}*.dsc";
    rutarepo="/var/packages/ubuntu";
    sudo cowbuilder --update
    svn-buildpackage  \
        --svn-builder="pdebuild --auto-debsign --buildresult ${buildarea}" \
	--svn-postbuild="rm ${buildarea}/*_source.changes; \
                         lintian -i ${rutapaquete}; linda -i ${rutapaquete}; \
                         cd ${rutarepo} && \
                         sudo -E reprepro remove gutsy \${package} && \
                         sudo -E reprepro includedeb gutsy ${rutapaquete} && \
                         sudo -E reprepro -S main -P low includedsc gutsy ${rutadsc}";
}

function svn-tag () {
    svn-buildpackage --svn-only-tag
}