Comment écrire un Portfile pour DarwinPorts


Kevin Van Vechten | kevin@opendarwin.org
8-Oct-2002

Divers

DarwinPorts automatise les tâches usuelles requises pour le portage de logiciel sur Darwin. Les Portfiles contiennent les informations nécessaires pour que la compilation et l'installation de logiciels particuliers soient faites correctement sous Darwin. Le but de DarwinPorts est de pouvoir garder la syntaxe des Portfiles aussi simple que possible, tout en supportant les cas spéciaux requis par la compilation et l'installation de beaucoup de logiciel afin que tout se passe avec succès.

Cet article décrit la constitution d'un simple Portfile, et explore les fonctions les plus communes à DarwinPorts.

Commencer

Pour pouvoir travailler avec DarwinPorts, vous devrez le télécharger et l'installer sur votre système. La page d'accueil du projet DarwinPorts décrit comment se le procurer et l'installer.

Comme vous vous intéressez à l'écriture d'un Portfile, changeons quelques options de configuration qui vous aideront au déboguage. Éditez le fichier /etc/ports/ports.conf afin que les changements suivants y soient incorporés (vous devrez passer par sudo pour pouvoir éditer ce fichier) :


ports_debug     yes
ports_verbose   yes

Cela affichera des messages utiles pour le déboguage qui sont normalement omis lors de l'utilisation de DarwinPorts.

DarwinPorts effectuera plusieurs tâches basiques prédéfinies, qui sont :

Sujets basiques

Sujets avancés

Annexe

Récupération des sources

La première chose à faire est de choisir un logiciel à porter. Pour cet exemple, nous allons utiliser ircII, un client IRC populaire. Nous commencerons avec un Portfile simple, décrivant les attributs basiques d'ircII comme son nom, sa version et le site où nous pouvons télécharger les sources. Créez un répertoire de travail nommé ircii et créez à l'intérieur un fichier nommé Portfile ayant le contenu suivant :


PortSystem 1.0
name            ircii
version         20020912
categories      irc
maintainers     kevin@opendarwin.org
master_sites    ftp://ircftp.au.eterna.com.au/pub/ircII/

Un Portfile consiste en une suite de paires de type clé/valeur. Les clés name et version décrivent le nom et la version du logiciel. La clé categories est une liste des catégories auquel le logiciel peut appartenir de façon logique; c'est utilisé dans un but d'organisation. La première entrée dans categories devrait correspondre au nom du répertoire où doit résider le répertoire du port. La clé maintainers devrait, elle, contenir votre adresse email et la clé master_sites devrait quant à elle contenir une liste des sites où télécharger les sources. DarwinPorts utilise les termes "clés" et "options" indifféremment comme la plupart des clés sont utilisées comme des options d'une tâche particulière dans le processus du portage.

Arrivé à ce point, le Portfile est assez complet pour permettre le téléchargement d'ircII. Par défaut, DarwinPorts ajoutera version à name et considérera que les sources sont au format .tar.gz. Depuis votre répertoire de travail, exécutez la commande suivante :


% port checksum

La commande port opère directement sur le Portfile du répertoire de travail actuel. Vous devriez voir la même chose que ce qui suit :


DEBUG: Executing com.apple.main (ircii)
DEBUG: Executing com.apple.fetch (ircii)
--->  ircii-20020912.tar.gz doesn't seem to exist in /opt/local/var/db/dports/
distfiles
--->  Attempting to fetch ircii-20020912.tar.gz from ftp://
ircftp.au.eterna.com.au/pub/ircII/
DEBUG: Executing com.apple.checksum (ircii)
Error: No checksums statement in Portfile.  File checksums are:
ircii-20020912.tar.gz md5 2ae68c015698f58763a113e9bc6852cc
Error: Target error: com.apple.checksum returned: No checksums statement in 
Portfile.

Vérification du fichier téléchargé

Remarquez que DarwinPorts vérifiera dans un premier temps s'il existe une copie locale d'ircii-20020912.tar.gz mais il ne la trouvera pas, donc il la téléchargera depuis le site distant. La commande port ne se termine correctement car l'erreur : "No checksums statement in Portfile" est arrivée. Les Portfiles doivent contenir une somme de contrôle md5 de tous les fichiers distribués -- cela permet à DarwinPorts de vérifier l'exactitude et l'authenticité des sources. Pour plus de souplesse, une somme de contrôle md5 pour les fichiers téléchargés est affichée lorsque l'argument checksums n'est pas spécifié. Revenez en arrière et ajoutez ce qui suit à votre Portfile :


checksums       md5 2ae68c015698f58763a113e9bc6852cc

Extraction des sources dans un répertoire de travail

Maintenant que nous avons une somme de contrôle, nous pouvons vérifier nos sources. Procédons à l'extraction des sources dans notre répertoire de travail. Exécutez la commande suivante :


% port extract

Qui devrait afficher ce qui suit :


DEBUG: Skipping completed com.apple.main (ircii)
DEBUG: Skipping completed com.apple.fetch (ircii)
DEBUG: Executing com.apple.checksum (ircii)
--->  Checksum OK for ircii-20020912.tar.gz
DEBUG: Executing com.apple.extract (ircii)
--->  Extracting for ircii-20020912
--->  Extracting ircii-20020912.tar.gz ... DEBUG: Assembled command: 'cd /Users/
kevin/opendarwin/proj/darwinports/dports/irc/ircii/work && gzip -dc /opt/local/
var/db/dports/distfiles/ircii-20020912.tar.gz | tar -xf -'
Done

Exécution d'un script Configure

Maintenant que les sources ont été extraites dans un répertoire nommé work placé dans le répertoire de travail actuel, nous pouvons configurer les sources afin de les compiler avec les options désirées. Par défaut, DarwinPorts assume que le logiciel que vous portez utilise un script configure autoconf, et toujours par défaut, DarwinPorts passera l'argument --prefix=${prefix} au script configure, spécifiant que ce logiciel devra s'installer dans la hiérarchie utilisée par DarwinPorts.

Les options standards d'ircII semblent correctes pour une installation de base sur Darwin, donc nous passerons directement à la phase de compilation.

Compilation des sources

Pour compiler, tapez ce qui suit :


% port build

Par défaut, la phase de compilation exécute l'utilitaire système make(1). (Cela peut être changé avec l'option build.type qui accepte les arguments tel que bsd, gnu ou pbx. Alternativement, l'option build.cmd peut être utilisée pour spécifier une commande de compilation arbitraire.) L'étape ci-dessus a commencé la compilation des sources, lorsqu'elle sera terminée, nous serons fin prêt pour installer le logiciel.

Installation du programme dans le système

Les Portfiles doivent contenir une option contents qui spécifie quels sont les fichiers installés. DarwinPorts utilise cette information pour cataloguer quel fichier appartient à quel logiciel, car ensuite il peut être désinstaller ultérieurement. Chaque paramètre de contents est un chemin vers un fichier. Tous les chemins sont relatifs à la variable ${prefix}. Comme moyen simple de déterminer exactement quels fichiers font partie d'ircII, utilisons la commande "find" pour composer un manifeste des fichiers dans la hiérarchie ${prefix}. Après l'installation, nous allons réutiliser la commande "find" et utiliser les différences pour générer notre liste.

En utilisant le format unidiff, nous allons comparer la liste des fichiers existants avec la nouvelle liste de fichiers, en prenant en compte juste les nouvelles lignes ajoutées. Comme les chemins sont supposés être relatifs à ${prefix}, nous allons passer via sed et effacer le prefix (/opt/local/), et stocker le résultat dans un fichier nommé contents placé dans notre dossier hébergeant notre port. Nous pouvons faire tout cela via les commandes suivantes :


% find /opt/local > /tmp/existing.files
% sudo port install
% find /opt/local > /tmp/more.files
% diff -u /tmp/existing.files /tmp/more.files | grep ^\+\/ | \
  sed -e 's|^\+/opt/local/*||g' > contents

Maintenant que nous avons un fichier contents dans notre répertoire hébergeant notre port, nous devrons l'éditer afin de débuter avec contents { et de terminer avec un }. (C'est important de noter que tout autre processus utilisant la hiérarchie ${prefix} peut interférer avec l'efficacité de la commande find. Vous devriez vérifier le fichier contents résultant afin de voir si tout les fichiers apparaissent à leur place, spécialement les fichiers temporaires de DarwinPorts comme /var/db/receipts/ircii-20020912.tmp.) Il est également important de s'assurer que dans le fichier contents les répertoires soient listés après les fichiers qui les contiennent afin que le processus de désinstallation fonctionne correctement. Ensuite nous devrons éditer le Portfile afin d'inclure notre fichier contents :


include contents

Si la liste des fichiers installés par le port ne s'étend pas au-delà d'une page de terminal de 80x24, l'option contents devrait être incluse dans le Portfile. Au lieu de include contents, nous utiliserons :


contents    bin/irc \
            bin/irc-20020912 \
            man/man1/irc.1 \
            man/man1/ircbug.1 \
            man/man1/ircII.1 \
            man/man1

À présent nous avons un portfile complet. Relancez l'étape d'installation pour ajouter ce port à votre propre registre :


% sudo port install
Qui devrait afficher :

DEBUG: Skipping completed com.apple.main (ircii)
DEBUG: Skipping completed com.apple.fetch (ircii)
DEBUG: Skipping completed com.apple.checksum (ircii)
DEBUG: Skipping completed com.apple.extract (ircii)
DEBUG: Skipping completed com.apple.patch (ircii)
DEBUG: Skipping completed com.apple.configure (ircii)
DEBUG: Skipping completed com.apple.build (ircii)
DEBUG: Skipping completed com.apple.install (ircii)
DEBUG: Executing com.apple.registry (ircii)
--->  Adding ircii to registry, this may take a moment...

Sujets avancés

Modifier des cibles

Il est possible de modifier la fonctionnalité d'une cible de compilation avec le code Tcl. Un exemple commun est le suivant, qui peut être utile pour un script sans script configure autoconf :


configure {}

Dans le Portfile, cela remplacera la fonctionnalité de la cible de configure, aussi nous sauterons cette étape. Il est également possible d'exécuter du code Tcl immédiatement avant ou après une cible standard. Cela peut être accompli de la manière suivante :


post-configure {
    reinplace "s|change.this.to.a.server|irc.openprojects.net|g" \
        "${workdir}/${worksrcdir}/config.h"
}

Cet exemple remplace l'occurrence de change.this.to.a.server avec irc.openprojects.net dans le fichier config.h qui a été généré pendant la phase précédant configure. Notez que c'est en quelque sorte un exemple inventé et voulu, car la même chose aurait pu être faite en spécifiant --with-default-server=irc.openprojects.net dans configure.args, mais l'approche est généralement utile lorsque de tels arguments ne sont pas présents.

Variantes du Portfile

Comme Darwin 6.0 gère ipv6, il est possible de configurer le port avec l'option --with-ipv6. Cela peut être effectué en ajoutant l'option suivante dans le Portfile :


configure.args      --disable-ipv6

variant ipv6 {
    configure.args-append  --enable-ipv6
}

Maintenant la compilation par défaut n'inclura pas le support d'ipv6, mais si la variante ipv6 est voulue, ircII l'aura. Les options par elles-même devraient être considérées comme un facteur d'assignation. Comme les variantes peuvent être utilisées en combinaison avec d'autre, il est conseillé de les ajouter uniquement aux options au lieu de les écraser. Toutes les options peuvent avoir un suffixe avec -append ou -delete pour ajouter ou effacer un terme de la liste. Vous pouvez spécifier la compilation avec la variante ipv6 de la manière suivante :


% port build +ipv6

Annexe

Aperçu d'un Portfile

Ce qui suit est le listage complet du Portfile d'ircII :


PortSystem 1.0
name            ircii
version         20020912
categories      irc
maintainers     kevin@opendarwin.org
master_sites    ftp://ircftp.au.eterna.com.au/pub/ircII/
checksums       md5 2ae68c015698f58763a113e9bc6852cc
configure.args  --disable-ipv6
include         contents

post-configure {
        reinplace "s|change.this.to.a.server|irc.openprojects.net|g" \
                  "${workdir}/${worksrcdir}/config.h"
}

variant ipv6 {
        configure.args-append --enable-ipv6
}

Liste de contents

Ce qui suit est un listage partiel du fichier contents d'ircII :


contents {
bin/irc
bin/irc-20020912
... omitted ...
man/man1/irc.1
man/man1/ircbug.1
man/man1/ircII.1
man/man1
man
... omitted ...
}