Capítol 3. Modificar les fonts originals.

Sumari

3.1. Configuració de quilt.
3.2. Apedaçant el codi font.
3.3. La instal lació dels arxius al seu destí
3.4. Diferències a les biblioteques.

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.

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.

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ó

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.

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».

[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.