Apéndice A. Técnicas avanzadas

# Apéndice A. Técnicas avanzadas

The rewrite of this tutorial document with updated contents and more practical examples is available as Guide for Debian Maintainers. Please use this new tutorial as the primary tutorial document.

Here are some hints and pointers for advanced packaging topics that you are most likely to deal with. You are strongly advised to read all the references suggested here.

Puede ser necesario editar manualmente los ficheros de las plantillas generadas con la orden dh_make para abordar los temas tratados en este capítulo. La nueva orden debmake maneja mejor estos aspectos de la construcción de paquetes.

## A.1. Bibliotecas compartidas

Antes de empaquetar bibliotecas compartidas, debes leer atentamente la siguientes referencias básicas:

- Debian Policy Manual, 8 "Shared libraries"

- Debian Policy Manual, 9.1.1 "File System Structure"

- Debian Policy Manual, 10.2 "Libraries"

Éstos son algunos consejos básicos para empezar:

- Las bibliotecas compartidas son archivos objeto en formato ELF que contienen código compilado.

- Las bibliotecas compartidas se distribuyen como ficheros `*.so` (no como ficheros `*.a` o `*.la`).

- Las bibliotecas compartidas se utilizan principalmente para compartir código común entre varios ejecutables con la orden ld.

- Las bibliotecas compartidas se utilizan, a veces, para proveer varios complementos («plugins») a un ejecutable mediante el procedimiento dlopen.

- Shared libraries export symbols, which represent compiled objects such as variables, functions, and classes; and enable access to them from the linked executables.

- El SONAME (el nombre lógico) de la biblioteca compartida `lib`nombre_biblioteca`.so`.`1`: `objdump -p lib`nombre_biblioteca`.so.`1` | grep SONAME` [87]

- El «SONAME» (el nombre lógico) de una biblioteca compartida generalmente coincide con el nombre del archivo de biblioteca (pero no siempre).

- El «SONAME» (el nombre lógico) de las bibliotecas compartidas enlazadas a ``/usr/bin/foo``: `objdump -p `/usr/bin/foo` | grep NEEDED` [88]

- `lib`foo``1``: el paquete de biblioteca de la biblioteca compartida `lib`foo`.so.`1`` con la versión ABI del nombre lógico («SONAME») `1`.[89]

- Los guiones de desarrollador de un paquete de biblioteca deben ejecutar ldconfig cuando sea necesario para generar los enlaces simbólicos para el «SONAME» (el nombre lógico).[90]

- `lib`foo``1`-dbg`: the debugging symbols package that contains the debugging symbols for the shared library package `lib`foo``1``.

- `lib`foo`-dev`: the development package that contains the header files etc. for the shared library `lib`foo`.so.`1``.[91]

- Debian packages should not contain `*.la` Libtool archive files in general.[92]

- Debian packages should not use RPATH in general.[93]

- Aunque está un poco anticuado y es sólo una referencia secundaria, Debian Library Packaging Guide aún puede ser útil.

## A.2. Gestionando `debian/`package`.symbols`

When you package a shared library, you should create a `debian/`package`.symbols` file to manage the minimal version associated with each symbol for backward-compatible ABI changes under the same SONAME of the library for the same shared library package name.[94] You should read the following primary references in detail:

- Debian Policy Manual, 8.6.3 "The symbols system"[95]

- dh_makeshlibs(1)

- dpkg-gensymbols(1)

- dpkg-shlibdeps(1)

- deb-symbols(5)

Here is a rough example of how to create the `libfoo1` package from the upstream version `1.3` with the proper `debian/libfoo1.symbols` file:

- Preparar el esqueleto de directorios fuente Debian utilizando el fichero con las fuentes `libfoo-1.3.tar.gz`.

  - Si es la primera versión del paquete `libfoo1`, genera un fichero `debian/libfoo1.symbols` en blanco.

  - Si la versión anterior del autor (la `1.2`) fue empaquetada en el paquete `libfoo1` con el fichero `debian/libfoo1.symbols` adecuado en el paquete fuente, utilízalo otra vez.

  - If the previous upstream version `1.2` was not packaged with `debian/libfoo1.symbols`, create it as the `symbols` file from all available binary packages of the same shared library package name containing the same SONAME of the library, for example, versions `1.1-1` and `1.2-1`. [96]

        $ dpkg-deb -x libfoo1_1.1-1.deb libfoo1_1.1-1
        $ dpkg-deb -x libfoo1_1.2-1.deb libfoo1_1.2-1
        $ : > symbols
        $ dpkg-gensymbols -v1.1 -plibfoo1 -Plibfoo1_1.1-1 -Osymbols
        $ dpkg-gensymbols -v1.2 -plibfoo1 -Plibfoo1_1.2-1 -Osymbols

- Make trial builds of the source tree with tools such as debuild and pdebuild. (If this fails due to missing symbols etc., there were some backward-incompatible ABI changes that require you to bump the shared library package name to something like `libfoo1a` and you should start over again.)

      $ cd libfoo-1.3
      $ debuild
      ...
      dpkg-gensymbols: advertencia: hay símbolos nuevos en el fichero de símbolos: ...
       mire las diferencias a continuación
      --- debian/libfoo1.symbols (libfoo1_1.3-1_amd64)
      +++ dpkg-gensymbolsFE5gzx        2012-11-11 02:24:53.609667389 +0900
      @@ -127,6 +127,7 @@
        foo_get_name@Base 1.1
        foo_get_longname@Base 1.2
        foo_get_type@Base 1.1
      + foo_get_longtype@Base 1.3-1
        foo_get_symbol@Base 1.1
        foo_get_rank@Base 1.1
        foo_new@Base 1.1
      ...

- If you see the diff printed by the dpkg-gensymbols as above, extract the proper updated `symbols` file from the generated binary package of the shared library. [97]

      $ cd ..
      $ dpkg-deb -R  libfoo1_1.3_amd64.deb libfoo1-tmp
      $ sed -e 's/1\.3-1/1\.3/' libfoo1-tmp/DEBIAN/symbols \
              >libfoo-1.3/debian/libfoo1.symbols

- Compilar paquetes para publicarlos con herramientas como debuild y pdebuild.

      $ cd libfoo-1.3
      $ debuild -- clean
      $ debuild
      ...

Además de los ejemplos anteriores, también debes comprobar la compatibilidad ABI con más atención y actualizar manualmente las versiones de los símbolos (si es necesario). [98]

Aunque es sólo una referencia secundaria, Debian wiki UsingSymbolsFiles y sus enlaces a otras páginas web puede ser útil.

## A.3. Varias arquitecturas

La función de varias arquitecturas introducida en Debian «wheezy» integra la instalación en más de una arquitectura de los paquetes binarios (en particular `i386`<->`amd64`, pero también con otras combinaciones) en `dpkg` y `apt`. Se recomienda leer atentamente las siguientes referencias:

- Ubuntu wiki MultiarchSpec (desarrollador original)

- Debian wiki Multiarch/Implementation (Debian)

Se utilizan tripletes del tipo `i386-linux-gnu` y `x86_64-linux-gnu` para el directorio de instalación de bibliotecas compartidas. El triplete de trabajo se establece dinámicamente al valor `$(DEB_HOST_MULTIARCH)` por dpkg-architecture(1) para cada compilación. Por ejemplo, el directorio de instalación de bibliotecas para varias arquitecturas se cambia como sigue:[99]

Directorio antiguo | directorio multi-arquitectura i386 | directorio multi-arquitectura amd64
--- | --- | ---
`/lib/` | `/lib/i386-linux-gnu/` | `/lib/x86_64-linux-gnu/`
`/usr/lib/` | `/usr/lib/i386-linux-gnu/` | `/usr/lib/x86_64-linux-gnu/`

Here are some typical multiarch package split scenario examples for the following:

- el código fuente de la biblioteca `lib`foo`-1.tar.gz`

- el código fuente de una orden ``bar`-1.tar.gz` escrito en un lenguaje compilado

- el código fuente de una orden ``baz`-1.tar.gz` escrito en un lenguaje interpretado

Paquete | Arquitectura: | Multi-arquitectura: | Contenido del paquete
--- | --- | --- | ---
`lib`foo``1`` | any | same | la biblioteca compartida, coinstalable
`lib`foo``1`-dbg` | any | same | los símbolos de depuración de la biblioteca compartida, coinstalable
`lib`foo`-dev` | any | same | los ficheros de cabeceras y otros de una biblioteca compartida, coinstalable
`lib`foo`-tools` | any | foreign | los programas de soporte en tiempo de ejecución no son co-instalables.
`lib`foo`-doc` | all | foreign | los ficheros de documentación de la biblioteca compartida
``bar`` | any | foreign | los ficheros compilados del programa, no son coinstalables
``bar`-doc` | all | foreign | los ficheros de documentación del programa
``baz`` | all | foreign | los ficheros de programa interpretados

Hay que tener en cuenta que el paquete de desarrollo debe contener un enlace simbólico a la biblioteca compartida asociada sin el número de versión. P. ej.: `/usr/lib/x86_64-linux-gnu/libfoo.so` -> `libfoo.so.1`

## A.4. Construcción de un paquete de biblioteca compartida

You can build a Debian library package enabling multiarch support using dh(1) as follows:

- Actualizar `debian/control`.

  - Add `Build-Depends: debhelper (>=10)` for the source package section.

  - Añadir `Pre-Depends: ${misc:Pre-Depends}` por cada paquete binario de biblioteca compartida.

  - Añadir el campo `Multi-Arch:` en cada sección de paquete binario.

- Set `debian/compat` to "10".

- Cambiar el directorio habitual `/usr/lib/` por el directorio multi-arquitectura `/usr/lib/$(DEB_HOST_MULTIARCH)/` para todos los guiones de empaquetado.

  - Call `DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)` in `debian/rules` to set the `DEB_HOST_MULTIARCH` variable first.

  - Reemplazar `/usr/lib/` por `/usr/lib/$(DEB_HOST_MULTIARCH)/` en `debian/rules`.

  - If `./configure` is used in part of the `override_dh_auto_configure` target in `debian/rules`, make sure to replace it with `dh_auto_configure --` . [100]

  - Cambiar todas referencias a `/usr/lib/` por `/usr/lib/*/` en los ficheros `debian/`nombre_del_paquete`.install`

  - Generate files like `debian/`foo`.links` from `debian/`foo`.links.in` dynamically by adding a script to the `override_dh_auto_configure` target in `debian/rules`.

        override_dh_auto_configure:
                dh_auto_configure
                sed 's/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/g' \
                        debian/nombre_del_paquete.links.in > debian/nombre_del_paquete.links

Debes comprobar que el paquete de biblioteca compartida solo contiene los ficheros esperados y que el paquete «-dev» sigue funcionando correctamente.

All files installed simultaneously as the multiarch package to the same file path should have exactly the same file content. You must be careful of differences generated by the data byte order and by the compression algorithm.

## A.5. Paquete nativo Debian

Si un paquete se mantiene exclusivamente para Debian o para uso local, su paquete fuente puede contener todos los ficheros `debian/*`. Hay dos maneras para empaquetarlos.

You can make the upstream tarball by excluding the `debian/*` files and package it as a non-native Debian package as in Sección 2.1, “Plan de trabajo para la construcción de paquetes Debian”. This is the normal way, which some people encourage using.

La alternativa es el esquema de trabajo para paquetes nativos Debian.

- Generaremos un paquete fuente Debian en el formato `3.0 (native)`, utilizando un archivo comprimido en formato «tar» que incluirá todos los archivos.

  - ``nombre_del_paquete`_`versión`.tar.gz`
  - ``nombre_del_paquete`_`versión`.dsc`

- Construiremos un paquete binario Debian del paquete de fuentes nativo Debian.

  - ``nombre_del_paquete`_`versión`_`arquitectura`.deb`

For example, if you have source files in `~/mypackage-1.0` without the `debian/*` files, you can create a native Debian package by issuing the dh_make command as follows:

    $ cd ~/mi_paquete-1.0
    $ dh_make --native

Then the `debian` directory and its contents are created just like in Sección 2.8, “Paquete no nativo Debian inicial”. This does not create a tarball, since this is a native Debian package. But that is the only difference. The rest of the packaging activities are practically the same.

Después de la ejecución de la orden dpkg-buildpackage, encontrarás los siguientes ficheros en el directorio superior:

- `mi_paquete_1.0.tar.gz`

  Este es el archivo del código fuente generado a partir del directorio `mi_paquete-1.0` por la orden dpkg-source (su sufijo no es `orig.tar.gz`.).

- `mi_paquete_1.0.dsc`

  This is a summary of the contents of the source code, as in the non-native Debian package. (There is no Debian revision.)

- `mi_paquete_1.0_i386.deb`

  This is your completed binary package, as in the non-native Debian package. (There is no Debian revision.)

- `mi_paquete_1.0_i386.changes`

  Este archivo describe todos los cambios realizados en el versión actual del paquete en el caso de los paquetes Debian no nativos (no tiene código de revisión Debian).

[87] Como alternativa: `readelf -d lib`nombre_biblioteca`.so.`1` | grep SONAME`

[88] Como alternativa: `readelf -d lib`foo`.so.`1` | grep NEEDED`

[89] Véase Debian Policy Manual, 8.1 "Run-time shared libraries".

[90] Véase Debian Policy Manual, 8.1.1 "ldconfig".

[91] Consulta Debian Policy Manual, 8.3 "Static libraries" y Debian Policy Manual, 8.4 "Development files".

[92] Consulta Debian wiki ReleaseGoals/LAFileRemoval.

[93] Consulta Debian wiki RpathIssue.

[94] Los cambios ABI incompatibles con versiones anteriores, normalmente requieren actualizar el «SONAME» (el nombre lógico) de la biblioteca y el de la biblioteca compartida a otros nuevos.

[95] Para bibliotecas C++ y otros casos en los que el seguimiento individual de símbolos es difícil, es mejor consultar Debian Policy Manual, 8.6.4 "The shlibs system".

[96] Las versiones previas de los paquetes Debian están disponibles en http://snapshot.debian.org/. La revisión Debian del paquete sigue a la versión para facilitar mantenimiento de versiones anteriores («backport») del paquete: `1.1` << `1.1-1~bpo70+1` << `1.1-1` y `1.2` << `1.2-1~bpo70+1` << `1.2-1`

[97] La revisión de Debian se deriva de la versión para hacer más fácil el mantenimiento de versiones anteriores («backport») del paquete: `1.3` << `1.3-1~bpo70+1` << `1.3-1`

[98] Véase Debian Policy Manual, 8.6.2 "Shared library ABI changes".

[99] Old special purpose library paths such as `/lib32/` and `/lib64/` are not used anymore.

[100] Como alternativa, puedes añadir los argumentos `--libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)` y `--libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)` en `./configure`. Fíjate que `--libexecdir` especifica el directorio predeterminado para la instalación de programas ejecutables que son ejecutados por otros programas en lugar de por los usuarios. El valor predeterminado por «Autotools» es `/usr/libexec/` pero en Debian es `/usr/lib/`.

Capítulo 9. Enviar el paquete |  |