Capítol 3. Modificar les fonts originals.

# Capítol 3. Modificar les fonts originals.

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.

No hi ha espai en aquest document per explicar tots els detalls de les modificacions que poden haver de fer-se a les fonts originals. Tot i així, a continuació s'expliquen els problemes més freqüents.

## 3.1. Configuració de quilt.

El programa quilt proporciona un mètode bàsic per aplicar i conservar les modificacions del codi font en la construcció de paquets Debian. Atès que és desitjable fer alguna modificació a la configuració predeterminada, anem a crear un àlies dquilt per a la construcció de paquets Debian afegint la següent línia a l'arxiu `~/.bashrc`. La segona línia garanteix que l'àlies tendrà la mateixa funció d'auto-completar del intèrpret d'ordres per l'ordre dquilt que l'ordre quilt:

    alias dquilt="quilt --quiltrc=${HOME}/.quiltrc-dpkg"
    . /usr/share/bash-completion/completions/quilt
    complete -F _quilt_completion -o filenames dquilt

Ara genera l'arxiu `~/.quiltrc-dpkg` de la següent manera:

    d=. ; while [ ! -d $d/debian -a $(readlink -e $d) != / ]; do d=$d/..; done
    if [ -d $d/debian ] && [ -z $QUILT_PATCHES ]; then
        # if in Debian packaging tree with unset $QUILT_PATCHES
        QUILT_PATCHES="debian/patches"
        QUILT_PATCH_OPTS="--reject-format=unified"
        QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"
        QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
        QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"
        if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi
    fi

Consulta quilt(1) i `/usr/share/doc/quilt/quilt.pdf.gz` per fer servir quilt.

## 3.2. Apedaçant el codi font.

Let's assume you find an error in the upstream `Makefile` as follows, where `install: gentoo` should have been `install: gentoo-target`.

    install: gentoo
            install ./gentoo $(BIN)
            install icons/* $(ICONS)
            install gentoorc-example $(HOME)/.gentoorc

Anem a adobar l'errada amb l'ordre dquilt desant les modificacions a realitzar en el fitxer `fix-gentoo-target.patch` [22]:

    $ mkdir debian/patches
    $ dquilt new fix-gentoo-target.patch
    $ dquilt add Makefile

Ara fes els canvis necessaris en el fitxer `Makefile` (amb un editor) original i deixa'l així:

    install: gentoo-target
            install ./gentoo $(BIN)
            install icons/* $(ICONS)
            install gentoorc-example $(HOME)/.gentoorc

A continuació executa dquilt (com s'indica a l'exemple següent) per actualitzar el pedaç generant el fitxer `debian/patches/fix-gentoo-target.patch` i afegeix la descripció de la modificació realitzada com es descriu a DEP-3: Patch Tagging Guidelines:

    $ dquilt refresh
    $ dquilt header -e
    ... descriu la modificació

## 3.3. La instal lació dels arxius al seu destí

En general, els programes s'instal·len en el directori `/usr/local`. Però els paquets Debian no poden fer servir aquest directori d'ús privat de l'usuari administrador: les instal·lacions es fan en els directoris del sistema com és ara `/usr/bin` com estableix la normativa de jerarquia del sistema de fitxers («Filesystem Hierarchy Standard» Filesystem Hierarchy Standard (FHS).).

És freqüent fer servir l'ordre make(1) per a la construcció (compilació) automatitzada del programa i l'execució de l'ordre `make install` instal·la directament el programa en el directori desitjat executant la secció `install` del fitxer `Makefile`. En la construcció dels paquets binaris de Debian, el sistema de construcció simula la instal·lació del programa en una reconstrucció de l'estructura de directoris del programa en un directori temporal en lloc de fer-ho en la destinació real.

Aquestes diferències entre la instal·lació del programa i la «simulació» d'instal·lació en el procés d'empaquetament Debian, és gestionada de manera transparent pel paquet `debhelper` amb les ordres dh_auto_configure i dh_auto_install si es compleixen els següents requisits:

- Cal que el fitxer `Makefile` segueixi les convencions GNU i accepti la variable `$(DESTDIR)` [23].

- Cal que el codi font segueixi l'estàndard de la jerarquia del sistema de fitxers («Filesystem Hierarchy Standard» o FHS).

Els programes que fan servir autoconf de GNU compleixen automàticamente amb les convencions GNU i el seu empaquetament es quasi automàtic. Amb aquests requisits i l'heurística emprada pel paquet `debhelper`, és possible empaquetar sense fer canvis en el sistema de compilació. L'empaquetament no es tan complicat com pot semblar.

Per fer canvis en el fitxer `Makefile`, assegura't que permet fer servir la variable `$(DESTDIR)`. La variable `$(DESTDIR)` no es defineix a l'arxiu i s'afegirà a totes les adreces de directoris que es facin servir en la instal·lació del programa. El guió d'empaquetament estableix el valor de la variable `$(DESTDIR)` al valor del directori temporal d'instal·lació del programa en el procés de construcció del paquet.

Per a un paquet de fonts que generi només un paquet binari, el directori temporal fet servir per l'ordre dh_auto_install és `debian/`nom_del_paquet`` per a paquets amb un arxiu binari [24]. El contingut complet del directori temporal s'instal·larà en el sistema de l'usuari quan aquest instal·li el paquet, amb la diferència que amb dpkg la instal·lació es fa des del directori arrel del sistema (en lloc del directori «debian/» o «debian/tmp» fet servir en la construcció del paquet).

Tots els fitxers i directoris que s'instal·len en el directori `debian/`nom_del_paquet`` en la construcció del paquet, hauran de poder instal·lar-se correctament des del directori arrel quan s'instal·lin fent servir el fitxer `.deb`. No s'ha de fer servir cadenes del tipus `/home/el_meu/deb/`nom_del_paquet`-`versió`/usr/share/`nom_del_paquet`` en la construcció del paquet.

Aquest és la part important del fitxer `Makefile` del paquet `gentoo` [25]:

    # On s'instal·laran els executables amb 'make install'?
    BIN     = /usr/local/bin
    # On s'instal·laran els icones amb 'make install'?
    ICONS   = /usr/local/share/gentoo

We see that the files are set to install under `/usr/local`. As explained above, that directory hierarchy is reserved for local use on Debian, so change those paths as follows:

    # On s'instal·laran els executables amb 'make install'?
    BIN     = $(DESTDIR)/usr/bin
    # On s'instal·laran els icones amb 'make install'?
    ICONS   = $(DESTDIR)/usr/share/gentoo

El destí correcte dels fitxers binaris, icones, documentació, etc, s'explica en el document «Estàndard de la jerarquia del sistema de fitxers». Cal que llegeixis les seccions que poden ésser d'aplicació al teu paquet.

Així doncs, hauríem d'instal·lar els arxius executables en el directori `/usr/bin` en lloc de `/usr/local/bin` i la pàgina de manual a `/usr/share/man/man1` en lloc de `/usr/local/man/man1`. No hi ha cap referència a la pàgina de manual en el fitxer `Makefile` de `gentoo`, però a Debian cal que cada programa tengui la seva pàgina de manual, així que més endavant en farem una i la instal·larem a `/usr/share/man/man1`.

Alguns programes no fan servir variables en el fitxer `makefile` per definir les ubicacions dels fitxers. Això significa que hauràs d'editar alguns dels fitxers de codi C per solucionar això per tal de que es facin servir els directoris correctes. Però, on cal buscar?, i exactament, què? Prova d'executar el següent:

    $ grep -nr --include='*.[c|h]' -e 'usr/local/lib' .

grep buscarà recursivament en l'estructura de directoris i indicarà el nom del fitxer i la línia on hi hagi alguna concordança.

Ara edita els fitxers i canvia la cadena `usr/local/lib` per `usr/lib`. La següent ordre hauria de fer-ho automàticament:

    $ sed -i -e 's#usr/local/lib#usr/lib#g' \
            $(find . -type f -name '*.[c|h]')

Si voleu confirmar cada una de les substitucions en el seu lloc, això es pot fer de forma interactiva de la següent manera:

    $ vim '+argdo %s#usr/local/lib#usr/lib#gce|update' +q \
            $(find . -type f -name '*.[c|h]')

Fet això hauries de trobar (en el fitxer `Makefile`) l'objectiu `install:` (busca una línia que comenci per «install:») i canviar el nom de totes les referències a directoris distints dels definits a l'inici de l'arxiu `Makefile`.

A l'original, l'objectiu «install» de `gentoo` posava:

    install: gentoo-target
            install ./gentoo $(BIN)
            install icons/* $(ICONS)
            install gentoorc-example $(HOME)/.gentoorc

Corregirem el problema i conservarem les modificacions en el fitxer `debian/patches/install.patch` amb l'ordre dquilt.

    $ dquilt new install.patch
    $ dquilt add Makefile

Anem a canviar això per al paquet Debian amb l'editor:

    install: gentoo-target
            install -d $(BIN) $(ICONS) $(DESTDIR)/etc
            install ./gentoo $(BIN)
            install -m644 icons/* $(ICONS)
            install -m644 gentoorc-example $(DESTDIR)/etc/gentoorc

Fixa't que hi ha la primera línia que és nova (`install -d`) abans de les altres. El fitxer `Makefile` original no estava aquesta ordre degut a què els directoris `/usr/local/bin` ja existeixen en el sistema quan s'executa `make install`. Per això, com farem la instal·lació en un directori buit (o inexistent), caldrà assegurar-se que els directoris necessaris ja existeixen.

També podem afegir altres coses al final de la regla, com la instal·lació de la documentació addicional que de vegades els autors originals poden haver descuidat:

           install -d $(DESTDIR)/usr/share/doc/gentoo/html
           cp -a docs/* $(DESTDIR)/usr/share/doc/gentoo/html

Després de comprovar que tot sigui correcte, fes que dquilt actualitzi la modificació en el fitxer `debian/patches/install.patch` i afegeix la descripció en la capçalera del fitxer:

    $ dquilt refresh
    $ dquilt header -e
    ... descriu la modificació

Ja tens un parell de pegats del paquet:

1. Correcció d'un error en el codi font: `debian/patches/fix-gentoo-target.patch`

2. Una modificació específica de l'empaquetat Debian: `debian/patches/install.patch`

Whenever you make changes that are not specific to the Debian package such as `debian/patches/fix-gentoo-target.patch`, be sure to send them to the upstream maintainer so they can be included in the next version of the program and be useful to everyone else. Also remember to avoid making your fixes specific to Debian or Linux — or even Unix! Make them portable. This will make your fixes much easier to apply.

No cal enviar cap dels fitxers del directori `debian/*` a l'autor original.

## 3.4. Diferències a les biblioteques.

There is one other common problem: libraries are often different from platform to platform. For example, a `Makefile` can contain a reference to a library that doesn't exist on the Debian system. In that case, we need to change it to a library that does exist in Debian, and serves the same purpose.

Anem a suposar que a l'arxiu `Makefile` (o `Makefile.in`) del teu programa hi ha una línia que posa alguna cosa com el següent.

    LIBS = -lfoo -lbar

Si el teu programa no es compila degut a que la biblioteca `foo` no està present i el seu equivalent és proporcionat per la biblioteca `foo2` en els sistemes Debian, pots corregir aquest problema de compilació canviant `foo` per `foo2` a l'arxiu `debian/patches/foo2.patch` [26]:

    $ dquilt new foo2.patch
    $ dquilt add Makefile
    $ sed -i -e 's/-lfoo/-lfoo2/g' Makefile
    $ dquilt refresh
    $ dquilt header -e
    .. descriu el canvi

[22] L'anterior execució de dh_make hauria d'haver generat el directori `debian/patches`. En cas contrari o bé si estàs treballant en l'actualització d'un paquet, caldrà executar la primera ordre «mkdir debian/patches».

[23] Consulta GNU Coding Standards: 7.2.4 DESTDIR: Support for Staged Installs.

[24] Per a un paquet de fonts que generi més d'un paquet binari, l'ordre dh_auto_install fa servir el directori temporal `debian/tmp` i l'ordre dh_install amb l'ajuda dels fitxers `debian/`paquet-1`.install` i `debian/`paquet-2`.install` distribuirà el contingut del directori `debian/tmp` en els directoris temporals `debian/`paquet-1`` i `debian/`paquet-2`` per tal de construir els paquets binaris ``package-1`_*.deb` i ``package-2`_*.deb`.

[25] Només és un exemple del contingut de l'arxiu `Makefile`. Si el fitxer `Makefile` es construeix amb l'ordre ./configure, el procediment correcte per solucionar això en l'arxiu `Makefile` és executar l'ordre ./configure des de l'ordre dh_auto_configure amb les opcions predeterminades afegint l'opció `--prefix=/usr`.

[26] Si hi ha canvis a l'API de la biblioteca `foo` a la biblioteca `foo2`, els canvis en el codi font s'hauran de fer de manera que siguin compatibles amb la nova API.

Capítol 2. Primers passos. |  | Capítol 4. Fitxers necessaris en el directori `debian`.