Usando equivs para crear links faltantes

2018/07/12

El parche presentado en este post fué aceptado en el código fuente de equivs.

Mi agradecimiento a Axel Beckert por el tiempo dedicado.


Descripción del problema

Utilizando pdfsam 2.2.4 en Ubuntu 14.04 (i386) se notó que ocurre un problema en la generación de thumbnails durante la edición de los pdf’s.

Revisando el log se obtiene:

12:12:08,656 ERROR Unable to generate thumbnail java.lang.UnsatisfiedLinkError: Unable to load library ‘freetype’: libfreetype.so: no se puede abrir el archivo del objeto compartido: No existe el archivo o el directorio

El problema anterior se soluciona creando un link simbólico:

$ sudo ln -s /usr/lib/i386-linux-gnu/libfreetype.so.6.11.1 /usr/lib/i386-linux-gnu/libfreetype.so

El problema que la solución anterior nos generaría es un problema si se quiere instalar el paquete libfreetype6-dev:

$ dpkg -S /usr/lib/i386-linux-gnu/libfreetype.so
libfreetype6-dev: /usr/lib/i386-linux-gnu/libfreetype.so

Alternativas de solución

Como solución se podría:

  1. Instalar el paquete libfreetype6-dev, con el problema de estar agregando dependencias no deseadas solo por un link simbólico.

  2. Crear un paquete dummy utilizando equivs que genere el link anterior y tenga un conflicto con el paquete libfreetype6-dev, para que pueda desinstalarse sin problemas si por algún motivo se quiere instalar libfreetype6-dev.

Se elige la segunda opción.

Se crea un paquete utilizando equivs; particularmente se utiliza el campo Links, en el archivo de control para equivs como se indica en la página del manual y está ejemplificado en /usr/share/doc/equivs/examples/libstdc++6-dev.ctl. A continuación se muestra el contenido del archivo pdfsam-fix-freetype:

Section: text
Priority: extra
Homepage: https://pdfsam.org/
Standards-Version: 3.9.2

Package: pdfsam-fix-freetype
Version: 1.0
Maintainer: Juan Picca <jumapico@gmail.com>
Depends: pdfsam (>= 2.0), libfreetype6
Conflicts: libfreetype6-dev
Architecture: i386
Description: Fix for pdfsam (>= 2.0)
 Fix errors in thumbnail generation due usage of `libfreetype.so`.
Links: /usr/lib/i386-linux-gnu/libfreetype.so.6 /usr/lib/i386-linux-gnu/libfreetype.so

Notar que esta opción Links no está disponible en la versión 2.0.9 provista por Ubuntu 14.04, pero si para la versión 2.10 provista por debian buster, por lo que el paquete se generará en debian buster.

Problema 1 - defaults de dpkg-deb

Luego de construir el paquete mediante

$ equivs-build --arch i386 pdfsam-fix-freetype

e intentar instalarlo en Ubuntu 14.04 se obtiene el siguiente error:

$ sudo dpkg -i pdfsam-fix-freetype_1.0_i386.deb
dpkg-deb: error: archive 'pdfsam-fix-freetype_1.0_i386.deb' has premature member 'control.tar.xz' before 'control.tar.gz', giving up
dpkg: error al procesar el archivo pdfsam-fix-freetype_1.0_i386.deb (--install):
 el subproceso dpkg-deb --control devolvió el código de salida de error 2
Se encontraron errores al procesar:
 pdfsam-fix-freetype_1.0_i386.deb

Esto se debe a que cambiaron las opciones por defecto del paquete dpkg-deb desde la versión utilizada en Ubuntu 14.04 a la utilizada en debian buster, y la compresión por defecto es xz en lugar de gzip. Por otro lado, la versión de dpkg de Ubuntu 14.04 no maneja correctamente el archivo de control comprimidos mediante xz, por lo que no se puede instalar dicho paquete.

Problema 2 - creación de fuentes con equivs

Ya que no se puede utilizar directamente el paquete generado por equivs-build, se intentará generar un paquete fuente, para luego editarlo y corregir los parámetros utilizados con dpkg-deb:

$ equivs-build --source --arch i386 pdfsam-fix-freetype
dpkg-buildpackage: info: source package pdfsam-fix-freetype
dpkg-buildpackage: info: source version 1.0
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: source changed by Juan Picca <jumapico@gmail.com>
 dpkg-source --before-build equivs.qTTGhv
 fakeroot debian/rules clean
dh_testdir
dh_clean
 dpkg-source -b equivs.qTTGhv
dpkg-source: error: can't build with source format '3.0 (quilt)': no upstream tarball found at ../pdfsam-fix-freetype_1.0.orig.tar.{bz2,gz,lzma,xz}
dpkg-buildpackage: error: dpkg-source -b equivs.qTTGhv subprocess returned exit status 255
Error in the build process: exit status 255

Se crea un archivo pdfsam-fix-freetype_1.0.orig.tar.gz vacío como es pedido por dpkg-source y se vuelve a intentar:

$ tar zcf pdfsam-fix-freetype_1.0.orig.tar.gz -T /dev/null
$ equivs-build --source --arch i386 pdfsam-fix-freetype
dpkg-buildpackage: info: source package pdfsam-fix-freetype
dpkg-buildpackage: info: source version 1.0
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: source changed by Juan Picca <jumapico@gmail.com>
 dpkg-source --before-build equivs.sJw8KU
 fakeroot debian/rules clean
dh_testdir
dh_clean
 dpkg-source -b equivs.sJw8KU
dpkg-source: error: can't build with source format '3.0 (quilt)': non-native package version does not contain a revision
dpkg-buildpackage: error: dpkg-source -b equivs.sJw8KU subprocess returned exit status 255
Error in the build process: exit status 255

Se modifica la versión en en archivo pdfsam-fix-freetype agregandole un número de revisión a la versión y volviendo a intentar crear el paquete:

$ sed -i 's/Version: 1.0/Version: 1.0-1/' pdfsam-fix-freetype
$ equivs-build --source --arch i386 pdfsam-fix-freetype
dpkg-buildpackage: info: source package pdfsam-fix-freetype
dpkg-buildpackage: info: source version 1.0-1
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: source changed by Juan Picca <jumapico@gmail.com>
 dpkg-source --before-build equivs.PkGbQl
 fakeroot debian/rules clean
dh_testdir
dh_clean
 dpkg-source -b equivs.PkGbQl
dpkg-source: info: using source format '3.0 (quilt)'
dpkg-source: info: building pdfsam-fix-freetype using existing ./pdfsam-fix-freetype_1.0.orig.tar.gz
dpkg-source: error: cannot represent change to install/0/libfreetype.so:
dpkg-source: error:   new version is symlink to /usr/lib/i386-linux-gnu/libfreetype.so.6
dpkg-source: error:   old version is nonexistent
dpkg-source: error: unrepresentable changes to source
dpkg-buildpackage: error: dpkg-source -b equivs.PkGbQl subprocess returned exit status 2
Error in the build process: exit status 2

Debido a los errores anteriores se descarta la idea de generar un paquete source para luego editar.

Solución final

Inspeccionando el código fuente de equivs-build, se encuentra que los templates a utilizar están hardcodeados en el código:

system("cp -R /usr/share/equivs/template/* \"$builddir\"") == 0 or
  die "Error on copy of the template files: exit status " . ($?>>8) . "\n";

Para solucionar el problema se modificará el código de equivs-build para que acepte por parámetros un directorio de templates. Se copiará el template distribuido con equivs, modificandose el archivo debian/rules agregando el parámetro -- -Zgzip a la linea con dh_builddeb que es la que llama a dpkg-deb para construir el paquete:

$ mkdir ~/pdfsam-fix-freetype
$ cat > ~/pdfsam-fix-freetype/pdfsam-fix-freetype <<'END'
Section: text
Priority: extra
Homepage: https://pdfsam.org/
Standards-Version: 3.9.2

Package: pdfsam-fix-freetype
Version: 1.0
Maintainer: Juan Picca <jumapico@gmail.com>
Depends: pdfsam (>= 2.0), libfreetype6
Conflicts: libfreetype6-dev
Architecture: i386
Description: Fix for pdfsam (>= 2.0)
 Fix errors in thumbnail generation due usage of `libfreetype.so`.
Links: /usr/lib/i386-linux-gnu/libfreetype.so.6 /usr/lib/i386-linux-gnu/libfreetype.so
END
$ cp -a /usr/share/equivs/template ~/pdfsam-fix-freetype/
$ sed -i 's/dh_builddeb/dh_builddeb -- -Zgzip/' ~/pdfsam-fix-freetype/template/debian/rules
$ cd ~/pdfsam-fix-freetype
$ equivs-build --templates ~/pdfsam-fix-freetype/template --arch i386 pdfsam-fix-freetype

La modificación a equivs-build es la siguiente:

diff --git a/usr/bin/equivs-build b/usr/bin/equivs-build
index a95688a..6a5ac86 100755
--- a/usr/bin/equivs-build
+++ b/usr/bin/equivs-build
@@ -22,20 +22,23 @@ my %control;

 sub usage {
   print STDERR <<EOU;
-Usage: equivs-build [--full|-f] [--source|-s] [--arch=foo|-a=foo] controlfile
+Usage: equivs-build [--full|-f] [--source|-s] [--arch=foo|-a=foo] [--templates=bar|-t=bar] controlfile
 controlfile is the name of an equivs controlfile.
 You can use "equivs-control filename" to create one.

---full   Full build including signing, etc., suitable for upload to Debian
---source Source build including signing, etc., suitable for upload to a PPA
---arch   Build package for a different architecture.
-         Used e.g. for building Hurd packages under Linux.
+--full      Full build including signing, etc., suitable for upload to Debian
+--source    Source build including signing, etc., suitable for upload to a PPA
+--arch      Build package for a different architecture.
+            Used e.g. for building Hurd packages under Linux.
+--templates Build package using alternative templates in the given directory.
+            Use with caution, this can break equivs-build.
 EOU
   exit 1;
 }

-my ($full_package, $source_only, $arch);
-GetOptions('full|f' => \$full_package, 'source|s' => \$source_only, 'arch|a=s' => \$arch) or usage();
+my ($full_package, $source_only, $arch, $templatedir);
+$templatedir = "/usr/share/equivs/template";
+GetOptions('full|f' => \$full_package, 'source|s' => \$source_only, 'arch|a=s' => \$arch, 'templates|t=s' => \$templatedir) or usage();

 my $debug = 0;

@@ -47,7 +50,7 @@ if (! $controlfile) {
   usage();
 }

-system("cp -R /usr/share/equivs/template/* \"$builddir\"") == 0 or
+system("cp -R \"$templatedir\"/* \"$builddir\"") == 0 or
   die "Error on copy of the template files: exit status " . ($?>>8) . "\n";

 # Parse the equivs control file

El parche completo del pull request realizado al proyecto se puede encontrar aquí.