Apèndix A. Tècniques avançades

# Apèndix A. Tècniques avançades

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.

Pot ésser necessari editar manualment els fitxers de plantilla per a la construcció del paquet generats per l'ordre dh_make per seguir els detalls tractats en aquest capítol. La nova ordre debmake gestiona millor aquestes etapes de la construcció de paquets.

## A.1. Biblioteques compartides.

Abans de construir paquets de biblioteques compartides, has de llegir les següents referències bàsicques en detall:

- Debian Policy Manual, 8 "Shared libraries"

- Debian Policy Manual, 9.1.1 "File System Structure"

- Debian Policy Manual, 10.2 "Libraries"

Heus aquí alguns consells simplistes per a que pugis començar.

- Les biblioteques compartides son fitxers objecte en format ELF que contenen codi compilat.

- Les biblioteques compartides es distribueixen com a fitxers `*.so` (ni fitxers `*.a` ni `*.la`).

- Les biblioteques compartides s'utilitzen principalment per compartir codi comú entre diversos executables fent servir l'ordre ld.

- Les biblioteques compartides, a vegades es fan servir per proporcionar complements («plugins») a un executable mitjançant el procediment 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 nom lògic) de la biblioteca compartida `lib`nom_biblioteca`.so`.`1`: `objdump -p lib`nom_biblioteca`.so.`1` | grep SONAME` [87]

- El «SONAME» (nom lògic) d'una biblioteca compartida en general coincideix amb el nom del fitxer de la biblioteca (però no sempre).

- El «SONAME» (nom lògic) de les biblioteques compartides enllaçades a ``/usr/bin/foo``: `objdump -p `/usr/bin/foo` | grep NEEDED` [88]

- `lib`nom_biblioteca``1``: el paquet de biblioteca de la biblioteca compartida `lib`nom_biblioteca`.so.`1`` amb la versió ABI del nom lògic («SONAME») `1`.[89]

- Els guions del desenvolupador del paquet de la biblioteca han d'executar ldconfig en les circumstàncies específiques per generar els enllaços simbòlics necessaris per a «SONAME» (nom lògic).[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]

- Encara que és una mica antiquat i és només una referència secundària, Debian Library Packaging Guide encara pot ésser útil.

## A.2. Gestionant `debian/`nom_del_paquet`.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:

- Prepara l'estructura de directoris Debian de les fonts fent servir el fitxer original de l'autor `libnom_biblioteca-1.3.tar.gz`

  - Si és la primera vegada que es construeix un paquet de `libnom_biblioteca1`, genera el fitxer `debian/libnom_biblioteca1.symbols` amb el contingut buit.

  - Si la versió `1.2` anterior de l'autor es va empaquetar en el paquet `libnom_biblioteca1` amb el fitxer `debian/libnom_biblioteca1.symbols` apropiat en el seu paquet font, fes-lo servir una altra vegada.

  - 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: warning: some new symbols appeared in the symbols file: ...
       see diff output below
      --- 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

- Construir paquets per distribuir amb eines com debuild i pdebuild.

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

A més a més dels exemples anteriors, cal comprovar la compatibilitat ABI amb més atenció i actualitzar manualment les versions dels símbols (si és necessari). [98]

Encara que només és una referència secundària, Debian wiki UsingSymbolsFiles i els seus enllaços a altres pàgines web pot ésser d'utilitat.

## A.3. Multi-arquitectura

La nova funció multi-arquitectura introduïda a la versió «wheezy» de Debian integra el suport per a la instal·lació en més d'una arquitectura dels paquets binaris (particularment a `i386`<->`amd64`, però també amb altres combinacions) en `dpkg` i `apt`. És convenient que llegeixis les següents referències detalladament:

- Ubuntu wiki MultiarchSpec (original)

- Debian wiki Multiarch/Implementation (estat a Debian)

S'utilitzen triplets com `i386-linux-gnu` i `x86_64-linux-gnu` per als directoris d'instal·lació de les biblioteques compartides. El triplet actual s'estableix de forma dinàmica al valor `$(DEB_HOST_MULTIARCH)` per dpkg-architecture(1) a cada compilació. Per exemple, el directori d'instal·lació de les biblioteques multi-arquitectura es pot canviar de la següent manera.[99]

Directori antic | directori multi-arquitectura i386 | directori 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 codi font de la biblioteca `lib`nom_biblioteca`-1.tar.gz`

- el codi font d'una ordre ``bar`-1.tar.gz` escrit en un llenguatge compilat

- el codi font d'una ordre ``baz`-1.tar.gz` escrit en un llenguatge interpretat

Paquet | Arquitectura | Multi-arquitectura: | Contingut del paquet
--- | --- | --- | ---
`lib`nom_del_paquet``1`` | any | same | la biblioteca compartida, és co-instal·lable
`lib`nom_del_paquet``1`-dbg` | any | same | els símbols de depuració de la biblioteca compartida, són co-instal·lables
`lib`nom_del_paquet`-dev` | any | same | els fitxers de capçalera i d'altres d'un biblioteca compilada, co-instal·lable
`lib`nom_del_paquet`-tools` | any | foreign | els programes de suport en temps d'execució, no són co-instal·lables
`lib`nom_del_paquet`-doc` | all | foreign | els fitxers de documentació de la biblioteca compartida
``bar`` | any | foreign | els fitxers del programa compilat, no són co-instal·lables
``bar`-doc` | all | foreign | els fitxers de documentació del programa
``baz`` | all | foreign | els fitxers del programa interpretat

Cal tenir en compte que el paquet de desenvolupament ha de tenir un enllaç simbòlic a la biblioteca compartida associada sense el número de versió. P. ex.: `/usr/lib/x86_64-linux-gnu/libfoo.so` -> `libfoo.so.1`

## A.4. Construint un paquet de biblioteca compartit

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

- Actualitza `debian/control`.

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

  - Afegeix `Pre-Depends: ${misc:Pre-Depends}` per a cada paquet binari de biblioteca compartida.

  - Afegeix el camp `Multi-Arch:` per a cada secció de paquet binari.

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

- Canvia el directori habitual `/usr/lib/` al directori multi-arquitectura `/usr/lib/$(DEB_HOST_MULTIARCH)/` per a tots els guions de la construcció del paquet.

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

  - Canvia `/usr/lib/` per `/usr/lib/$(DEB_HOST_MULTIARCH)/` a `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]

  - Canvia cada repetició de `/usr/lib/` per `/usr/lib/*/` als fitxers `debian/`nom_del_paquet`.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/nom_del_paquet.links.in > debian/nom_del_paquet.links

Comprova que el paquet de biblioteca compartida conté només els fitxers que s'esperava i que el paquet «-dev» continua funcionant correctament.

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. Paquet nadiu Debian

Si el paquet es construeix només per a Debian o fins i tot només per fer-ho servir en local, les seves fonts poden incloure tots els fitxers de `debian/*`. Hi ha dos mètodes per construir el paquet.

You can make the upstream tarball by excluding the `debian/*` files and package it as a non-native Debian package as in Secció 2.1, «Pla de treball de la construcció de paquets Debian». This is the normal way, which some people encourage using.

L'alternativa és seguir el model de treball pels paquets nadius Debian.

- Genera un paquet nadiu de fonts Debian en el format `3.0 (native)` fent servir un únic arxiu comprimit en format «tar» afegint tots els arxius.

  - ``nom_del_paquet`_`versió`.tar.gz`
  - ``nom_del_paquet`_`versió`.dsc`

- Construcció de paquets binaris Debian des de paquets de fonts Debian nadius.

  - ``nom_del_paquet`_`versió`_`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 ~/el_meu_paquet-1.0
    $ dh_make --native

Then the `debian` directory and its contents are created just like in Secció 2.8, «Paquet Debian no nadiu 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.

Després d'executar l'ordre dpkg-buildpackage, veuràs els següents fitxers en el directori superior:

- `el_meu_paquet_1.0.tar.gz`

  Aquest és el «tarball» del codi font generat a partir del directori `el_meu_paquet-1.0` per l'ordre dpkg-source (el seu sufix no és `orig.tar.gz`).

- `el_meu_paquet_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.)

- `el_meu_paquet_1.0_i386.deb`

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

- `el_meu_paquet_1.0_i386.changes`

  Aquest arxiu descriu els canvis realitzats en la versió actual del paquet de la mateixa forma que en els paquets Debian no nadius (no hi ha el codi de revisió Debian).

[87] Alternativament: `readelf -d lib`nom_biblioteca`.so.`1` | grep SONAME`

[88] Alternativament: `readelf -d lib`nom_biblioteca`.so.`1` | grep NEEDED`

[89] Consulta Debian Policy Manual, 8.1 "Run-time shared libraries".

[90] Consulta Debian Policy Manual, 8.1.1 "ldconfig".

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

[92] Consulta Debian wiki ReleaseGoals/LAFileRemoval.

[93] Consulta Debian wiki RpathIssue.

[94] Els canvis ABI incompatibles amb versions anteriors, normalment requereixen l'actualització del «SONAME» (nom lògic) de la biblioteca i del paquet de la biblioteca compartida a d'altres nous.

[95] Per a biblioteques C++ i altres casos pels quals el maneig individual de símbols és difícil, es millor guiar-se per Debian Policy Manual, 8.6.4 "The shlibs system".

[96] Totes les versions anteriors dels paquets Debian estan disponibles a http://snapshot.debian.org/. La revisió Debian del paquet segueix a la versió per facilitar el manteniment de versions anteriors («backport») del paquet: `1.1` << `1.1-1~bpo70+1` << `1.1-1` i `1.2` << `1.2-1~bpo70+1` << `1.2-1`

[97] La revisió Debian es deriva de la versió per facilitar el manteniment de versions anteriors («backport») del paquet: `1.3` << `1.3-1~bpo70+1` << `1.3-1`

[98] Consulta 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] Alternativament, pots afegir els arguments `--libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)` and `--libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)` a `./configure`. Fitxa't que `--libexecdir` especifica el directori predeterminat per instal·lar programes executables que són engegats per altres programes més que no pas pels usuaris. El valor predeterminat per «Autotools» és `/usr/libexec/` però a Debian és `/usr/lib/`.

Capítol 9. Enviar el paquet. |  |