OBSD4* : wiki

Version de traduction basée sur la 6.2 officielle


Ports - Guide

Aperçu

Ainsi, vous venez de compiler votre package de logiciel préféré sur votre machine OpenBSD et vous voulez partager vos efforts en le transformant en port standard. Que faire ?

La plus importante des choses à faire est de communiquer. Demandez aux personnes sur ports@openbsd.org s'ils travaillent sur le même port. Parlez-en aux auteurs du logiciel, y compris des problèmes que vous pourriez rencontrer. Si les renseignements sur la licence semblent inexacts, dites-leur. Si vous avez rencontré des difficultés pour faire la construction du port, dites-leur ce qui peut être corrigé. S'ils ne développent que sous Linux et semblent ignorer le reste du monde Unix, essayez de les faire changer d'avis.

La communication fait la différence entre un port qui réussi et un port qui sera lentement abandonné par tous.

Tout d'abord, regardez les informations de portage sur cette page. Testez, re-testez encore, et finalement testez à nouveau !

OpenBSD supporte pleinement les mises à jours. Cela signifie que certains problèmes doivent être pris en compte.

Soumettez le port. Créez une archive tar gzip du répertoire du port. Vous pouvez alors soit le placer sur un serveur HTTP public, en envoyant son URL à ports@openbsd.org, soit envoyer le port MIME encodé à la même adresse.

Portez certains nouveaux logiciel prend du temps. Le maintenir dans le temps est encore plus difficile. Il est tout à fait correct de porter le logiciel et de laisser d'autres personnes s'en occuper après. Il est également correct d'aider les autres personnes à mettre à jour et maintenir d'autres ports, tant que vous communiquez pour éviter de faire les mêmes choses deux fois.

Dans la culture d'OpenBSD, le rôle de RESPONSABLE n'est pas un statut, mais une responsabilité. Nous avons CVS et les commentaires pour donner du crédit à la personne qui a fait le travail. Un RESPONSABLE de port est ceci : une personne qui assume la responsabilité du fonctionnement du port et qui est prête à passer un certain temps pour s'assurer qu'il fonctionne le mieux possible.

Liste de contrôle du portage

La liste ci-dessous est utile pour se rappeler des choses à faire. Elle n'est ni totalement exacte, ni parfaite. Envoyez vos commentaires et vos questions à ports@openbsd.org.

  1. Si vous désirez être responsable, souscrivez à ports@openbsd.org.
    • C'est ici que toutes les discussions sur les ports ont lieu.
    • Lire cette liste est important puisque beaucoup d’annonces y sont faites.
    • Vous y trouverez beaucoup d'experts en portage. Ils peuvent vous offrir de bons conseils ou tester les ports pour vous.
  2. Devenir responsable signifie plus que juste soumettre des ports. Cela signifie aussi d'essayer de les garder à jour, et de répondre aux questions les concernant.
  3. Procurez vous une copie de l'arborescence des ports depuis CVS. Vous pouvez trouver des instructions sur comment faire cela sur la page AnonCVS. En tant que porteur, vous devrez garder à jour votre système de base, l'arborescence des ports, et les packages installés.
  4. À partir des sous-répertoires de premier niveau de /usr/ports/, choisissez une catégorie primaire pour votre port. Créez un nouveau répertoire sous /usr/ports/<category>/ ou /usr/ports/mystuff/<category>/ et créez-y l'infrastructure de base. Copiez le modèle du fichier Makefile depuis /usr/ports/infrastructure/templates/Makefile.template. Remplissez la valeur CATEGORIES par la première catégorie que vous avez choisie.
  5. Ajoutez les parties au Makefile concernant les éléments à récupérer.
    • Remplissez la valeur EXTRACT_SUFX si elle est autre que .tar.gz. D'autres exemples sont .tar.Z, ou .tgz.
    • Remplissez la valeur DISTNAME par le nom du fichier moins la valeur du suffixe d'extraction. Si vous avez foo-1.0.tar.gz, DISTNAME est foo-1.0.
    • Remplissez la valeur MASTER_SITES avec une liste d'URL aux endroits où le fichier distfile est conservé, par exemple https://ftp.openbsd.org/pub/OpenBSD/distfiles/. N'oubliez pas la barre oblique. Essayez d'avoir au moins trois sites distincts. Placez le plus accessible en premier car ils sont parcourus dans l'ordre.
    • Gardez à l'esprit que la récupération du fichier passe par le chemin ${MASTER_SITES}${DISTNAME}${EXTRACT_SUFX}. Les trois sont utilisées. Ne paramétrez pas DISTNAME pour pointer directement vers le fichier.
    • Vous pouvez vérifiez si vous avez rempli correctement ces valeurs en tapant make makesum.

      Pour des ports plus complexes, vous avez plus d'options et d'outils disponibles.

    • Vous avez aussi de disponible la variable PATCHFILES. Ceci est une liste de correctifs venant de l'auteur (qui ne fait pas partie d'OpenBSD) à appliquer au port. Les utilisations courantes sont en rapport avec les correctifs de sécurité ou de fiabilité.
    • Si vos ports sont disponibles sur de grands miroirs publics tels que GNU, Sourceforge ou CPAN, nous avons déjà fourni une liste de sites pour votre utilisation dans /usr/ports/infrastructure/templates/network.conf.template. Paramétrez MASTER_SITES à ${MASTER_SITE_GNU}, ou ${MASTER_SITE_SOURCEFORGE}, etc. Pour simplifier ce processus, utilisez la notation ${MASTER_SITE_FOO:=subdir/} pour ajouter le sous-répertoire de distribution.
    • Pour les ports avec des sources distribuées depuis GitHub, il y a plusieurs possibilités.
      • Dans quelques cas, par exemple icinga ou darktable, un fichier de distribution tar a été préparé et est disponible dans le répertoire /releases/. S'ils sont disponibles, utilisez-les de préférence à d'autres options car elles incluent généralement l'infrastructure de construction appropriée (les scripts configure, etc.) qui manquent souvent dans les versions “taguées”. Spécifiez-les comme d'habitude, en utilisant quelque chose comme MASTER_SITES=https://github.com/acct/project/releases/download/relname/.
      • Dans d'autres cas, les fichiers ont été étiquetés mais ils reposent sur la création d'archive github à la volée. Cela peut être spécifié en utilisant les variables suivantes de bsd.port.mk(5) : GH_ACCOUNT, GH_PROJECT, GH_TAGNAME. Le nom de fichier fourni est rarement approprié pour une utilisation directe en tant que DISTNAME, n'ayant fréquemment que seul le numéro de version ; ils peuvent être renommés au moment du téléchargement en utilisant la notation “{}” dans DISTFILES.
      • Occasionnellement il n' y a pas d'autre alternative que d'avoir pour référence de port seulement un identifiant de commit. Dans ce cas, GH_COMMIT devrait être utilisé à la place de GH_TAGNAME.
    • Normalement, les ports correspondent aux versions données d'un logiciel. Une fois qu'ils sont récupérés, les fichiers sont comparés aux sommes de contrôle enregistrées dans distinfo. Ainsi, pour éviter la confusion, DISTFILES et PATCHFILES devraient avoir clairement des versions de numéro visibles : ne récupérez pas foo-latest.tar.gz si c'est un lien vers foo-1.0.5.tar.gz. Si une information n'est disponible que dans un fichier non versionné, demandez gentiment à l'auteur du programme original de faire clairement ces distinctions. Dans l'intervalle, si vous devez utiliser un fichier comme celui-ci, réglez DIST_SUBDIR sur ce que serait un DISTNAME raisonnable, tel que foo-1.0.5, de telle sorte que les différentes versions du fichier distfile portant le même nom ne s'affrontent pas sur les miroirs du fichier de distribution.
    • Si un port donné nécessite plus de cinq DISTFILES et PATCHFILES pour fonctionner, utilisez DIST_SUBDIR pour éviter de trop encombrer DISTDIR (/usr/ports/distfiles par défaut). Dans ce cas, DIST_SUBDIR ne doit pas inclure de numéros de version. Quand le port est mis à jour vers la dernière version, quelques fichiers distfiles peuvent ne pas changer, mais ils seront récupérés si DIST_SUBDIR est changé. Même si tous les fichiers distfiles changent, il est plus facile pour l'utilisateur de faire du dépoussiérage.
    • Tous les DISTFILES et PATCHFILES ne viennent pas nécessairement du même ensemble de MASTER_SITES. Des sites supplémentaires peuvent être définis en utilisant les variables MASTER_SITES0 à MASTER_SITES9. Écrivez simplement DISTFILES=foo-1.0.5.tar.gz:5 pour récupérer foo-1.0.5.tar.gz depuis MASTER_SITES5.
    • Certains ports n'ont pas toujours besoin de récupérer tous les fichiers en toutes circonstances. Par exemple, certains ports ont quelques options de compilation, et des fichiers associés qui sont requis seulement dans ces cas. Ou, ils peuvent avoir besoin de certains fichiers seulement pour certaines architectures. Dans de tels cas, ces fichiers supplémentaires optionnels peuvent être mentionnés dans la variable SUPDISTFILES. Des cibles telles que makesum ou mirror-distfiles récupéreront ces fichiers supplémentaires dont l'utilisateur occasionnel n'a pas besoin.
  6. Créez une somme de contrôle dans distinfo en tapant make makesum. Puis, vérifiez que la somme de contrôle soit correcte en tapant make checksum.
    • Dans certains cas rares, les sommes de contrôle des fichiers ne peuvent pas être vérifiées de manière fiable. Par tous les moyens, les porteurs devraient essayer de trouver des sites fiables. Il est hautement souhaitable de communiquer avec l'auteur du logiciel et le responsable du site d'archivage à ce stade. Dans le pire des cas, les fichiers non vérifiables peuvent être mentionnés dans la variable IGNOREFILES.
    • Tous les fichiers dans DISTFILES sont habituellement traités durant make extract. EXTRACT_ONLY peut être utilisé pour limiter l'extraction d'un sous-ensemble de fichiers (éventuellement vide). L'utilisation habituelle de cette variable est de personnaliser l'extraction : par exemple, si certains DISTFILES ont besoin de traitement spécifique, ils peuvent être enlevés de EXTRACT_ONLY et manipulé manuellement au stade post-extract. Pour des raisons historiques, make extract configure d'abord le répertoire de travail lors de l'extraction des fichiers. Cela étant, fournir une cible pre-extract ou do-extract est hautement inhabituel (et est un comportement assez suspect, révélateur d'un haut degré d'obscurcissement dans le port).
    • Pour des raisons historiques, les correctifs qui ont besoin d'un traitement spécifique devraient être mentionnés dans DISTFILES, et supprimés depuis EXTRACT_ONLY.
  7. Extraire le port avec make extract. Prêtez attention à l'endroit où se trouvent la base des sources. Habituellement, c'est dans /usr/ports/pobj/${PKGNAME}${FLAVOR_EXT}${DISTNAME}. Vous pouvez avoir besoin de modifier la variable WRKDIST du fichier Makefile si cela est différent.
  8. Lisez la documentation d'installation et les notes dont vous avez besoin pour construire le port et toutes options spécifiques qui pourraient être nécessaires.
  9. C'est aussi le bon moment pour déterminer quelles sont les restrictions de licence qui s'appliquent à votre port. Beaucoup sont librement redistribuables, mais certaines ne le sont pas. Nous avons besoin de répondre à trois questions pour distribuer les ports proprement. Ce sont les valeurs PERMIT_* dans le fichier Makefile.
    • PERMIT_PACKAGE_CDROM nous dit si nous pouvons mettre à disposition le package sur cdrom
    • PERMIT_PACKAGE_FTP nous dit si nous pouvons mettre à disposition le package sur sites par ftp.
    • PERMIT_DISTFILES_FTP nous dit si nous pouvons faire un miroir des fichiers distfiles sur site par ftp.
      Si toutes les trois sont permises, remplissez simplement PERMIT_PACKAGE_CDROM=Yes. Autrement incluez toutes ces trois variables, paramétrez les sur Yes, ou mettez une chaîne de commentaire indiquant que certaines distributions ne sont pas autorisées. Prêtez attention aux conditions spéciales que vous pourriez avoir à remplir plus tard. Par exemple, certains ports requièrent d'installer une copie de la licence. Nous vous recommandons de placer la licence dans /usr/local/share/doc/<name>/.
      En plus de ces valeurs PERMIT_*, déposez un marqueur de licence tel que #License au-dessus en tant que commentaire, de cette manière nous savons pourquoi les valeurs PERMIT_* sont ainsi paramétrées. Pour la GPL, spécifiez quelle version est applicable, p. ex. “GPLv2 only”, “GPLv2+” (signifiant “v2 ou plus récent”), “GPLv3 only”, etc.
  10. Ajoutez les options de configuration à Makefile et/ou créez les scripts de configuration.
    • Si GNU configure est utilisé, exécutez ./configure –help pour voir quelles options sont disponibles. En particulier, regardez quelles dépendances optionnelles peuvent ne pas être présentes sur votre système, mais peuvent être obtenues sur un autre systme ou dans une autre construction.
    • Tout ce que vous souhaitez modifier peut être changé en ajoutant les drapeaux –option au paramètre CONFIGURE_ARGS dans le Makefile.
    • Utilisez CONFIGURE_ARGS+= pour ajouter à la variable. CONFIGURE_ARGS= l'écrasera.
  11. Essayez de compiler le port par make build.
    • Si vous êtes chanceux, le port ira jusqu'au bout sans erreurs.
    • S'il quitte avec une erreur, vous aurez besoin de générer des correctifs pour votre port. Déterminez ce qui doit être changé et faites un correctif.
    • La séquence pour faire un correctif pour un fichier est habituellement :
      • cd `make show=WRKSRC` ; cp foo/bar.c{,.orig}
      • éditer foo/bar.c pour corriger l'erreur.
      • cd - ; make update-patches
      • ce qui créera le fichier patches/patch-foo_bar_c avec vos modifications.
    • La manière la plus facile de remettre à zéro le port et de tester vos correctifs est de faire make clean patch.
  12. Commencez un cycle de make build, générez un correctif en utilisant make update-patches et make clean patch.
    • Les correctifs vont dans le répertoire patches/ et devraient être nommés patch-* - * étant une chaîne de caractères significative. La manière préférée pour le nommer est patch-FILENAME, où FILENAME est le nom du fichier qui est corrigé (make update-patches fait cela automatiquement pour vous).
    • Appliquer PATCHFILES est la première moitié de l'étape du make patch. Il peut être invoqué séparément comme make distpatch, qui est une cible pratique pour les porteurs. Ignorez ceci si vous ne l'avez pas paramétré.
    • Veuillez ne corriger seulement qu'un fichier source par fichier correctif.
    • Utilisez make update-patches pour générer les correctifs.
    • Vérifiez que les correctifs NE contiennent PAS d'étiquettes que cvs remplacerait. Si cela est, vos correctifs ne s'appliqueraient pas après avoir été enregistrés. Vous pouvez enregistrer vos changements avec -kk pour éviter cela.
    • Écrivez de petites explications au début du fichier correctif à son propos (ce n'est pas obligatoire, mais cela est fait, par exemple, souvent pour les correctifs de sécurité).
    • Veuillez renvoyer vos correctifs à l'auteur du logiciel.
  13. Essayez de paramétrer SEPARATE_BUILD.
    • Si le port peut compiler avec des fichiers objet en dehors de son arborescence source, c'est plus propre (beaucoup de programmes utilisant CONFIGURE_STYLE=gnu le peuvent), et cela peut aider les personnes qui montent leur arborescence de ports sur plusieurs architectures.
    • Cela peut également vous épargner des efforts, car vous pourrez éventuellement redémarrer le cycle par la configuration la plupart du temps.
  14. Parcourez la sortie (le cas échéant) et modifiez les options dans le Makefile. Pour répéter, utilisez la commande make clean configure.
    Note : assurez vous que les fichiers dépendant de l'hôte aillent dans /etc ou /etc/<name>, mais ne doivent JAMAIS REMPLACER OU MODIFIER des fichiers existants dans /etc. Il est mieux de les installer dans /usr/local/share/<name> puis de les copier dans /etc si seulement ils n'existent pas. Si les fichiers existent, affichez un message qui informe que tels et tels fichiers ont besoin d'être modifiés. Cela garantit aussi que les fichiers seront inclus dans le package puisque tout ce qui est sous /usr/local est inclus dans le fichier PLIST. Pour manipuler la copie avec précaution, le mot-clé @sample est de préférence utilisé dans le PLIST. Après qu'un package ait été installé, le contenu de pkg/MESSAGE sera affiché s'il existe.
    Les emplacements des fichiers OpenBSD sont :
    user executables:			/usr/local/bin
    system admin executables:		/usr/local/sbin
    program executables:			/usr/local/libexec
    libraries:				/usr/local/lib
    architecture dependent data:		/usr/local/lib/<name>
    installed include files:		/usr/local/include or
    					/usr/local/include/<name>
    single-machine data:			/etc or /etc/<name>
    local state:				/var/run
    games score files:			/var/games
    GNU info files:				/usr/local/info
    man pages:				/usr/local/man/...
    read-only architecture-independent:	/usr/local/share/<name>
    misc documentation:			/usr/local/share/doc/<name>
    examples files:				/usr/local/share/examples/<name>
  15. Commencez un cycle de makes jusqu'à ce que le port soit prêt. Corrigez (voir ci-dessus), nettoyez, et construisez le jusqu'à ce que le port soit généré. Éliminez si possible tous les avertissements, en particulier les avertissements liés à la sécurité.
  16. Contrôlez la sémantique de SEPARATE_BUILD. Vous devez faire cela seulement si le port est construit avec SEPARATE_BUILD défini. Idéalement, le port ne devrait modifier aucun fichier dans ${WRKSRC} après make patch. Vous pouvez vérifier cela en vous assurant de ne pas avoir d'accès en écriture sur ${WRKSRC}. Alors, vous pouvez paramétrer SEPARATE_BUILD=concurrent. Une personne peut utiliser la même arborescence des sources pour construire sur des architectures différentes simultanément. Autrement, paramétrez SEPARATE_BUILD=simple. Construire sur des arches distinctes simultanément peut poser des problèmes, car certains fichiers sources peuvent être régénérés à des moments gênants.
  17. Ajoutez COMMENT dans le Makefile. COMMENT est une COURTE description du port en une ligne (max. 60 caractères). N'incluez PAS le nom du package (ou le numéro de version du logiciel) dans le commentaire. NE démarrez PAS avec une lettre majuscule à moins que cela soit significatif sémantiquement, et NE terminez PAS avec un point. NE JAMAIS DÉMARREZ AVEC UN ARTICLE INDÉFINI TEL QUE “a” OU “an” - supprimez l'article complètement.
  18. Mettez une description plus longue dans pkg/DESCR. De un à quelques paragraphes, expliquant brièvement ce que le port fait, est suffisant. Les lignes ne devraient pas avoir une longueur de plus de 80 caractères. Cela peut être fait en commençant par éditer le fichier DESCR puis en exécutant dessus fmt -w 80.
  19. Si l'application a besoin de créer un utilisateur ou un groupe, choisissez l'identifiant libre le plus petit depuis /usr/ports/infrastructure/db/user.list pour votre port et assurez vous que votre port soit ajouté à ce fichier au moment du commit.
  20. Installez l'application avec make fake. Les bibliothèques ne devraient jamais être retirées. Les exécutables sont supprimés par défaut; ceci est gouverné par ${INSTALL_STRIP}. ${INSTALL_PROGRAM} honore cela automatiquement et est préférable à des retraits inconditionnels (par exemple, par une cible install-strip ou en exécutant strip depuis le Makefile). Vous pouvez utiliser objdump --syms pour déterminer si un binaire est retiré ou non. Les fichiers retirés n'ont pas de symboles dans la SYMBOL TABLE.
  21. Vérifiez encore le port pour les trous de sécurités. C'est particulièrement important pour les programmes en réseaux. Lisez nos recommandations de sécurité.
  22. Assurez-vous que votre répertoire /etc/mtree soit à jour. (La prochaine étape utilise les listes mtree pour supprimer les répertoires existants des les listes d'empaquetage générées). Souvenez-vous que (U)pdate d'OpenBSD ne touche pas à /etc… Pour mettre à jour automatiquement /etc, sysmerge(8) peut aider.
  23. Créez pkg/PLIST. Après que l'installation avec make fake soit complète, utilisez la commande de développeur make plist, qui crée ou met à jour le fichier PLIST dans le répertoire pkg. Ce fichier est un candidat pour la liste d'empaquetage.
    Parcourez PLIST et vérifiez que tout a été installé et installé aux bons endroits. Tout ce qui n'a pas été installé peut être ajouté par une règle Makefile post-install. Notez que les annotations PLIST sont documentées dans le manuel pkg_create(1).
  24. Il est possible que certains répertoires n'aient pas besoin d'être dans PLIST car ils ont été installés par une dépendance ; si vous l'avez ajoutée à LIB_DEPENDS ou RUN_DEPENDS, relancez make plist pour les supprimer.
  25. Testez l'empaquetage avec make package, testez l'installation du paquet résultant avec make install, et testez sa suppression avec make uninstall. Lors du traitement de paquets multiples, il peut être préférable d'utiliser directement pkg_add(1) et pkg_delete(1), en paramétrant PKG_PATH sur /usr/ports/packages/`arch -s`/all/ dans l'environnement.
  26. Vérifiez les dépendances. Parcourez vos journaux pour vérifier que le port ait bien détecté ce qui est mentionné dans DEPENDS, et rien d'autre. Vérifiez les noms, particulièrement à l'étape make configure, pour les dépendances cachées (du genre qui existe ailleurs dans l'arborescence des ports et qui pourrait être détectée si l'utilisateur installe d'abord d'autres ports).
  27. Vérifiez les dépendances de type bibliothéques partagées. Exécutez make port-lib-depends-check et ajoutez chaque annotation LIB_DEPENDS ou WANTLIB jusqu'à ce que cela fonctionne correctement. Il se peut que vous ayez besoin de lire les directives de mise à jour pour comprendre pourquoi c'est si important.
  28. Vérifiez que les tests de régression fonctionnent bien. Paramétrez NO_TEST=Yes si le port n'a pas d'infrastructure de test. Si des dépendances sont requises pour exécuter les tests, mais pas pour construire le port, listez-les dans TEST_DEPENDS. Veuillez noter : ne pas paramétrez NO_TEST si le port possède un test de régression vide.
  29. Testez le succès de make clean. Parfois l'étape make fake crée des fichiers dans le répertoire de compilation qui peuvent provoquer un échec.
  30. Exécutez l'utilitaire /usr/ports/infrastructure/bin/portcheck dans le répertoire de votre port et traitez les problèmes qu'il trouve, le cas échéant.
  31. Envoyez un mail à ports@openbsd.org avec une description, la page d'accueil (s'il y a), et une courte note demandant des commentaires et des tests. Assurez-vous d'attacher le port, le correctif au courriel (ou de mentionner l'URL où il peut être trouvé) et envoyez-le.
    Essayez d'obtenir des autres de le tester pour vous sur différentes plate-formes.
    • Les systèmes AMD64 sont bons car ils sont rapides, et car sizeof(int) != sizeof(long) sur cette plate-forme.
    • les systèmes sparc64 sont bons parce qu'ils sont assez communs, peuvent être assez rapides, et leur ordre d'octet est à l'opposé de i386 ; si vous développiez sur sparc64, bien sûr, vous devriez le tester sur i386.
  32. Intégrez tous les retours que l'ont vous fait. Testez à nouveau sur votre plate-forme. Obtenez de ceux qui vous ont fait des retours de tester à nouveau votre port mis à jour.
  33. Faites un commit CVS du port.
    Si vous n'êtes pas un développeur avec un accès à CVS, alors vous devrez trouver un développeur OpenBSD pour faire les étapes suivantes à votre place (demandez sur ports@openbsd.org).
    Avant d'importer quoi que ce soit, obtenez au moins un “OK” d'un autre développeur de ports (plus il y en a, mieux c'est).
    Si vous utilisez @newuser ou @newgroup dans les fichiers PLIST, vérifiez qu'aucun utilisateur n'a été ajouté à /usr/ports/infrastructure/db/user.list depuis que le port a été créé.
    Pour les nouveaux ports, nous utilisons cvs import, plutôt que d'ajouter les nouveaux fichiers individuellement. Par exemple, pour importer un nouveau port lang/kaffe1, faites d'abord une importation :
    $ cd /usr/ports/lang/kaffe1
    $ cvs -ndcvs.openbsd.org:/cvs import ports/lang/kaffe1 username username_yyyymmdd


    username est votre nom de compte utilisateur, et yyyymmdd est la date actuelle. Si cela réussit, alors vous pouvez supprimer l'option -n pour importer vraiment. Votre éditeur sera invoqué pour que vous puissiez entrer un message de validation. Dans le message de commit, indiquez au moins ce que vous importez et quels développeurs ont donné leur accord. Assurez-vous que le chemin d'import soit correct ; il débute toujours par ports/. Alternativement, vous pouvez utiliser ports/infrastructure/bin/portimport pour importer de nouveaux ports (lisez le manuel pour les instructions d'utilisation).

  34. Dernier point mais non des moindres, ajoutez une entrée sur une ligne pour le nouveau port dans le Makefile du répertoire parent, par ex., pour ports/lang/kaffe1, ajoutez-le à ports/lang/Makefile. Ne pas oubliez de diffuser tout changement fait à /usr/ports/infrastructure/db/user.list.
  35. Maintenez le port ! Avec le temps, des problèmes peuvent apparaitre, ou de nouvelles version du logiciel peuvent être publiées. Vous devriez vous efforcer de maintenir à jour votre port. En d'autres termes - itérez, testez, testez, itérez …
  36. Quand vous mettez à jour un port, rappelez-vous de gérer les dépendances! Vous ne devriez pas casser un port qui dépend du vôtre. En cas de problèmes, communiquez avec les responsables de tels ports. De même, soyez vigilant sur les mises à jour des dépendances et vérifiez que le responsable ait fait son travail.

Gestion de situations complexes

Supposons que vous avez réussi à construire le logiciel, à fournir les correctifs requis et que vous voulez terminer le portage.

Connaître le logiciel

Identifier les options

La première étape est habituellement d'identifier les options de compilation. Vous devrez souvent lire le journal de configuration, voir ce que votre port détecte automatiquement. Lisez les options du script configure. Lisez la documentation du port pour plus d'informations.

Faire en sorte que les options fonctionnent

Recompilez votre port avec différentes options. Installez les dépendances supplémentaires. Assurez-vous que votre port les détecte correctement. Ajouter les correctifs supplémentaires pour vous assurer de la compilation. Testez le résultat, et vérifiez que les choses supplémentaires fonctionnent.

Identifier les logiciels oubliés.

Certaines dépendances ne seront pas satisfaites car le logiciel manquant n'a pas encore été porté. Il est hautement recommandé de désactiver explicitement ces options. Ne pas faire cela provoque régulièrement des échecs de compilations groupées : une personne porte un nouveau logiciel et l'importe, et peu de temps après, d'anciens ports s'arrêtent de compiler parce qu'ils détectent la dépendance, essayent de l'utiliser, et sont en échec de compilation ou d'empaquetage.

Contrôler les dépendances d'exécution par rapport aux dépendances de génération

Mettez à jour votre liste d'empaquetage avec make plist. Utilisez make port-lib-depends-check pour voir quelles bibliothèques a besoin votre logiciel (qui finira dans LIB_DEPENDS ou WANTLIB, habituellement). Identifiez les nombreux fichiers et binaires dans les dépendances qui doivent être présents pour que le port fonctionne.

À ce stade, vous devriez avoir une bonne compréhension de comment fonctionne votre port.

Déterminer les options importantes

Ne vous souciez pas de certaines options. Cela n'a pas de sens de désactiver certaines choses si elles fonctionnent toujours, et si les dépendances sont assez petites. Prenez spécialement notes des licences sur les dépendances, spécifiquement à-propos des PERMIT*. En règle générale, même si une dépendance est très petite, si elle affecte la licence du package résultant, vous devez y faire explicitement attention.

Considérant toutes les options possibles, vous devriez avoir un ensemble beaucoup plus petit d'options pour votre port, essentiellement en fonction des packages nécéssaires pour exécuter le logiciel. Dans l'immédiat, ne vous inquiétez pas des dépendances de compilation. Souvenez-vous que le système de ports OpenBSD est centré sur l'utilisateur final, que l'utilisateur final voudra installer des packages binaires, donc peu importe que vous ayez besoin d'une énorme quantité de logiciels pour construire votre port si ceux ci n'apparaissent pas comme des bibliothèques ou des dépendances d'exécution.

Le cas idéal : ''MULTI_PACKAGES'' et ''PSEUDO_FLAVORS''

Maintenant, vous devriez avoir une très bonne idée de :

  • quels nouveaux fichiers apparaissent quand vous activez chaque option
  • quels bibliothèques et/ou fichiers d'exécutions sont nécessaires quand vous activez chaque option

Dans le cas idéal, les options de compilation créeront simplement de nouveaux fichiers, avec de nouvelles dépendances, et n'affecteront pas d'autres choses. C'est un scenario assez courant pour les frameworks de plugins : vous ajoutez une librairie, vous obtenez un nouveau plugin. Ceci arrive assez souvent pour les applications centrales avec une interface graphique : l'application console est compilée chaque fois, et l'interface X11 apparaît en tant que binaire séparé.

Dans ce cas, essayez de paramétrer la variable MULTI_PACKAGES pour lister les packages -sub, ajouter les COMMENTS correspondants, et regarder votre empaquetage. Basiquement, MULTI_PACKAGES affecte seulement l'empaquetage. Si vous avez MULTI_PACKAGES=-s1 -s2, tout ce qui relève du package existera en deux variantes : COMMENT-s1 pour le premier package, COMMENT-s2 pour le second package, PLIST-s1, PLIST-s2, DESCR-s1, DESCR-s2. Vous avez besoin d'écrire COMMENT-s1 et COMMENT-s2 dans le Makefile, de découper votre PLIST en deux parties, et de créer DESCR-s1/DESCR-s2. Vous avez aussi besoin de spécifier des PKGNAME séparés pour tous les sous-paquets.

C'est une bonne idée de commencer le travail requis avec un framework minimal : copiez simplement la description et les commentaires existants, parce que vous avez besoin de triturer MULTI_PACKAGES et d'autres choses, avant d'affiner cela.

Une fois que vous avez séparé les fichiers proprement, vous avez besoin de vérifier les dépendances : LIB_DEPENDS, WANTLIB, et RUN_DEPENDS seront fractionnés pour chaque sous-paquet. C'est généralement le moment de vérifier que votre empaquetage multiple “fonctionne”, et que ces dépendances désagréables qui ne devraient pas s'imposer à l'utilisateur soient reléguées à un sous-paquet spécifique.

Si cela fonctionne, vous avez presque fini. Il suffit de choisir des noms raisonnables pour les différents paquets, et de remplir les commentaires et les descriptions. L'utilisateur final sera capable d'installer simplement le(s) package(s) désiré(s).

Mais, attendez. Qu'en est-il de la compilation ? Eh bien, avoir beaucoup de dépendances durant la compilation n'est pas un problème. La plupart des packages sont construits par l'équipe d'OpenBSD en utilisant des procédures de compilations spéciales (connues en tant que bulk builds) où un développeur compile simplement tous les packages possibles sur une machine dédiée (ou sur plusieurs, pour les architectures lentes). Puisque tout sera compilé, avoir de lourdes dépendances n'est pas un problème. Compiler la même chose plusieurs fois est un problème, c'est pourquoi MULTI_PACKAGES est la meilleure manière de gérer les options (quand cela est possible) : une compilation, un ensemble de paquets à tester, une meilleure qualité par dessus tout…

Si vous souhaitez aider des personnes à compiler elles-mêmes des packages, vous pouvez considérer l'ajout de PSEUDO_FLAVORS. Une pseudo-saveur est une manière de modifier une option (disons, désactiver l'interface graphique), ce qui est très similaire aux saveurs normales. Dans les faits, la grande différence est une différence fonctionnelle : une pseudo saveur ne devrait affecter seulement que l'ensemble de packages qu'elle a compilé, mais il ne lui est jamais permis de modifier le contenu de l'actuel package.

Par exemple, en considérant que vous avez séparé l'interface graphique dans un sous-paquet séparé (MULTI_PACKAGES=-core -x11), vous devriez créer une pseudo saveur no_x11 qui évite de compiler le sous-package -x11. Le point crucial est que cette saveur N'affectera PAS le package -core de quelque manière que ce soit.

Vous finiriez avec un Makefile qui ressemblerait à cela :

  CATEGORIES = app
  COMMENT-core = foo core application
  COMMENT-x11 = foo graphical interface
  V = 1.0
  DISTNAME = foo-1.0
  PKGNAME-core = foo-core-$V
  PKGNAME-x11 = foo-x11-$V
  PSEUDO_FLAVORS = no_x11
  FLAVOR ?=
  CONFIGURE_STYLE = gnu
  
  MULTI_PACKAGES = -core
  WANTLIB = c m crypto ssl
  WANTLIB-x11 = ${WANTLIB} X11 Xt
  RUN_DEPENDS-x11 = ::${BASE_PKGPATH},-core
  
  .if ${FLAVOR:L:Mno_x11}
  CONFIGURE_ARGS += --disable-x11
  .else
  MULTI_PACKAGES += -x11
  .endif
   
  .include <bsd.port.mk>

Notez que vous n'avez qu'à écrire une toute petite section conditionnelle dans le Makefile : le système ne se soucie pas du tout que vous définissiez des variables supplémentaires.

Interdépendances entre sous-paquets

Les paramétrages MULTI_PACKAGES étaient autrefois asymétriques, avec un sous-package -main et d'autres sous-packages, le sous-package -main était toujours construit, et éventuellement les sous-packages dépendants de lui. La situation actuelle est totalement symétrique : tout sous-package peut dépendre d'un autre. L'infrastructure a des dispositions spécifiquers pour éviter de boucler indéfiniment.

L'infrastructure accorde un soin particulier aux bibliothèques inter-dépendantes : elle peut détecter quel WANTLIB vient de dépendances externes, et lequel vient d'inter-dépendances. Tandis que les bibliothèques externes LIB_DEPENDS et WANTLIB sont vérifiées au démarrage de la compilation, les LIB_DEPENDS et WANTLIB qui se référent à un des sous-packages en cours de compilation, seront seulement vérifiées au moment de l'empaquettage (et ainsi, ces packages peuvent être créés dans un ordre spécifique pour satisfaire l'inter-dépendance).

L'infrastructure fournit des variables spécifiques pour aider à écrire les inter-dépendances : BUILD_PKGPATH contient le PKGPATH utilisé durant la compilation des packages en question, prenant en compte les saveurs et pseudo-saveurs. Il est fortement recommandé d'utiliser cette variable au lieu de votre solution personnelle : ne pas respecter celà déclenchera souvent des reconstructions dans des situations de saveurs intéressantes. Par exemple :

  ...
  FLAVORS = a b
  FLAVOR ?=
  MULTI_PACKAGES = -p1 -p2
  WANTLIB-p1 = foo
  LIB_DEPENDS-p1 = some/pkgpath,-p2
  ...

Si vous continuez et compilez via un/quelconque/pkgpath avec FLAVOR=a, alors créez le sous-paquet pour -p1 déclenchera une reconstruction avec FLAVOR=''. Écrivez plutôt cela :

  LIB_DEPENDS-p1 = ${BUILD_PKGPATH},-p2

Il y a aussi une variable BASE_PKGPATH, qui ne prend pas en compte les pseudo-saveurs. Cette variable a une applicabilité limitée : elle correspond à une transition entre les anciens MULTI_PACKAGES et les plus récents, où l'ancien sous-paquet principal n'avait pas de marqueur dans son chemin d'accès, et donc le paquet correspondant nécessite un chemin d'accès @pkg ${BASE_PKGPATH} dans sa liste d’empaquetage. (En général, les pseudo-saveurs sont des informations de compilation, et ne devraient pas se retrouver dans les packages et les listes d'empaquetage).

Véritables ''FLAVORS'' et ''PKGNAMES''

Il y a certains cas où les options de configuration sont trop invasives, et vous devrez ajouter de vraies saveurs au Makefile : ces saveurs commanderont certaines options de configuration, et habituellement des ajouts à de diverses dépendances. Notez que le nommage de paquets est souvent automatique : le PKGNAME aura une extension construite par ajout des saveurs spécifiées à son nom. Ainsi, si :

  PKGNAME = foo-1.0
  FLAVORS = f1 f2 f3

et que vous construisez le port avec FLAVOR='f3 f1', alors FULLPKGNAME=foo-1.0-f1-f3 (FLAVORS est utilisée pour réordonner les saveurs spécifiées d'une manière canonique).

Il y a parfois des situations mélangées, où certains packages dépendent de FLAVOR, et d'autres non. Par exemple, certains ports incluent un large ensemble de documentations qui ne dépend pas de FLAVOR, et quelques programmes actuels qui dépendent de FLAVOR. Dans de tels cas, vous pouvez spécifier FULLPKGNAME explicitement pour le sous-paquet de documentation. Quelque chose comme :

  CATEGORIES = app
  COMMENT-core = foo application
  COMMENT-doc = foo documentation
  V = 1.0
  DISTNAME = foo-1.0
  PKGNAME-core = foo-$V
  FULLPKGNAME-doc = foo-doc-$V
  FLAVORS = crypto
  
  MULTI_PACKAGES = -core -doc
  WANTLIB-core = c m
  
  .if ${FLAVOR:L:Mcrypto}
  WANTLIB-core += ssl crypto
  CONFIGURE_ARGS += --enable-crypto
  .endif

Tel que mentionnée dans la documentation, tous les noms de packages ont la même structure : stem-version-flavor_extension.

Par défaut, les packages avec la même stem, and update paths will look at candidates with the same stem. Le bon package sera celui venant de l'identique exact PKGPATH, ou correspondant à l'annotation @pkgpath dans la liste d'empaquetage.

Habituellement, MULTI_PACKAGES ne devraient pas être en conflit, puisqu'ils doivent avoir des noms différents (et l'infrastructure n'a aucun moyen de construire ces noms). D'un autre côté, les saveurs devraient être en conflit, puisqu'elles ont le même nom. L'information de saveur devrait être à la fin du nom de package, exceptée pour les pseudo-saveurs, ce qui ne change pas la manière dont un package est compilé.

En ce qui concerne les dépendances, par défaut, spécifier un PKGPATH créera juste une dépendance stem-*, ce qui signifie que tout paquet avec la bonne stem correspondra à la dépendance. Par défaut, toute saveur correspondra. Si seules des saveurs spécifiques sont désirées, vous devez les inclure dans votre spécification, ex., stem-*-flavor. Si certaines saveurs ne sont pas recherchées, vous pouvez les supprimer de la correspondance des packages, ex., stem-*-!flavor.

Depuis OpenBSD 4.9, demander au moins une certaine version de dépendance peut être directement adressé à PKGPATH, ex., dir/foo>=2.0.

Mettre à jour les ports

Les outils des packages peuvent subir des mises à jours, ainsi les mainteneurs doivent faire attention à ce simple fait : les mises à jours ne sont pas instantanées. Même si un utilisateur passe juste d'une version à l'autre, chaque fois, qu'il exécute pkg_add -u, le système remplacera chaque package par une nouvelle version, un paquet à la fois. Ainsi l'utilisateur exécutera un système mélangé, même si cela est juste pour quelques minutes.

Il y a fondamentalement deux modèles de mises à jours dont les mainteneurs doivent être au courant.

  • Certains utilisateurs suivent current sans grande rigueur. Ils mettent à jour leurs packages tous les jours ou toutes les semaines. Soit tous les packages, soit seulement certains packages sélectionnés. Le mécanisme de mise à jour devrait fonctionner pour eux : il peut les forcer à mettre à jour certains packages spécifiques, ou installer de nouvelles choses, mais il ne devrait pas se mettre en erreur de manière silencieuse. Les micro-mises à jour devraient être testées. Ces utilisateurs seront souvent capables de faire face à de petits changements, tels que des changements de nom de programme, ou des ajustements de configuration.
  • Certains utilisateurs mettent à jour tous les six mois lors d'une nouvelle version. Ils téléchargeront ainsi les mises à jour stables (les mises à jour de sécurité et critiques). Durant six mois, une grande partie de l'arborescence des ports change. Ces utilisateurs ne se soucient pas des changements individuels de logiciel. Ils veulent juste un système qui fonctionne. Changer les noms des binaires est complétement inamical pour ces utilisateurs. Modifier des centaines de configuration de fichiers sera une grande souffrance pour eux. Les mainteneurs peuvent aider en fournissant des guides de mise à jour fluides et des conseils importants chaque fois que quelque chose d'important change.

Notez qu'une partie du processus de mise à jour, en particulier les modifications macroscopiques pour les utilisateurs qui mettent à jour tous les six mois, n'est pas encore automatisée. Le mécanisme global de mise à jour est toujours en cours d'élaboration et pkg_add sera en mesure de faire face à d'autres problèmes à l'avenir. Pour l'instant, vous devriez vous concentrer sur le fait que le système fasse ses mises à jour à correctement, un port à la fois, et que la mise à jour d'un port tient compte des autres ports, en ce qui concerne les conflits et autres problèmes.

Mettre à jour la liste de vérification

Une partie du travail doit être effectuée lors de la réalisation du port lui-même.

  • Assurez-vous que les auteurs du logiciel soient informés de vos réglages pour qu'il fonctionne sur OpenBSD. Vous devez vous efforcer d'obtenir les correctifs d'OpenBSD dans la prochaine version du logiciel. Autrement, vous pouvez vous préparer à réécrire la plupart de vos correctifs de zéro à chaque version.
  • Assurez-vous que les auteurs du logiciel comprennent la numérotation de version. Si les fichiers distfiles ne contiennent aucun numéro de version, ou s'ils référencent le travail en cours, communiquez avec les auteurs pour obtenir des URL permanentes.
  • Documentez les solutions de contournement. Cela vous aidera à vous rappeler de vérifier si elles sont toujours nécessaires quand vous essaierez de mettre à jour le port.
  • Documentez les dépendances, en particulier celles que vous n'utilisez pas. Certains ports peuvent utiliser un logiciel externe qui peut ne pas être disponible au moment du port. Assurez-vous de ne pas le sélectionner, de le documenter, ainsi vous pourrez mettre à jour votre port quand ce logiciel sera disponible plus tard.
  • Si le port utilise libtool, copiez ses journaux à l'identique depuis le fichier ${WRKBUILD}/shared_libs.log comme base de votre paramétrage SHARED_LIBS. Cela aidera lors des mises à jour.
  • Utilisez PLIST_DB et construisez une base de données des listes d'empaquetage. Cela est utile pour trouver les noms de packages oubliés, et aussi pour vérifier les conflits avec d'anciens packages.
  • Assurez-vous que les dépendances restent souples autant qu'elles peuvent l'être. Par défaut, RUN_ et LIB_DEPENDS peuvent être satisfaits par n'importe qu'elle version d'un package. N'insistez pas sur une version donnée sauf si vous le devez. Utilisez les versions minimales autant que possible.

Les ports ont souvent besoin de mises à jour mineures sans nouvelle version en amont.

  • Chaque mise à jour de port nécessite un changement de nom de paquet. Autrement, le mécanisme de mise à jour pour les packages binaires ne peut fonctionner. Tout ce qui affecte un package binaire implique un changement. Cela inclut les changements de HOMEPAGE, MAINTAINER ou de description.
  • Les numéros de version vont toujours de l'avant. Si quelque chose d'inattendu se produit, et que vous devez revenir en arrière, ou si la numérotation change complètement au point que le numéro de version semble régresser, vous devez utiliser EPOCH pour vous assurer que pkg_add(1) voit le paquet comme un paquet plus récent.
  • Si le package ne compile pas, aucun changement n'est nécessaire : les modifications visant à rétablir l'état de fonctionnement d'un port après qu'il ait été cassé ne justifient pas de changement de version.
  • Les modifications pour s'assurer qu'un port choisit/ne choisit pas une dépendance externe justifient un changement.
  • Les changements dans les dépendances n'affectent pas généralement un numéro de version d'un port. Le système d'empaquetage utilise un mécanisme de signature tel qu'un package binaire est entièrement identifié par ses noms de package, plus les dépendances par rapport auxquelles il a été compilé, plus les numéros de version de toutes les bibliothèques partagées qu'il contient.

Une partie du travail aura lieu avant la mise à jour elle-même.

  • exécutez make patch pour avoir une copie initiale du port avant la mise à jour.

Et, ensuite la mise à jour

  • Éditez le Makefile du port pour récupérer la nouvelle version, exécutez make makesum et make patch comme base de départ.
  • Une fois que vous avez fixé les correctifs défaillants, exécutez un diff complet entre l'ancienne et la nouvelle version pour déterminer exactement ce qui a changé. Prenez des notes, soyez prêt à revoir les choses plus tard.
  • Faites le nécessaire pour que le port fonctionne afin d'obtenir une nouvelle version à exécuter sous OpenBSD : ajuster les dépendances, changer le contenu d'un package, etc.
  • Vérifiez par deux fois les versions des bibliothèques partagées. Pour les ports basés sur libtool, vous avez le journal shared_libs.log pour vérifier ce que les auteurs du logiciels ont fait comme changements significatifs. Notez bien que cela ne suffit pas. La plupart des auteurs de logiciel ne comprennent pas réellement les problèmes de bibliothèques partagées. Vous devez lire le diff complet entre l'ancienne et la nouvelle version, et incrémenter les versions de librairies en fonction. En cas de doute, incrémenter la version.
  • Soyez attentif aux conflits avec les packages déjà compilés. Rien ne doit être fait pour de simples mises à jour. Si vous découpez un package en plusieurs sous-packages, assurez-vous que les sous-paquets aient leurs propres annotations de conflits : ils devraient généralement entrer en conflit avec l'“ancien” paquet de base.
  • Aidez l'utilisateur. Si certaines étapes spécifiques doivent être prises au-delà de pkg_add -u, assurez-vous qu'elles soient visibles. Quand votre politique d'empaquetage change, documentez-la dans la description du package. Par exemple, si vous déplacez la documentation dans un package séparé pour des contraintes d'espace, la description du package principal devra mentionner que la documentation est maintenant disponible dans un package séparé.

Commit des mises à jour du port

Quand une mise à jour du port est prête, mettez-la dans CVS. Si vous n'avez pas de compte CVS, alors vous devrez trouver un développeur pour faire cela pour vous (demandez sur ports@openbsd.org).

  1. Obtenez au moins un “OK” par un autre développeur de port.
  2. Utilisez cvs add pour ajouter les nouveaux fichiers.
  3. Utilisez cvs rm pour supprimer les fichiers qui n'ont plus besoin d'y être (ex. les patches ayant été acceptés en amont).
  4. Vérifiez la sortie de cvs -n up -d. Les nouveaux fichiers devraient être marqués A, les fichiers effacés devraient être marqués D et les fichiers changés devraient être marqués M. Cherchez les fichiers marqués ? - souhaitiez-vous les cvs add ?
  5. Si tout est bon, validez les fichiers nouveaux/effacés/modifiés en utilisant cvs commit. Lorsque vous invoquez cvs commit, vous pouvez soit lister les fichiers individuellement, ou si vous ne fournissez aucun nom de fichier, CVS les validera récursivement (faites attention avec cette fonctionnalité). Il vous sera demandé d'entrer un message de validation, dans lequel vous devrez indiquer quel port est mis à jour, et qui a fourni un OK.

OpenBSD Politique de Portage

  • OpenBSD N'utilise PAS /usr/local/etc/rc.d. /usr/local est souvent partagé entre plusieurs machines, grâce à NFS. Pour cette raison, les fichiers de configuration qui sont spécifiques à une machine donnée ne peuvent être enregistrés sous /usr/local. /etc est le dépôt central pour les fichiers de configuration par machine. De plus, la politique d'OpenBSD est de ne jamais mettre à jour les fichiers sous /etc automatiquement. Les ports qui ont besoin d'une configuration de démarrage spécifique doivent avertir l'administrateur ce qu'il doit faire au lieu d'installer aveuglément des fichiers.
  • OpenBSD NE compresse PAS les pages de manuel.
  • OpenBSD NE requiert PAS -lcrypt, -ldl, ou -lrt. Les fonctions fournies par ces bibliothèques sont une partie de libc. La fonction crypt() ne supporte pas DES, seulement bcrypt.
  • OpenBSD a un espace de noms séparé pour les utilisateurs et les groupes créés par les ports. Lisez /usr/ports/infrastructure/db/user.list pour les détails.
  • OpenBSD est fortement orienté sécurité. Vous devrez lire et comprendre la section sécurité de cette page.
  • Assurez d'ajouter l'étiquette CVS $OpenBSD$ au Makefile. Le nom du compte, le numéro de version, etc, sera rempli automatiquement par CVS durant le commit.
  • Le but est d'obtenir que toutes les applications portées supportent OpenBSD. Pour atteindre ce but, vous devez fournir tout correctif OpenBSD au responsable de l'application.

Recommandations de Sécurité

Il y a de nombreux problèmes de sécurité à prendre en compte. Si vous n'êtes pas absolument sûr de ce que vous faites, veuillez demander de l'aide sur la liste de diffusion des ports.

  • Ne pas utiliser de code alpha ou beta lors de la préparation du port. Utilisez la dernière version standard ou le dernier correctif.
  • Tout logiciel qui doit être installé en tant que serveur doit être analysé pour détecter les débordements de tampons, en particulier l'utilisation dangereuse de strcat/strcpy/strcmp/sprintf. En général, sprintf doit être remplacé par snprintf.
  • N'utilisez jamais les noms de fichier en tant que véritable sécurité. Il y a de nombreuses situations de course où vous n'avez pas le contrôle approprié. Par exemple, un attaquant qui a déjà des privilèges utilisateur sur vos machines peut remplacer les fichiers dans /tmp par des liens symboliques vers des fichiers plus stratégiques, tels que /etc/master.passwd.
  • Par exemple, fopen et freopen créent un nouveau fichier ou ouvrent un fichier existant pour écrire. Un attaquant peut créer un lien symbolique depuis /etc/master.passwd vers /tmp/addrpool_dump. À l'instant où vous l'ouvrez, votre fichier de mot de passe est foutu. Oui, même avec un unlink juste avant. Vous réduisez seulement la fenêtre d'opportunité. Utilisez open avec O_CREAT|O_EXCL et fdopen à la place.
  • Un autre problème très commun est la fonction mktemp. Respecter les avertissements du linker bsd concernant ses utilisations. Celles-ci doivent être fixées. Ce n'est pas aussi simple que s/mktemp/mkstemp/g. Reférez-vous à mktemp(3) pour plus d'informations. Des exemples d'usages corrects de mkstemp incluent le code source de ed ou mail. Un exemple rare de code qui utilise mktemp correctement peut être trouvé dans le port rsync.
  • Juste parce que vous pouvez le lire ne signifie pas que vous le devriez. Un trou bien connu de cette nature était le problème startx. En tant que programme setuid, vous pouvez lancer startx avec n'importe quel fichier en tant que script. Si le fichier n'était pas un script shell valide, un message d'erreur de syntaxe suivrait, ainsi que la première ligne du fichier incriminé, sans autre vérification d'autorisation. Assez pratique pour attraper la première ligne d'un fichier shadow passwd, étant donné que ceux-ci commencent souvent par l'entrée root. N'ouvrez pas votre fichier, pour ensuite faire un fstat sur le descripteur ouvert pour vérifier si vous auriez dû pouvoir l'ouvrir (ou l'attaquant jouera avec /dev/rst0 et rembobinera votre enregistrement sur bande). – ouvrez le avec l'ensemble correct uid/gid/grouplist.
  • N'utilisez rien qui fork un shell dans les programmes setuid avant de supprimer vos privilèges. Cela inclut popen et system. Utilisez fork, pipe et execve à la place.
  • Passez les descripteurs ouverts au lieu des noms de fichiers à d'autres programmes pour éviter les situations de course. Même si un programme n'accepte pas les descripteurs de fichiers, vous pouvez toujours utiliser /dev/fd/0.
  • Les droits d'accès sont attachés au descripteur de fichier. Si vous avez besoin des droits setuid pour ouvrir un fichier, ouvrez ce fichier, puis supprimez vos privilèges. Vous pouvez toujours accéder au descripteur ouvert, mais vous avez moins à vous soucier à ce propos. C'est à double tranchant : même après avoir abandonné les privilèges, vous devriez quand même faire attention à ces descripteurs.
  • Évitez root setuid autant que possible. En fait, root peut tout faire, mais les droits root sont très rarement nécessaires, excepté peut être pour créer des sockets de ports avec un numéro inférieur à 1024. Vous devez connaître la magie appropriée pour écrire des démons afin d'y parvenir. Il pourrait être argumenté que vous n'avez pas à écrire des programmes setuid si vous ne savez pas comment le faire.
  • Utilisez setgid au lieu de setuid. Hormis quelques fichiers spécifiques nécessaires aux programmes setgid, la plupart des fichiers n'ont pas les droits en écriture pour les groupes. De fait, un problème de sécurité dans un programme setgid ne compromettra pas autant votre système : avec seulement des droits de groupe, le pire qu'un intrus puisse faire est de pirater les meilleurs scores d'un jeu ou ce genre de chose. Voyez le port xkobo comme exemple d'un tel changement.
  • Ne faites pas confiance aux fichiers ayant des droits en écriture pour les groupes. Même s'ils sont audités, les programmes setgid ne sont pas perçus comme de potentiels et importants trous de sécurité. Par conséquent ce qu'ils peuvent manipuler ne doit pas être considéré comme information sensible.
  • Ne faites pas confiance à votre environnement ! Cela implique des choses simples comme votre PATH (ne jamais utiliser system avec un nom non qualifié, éviter execvp), mais aussi des éléments plus subtils comme votre locale, fuseau horaire, termcap, etc. Soyez conscient de la transitivité : même si vous prenez toutes les précautions nécessaires, les programmes que vous appelez directement ne le feront pas nécessairement. Ne jamais utiliser system dans des programmes privilégiés, aménagez votre propre ligne de commande, un environnement contrôlé, et appelez directement execve. La page de manuel perlsec est un bon tutoriel concernant de tels problèmes.
  • Ne jamais utiliser des scripts shell setuid. Ils sont fondamentalement non sûrs. Enveloppez les dans du code C ce qui assure un environnement sain. D'un autre côté, OpenBSD propose des scripts perl sécurisés.
  • Attention au chargeur dynamique. Si vous exécuter setuid, il utilisera seulement des bibliothèques de confiance qui ont été analysées avec ldconfig. Setgid n'est pas suffisant.
  • Les bibliothèques dynamiques sont délicates. Le code C++ pose un problème similaire. Fondamentalement, les bibliothèques peuvent prendre certaines mesures en fonction de votre environnement avant même que votre programme principal puisse vérifier son statuts setuid. issetugid d'OpenBSD résout ce problème, du point de vue de l'auteur de la bibliothèque. N'essayez pas de porter des bibliothèques sauf si vous comprenez bien ce problème.
  • Sur OpenBSD, rand(3), random(3) et la famille drand48(3) retourne des nombres aléatoires non déterministes par défaut. Toute valeur de graine spécifiée est ignorée par la fonction de graine associée, et arc4random est utilisée à la place. Si le comportement déterministe (c-à-d, répétable) doit être préservé, utilisez les extensions d'OpenBSD : srand_deterministic, srandom_deterministic, srand48_deterministic, seed48_deterministic et lcong48_deterministic.

Conseils génériques de portage

  • __OpenBSD__ devrait être utilisé avec parcimonie, voir pas du tout. Les tournures de ce type
    #if defined(__NetBSD__) || defined(__FreeBSD__) 

    sont souvent inappropriées. N'ajoutez pas aveuglément __OpenBSD__. Au lieu de cela, essayez de comprendre ce qui se passe, et quelle fonctionnalité est réellement nécessaire. Les pages de manuel sont souvent utiles, car elles incluent des commentaires historiques, indiquant quand une fonctionnalité particulière a été incorporée dans BSD. Vérifiez la valeur numérique de BSD par rapport aux versions connues est souvent la bonne manière. Lisez le guide pkgsrc de NetBSD pour plus d'informations.

  • Définir BSD est une mauvaise idée. Essayez d'inclure sys/param.h. Cela ne définit pas seulement BSD, cela donne aussi une valeur appropriée. Le bon fragment de code devrait ressembler à ceci :
        #if (defined(__unix__) || defined(unix)) && !defined(USG)
        #include <sys/param.h>
        #endif
  • Testez les fonctionnalités, pas par rapport aux OS spécifiques. A long terme, il est bien mieux de tester si tcgetattr fonctionne que de tester si vous utilisez BSD 4.3 ou une version ultérieure, ou SystemVR4. Ce genre de tests ne font qu'embrouiller le problème. La bonne manière de faire cela est, par exemple, de tester pour un système particulier, définissez une série de HAVE_TCGETATTR, puis passez au système suivant. Cette technique sépare les fonctionnalités de tests selon les OS spécifiques. En toute hâte, un autre porteur peut simplement ajouter l'ensemble des définitions -DHAVE_XXX dans le Makefile. Un autre peut aussi écrire ou ajouter un script configure pour surveiller si cette fonctionnalité est requise puis l'ajouter automatiquement. Comme exemple à ne pas suivre, jetez un œil aux sources de nethack 3.2.2 : il considère acquises beaucoup de choses selon le type du système. La plupart de ces hypothèses sont obsolètes et ne reflètent plus la réalité : les fonctions POSIX sont plus utiles que ce qui différencie la vieille BSD de SystemV, au point que certaines fonctions bsd traditionnelles ne sont plus supportées que par les bibliothèques de compatibilité.
  • Évitez d'inclure des fichiers qui en incluent d'autres qui en incluent… Premièrement, parce que c'est inefficace. Votre projet finira par inclure un fichier qui inclue tout. De plus, parce que cela pose quelques problèmes difficiles à corriger. Au bout d'un moment, il devient plus difficile de ne pas inclure un fichier particulier.
  • Évitez les astuces de macro bizarres. Défaire une macro qui a été définie par un fichier entête est une mauvaise idée. Définir des macros pour avoir certains comportements spécifiques depuis un fichier inclut est aussi une mauvaise idée : les modes de compilation devraient être globaux. Si vous voulez un comportement POSIX, dites-le par #define POSIX_C_SOURCE à travers tout le projet, et non pas quand vous en avez envie.
  • N'écrivez jamais des prototypes de fonctions systèmes. Tous les systèmes modernes, OpenBSD inclus, ont un endroit standard pour ces prototypes. Parmi les endroits possibles, citons unistd.h, fcntl.h ou termios.h. La page de manuel indique fréquemment où ces prototypes peuvent être trouvés. Vous pourriez avoir besoin d'une autre série de macros HAVE_XXX pour obtenir le bon fichier. Ne vous inquiétez pas d'inclure deux fois le même fichier : les fichiers à inclure ont des gardes qui empêchent toutes sortes de drame. Si un système mal conçu a besoin que vous écriviez le prototype, ne l'imposez pas à tous les autres systèmes. Les prototypes faits-maison casseront parce qu'ils peuvent utiliser des types équivalents sur votre système, mais ne sont pas portables avec d'autres systèmes (unsigned long au lieu de size_t), ou traiteront un status const de la mauvaise manière. De plus, certains compilateurs, comme le gcc d'OpenBSD, sont capables de faire un meilleur travail avec des fonctions très fréquentes comme strlen si vous incluez le bon fichier d'entête.
  • Vérifiez soigneusement le journal de compilation pour tout avertissement du compilateur.
    • implicit declaration of function foo() indique qu'un prototype de fonction est manquant. Cela signifie que le compilateur supposera que le type de retour soit un entier. Lorsque la fonction renvoie un pointeur, sur les plates-formes 64 bits il est tronqué, ce qui provoque généralement un erreur de segmentation.
  • N'utilisez pas le nom d'une fonction système standard pour autre chose. Si vous voulez écrire votre propre fonction, donnez-lui son propre nom, et appelez cette fonction partout. Si vous souhaitez revenir à la fonction système par défaut, il vous suffit de commenter votre code et de définir votre propre nom pour la fonction système. Ne faites pas l'inverse. Le code devrait ressembler à cela :
        /* prototype part */
        #ifdef USE_OWN_GCVT
        char *foo_gcvt(double number, size_t ndigit, char *buf);
        #else
        /* include correct file */
        #include <stdlib.h>
        /* use system function */
        #define foo_gcvt  gcvt
        #endif
        
        /* definition part */
        #ifdef USE_OWN_GCVT
        char *foo_gcvt(double number, size_t ndigit, char *buf)
           {
           /* proper definition */
           }
        
        /* typical use */
        s = foo_gcvt(n, 15, b);

Autres conseils utiles

  • Les versions récentes de bsd.port.mk paramètrent le chemin de l'installeur. Spécifiquement, elles font en sorte que /usr/bin et /bin soient parcourus avant /usr/local/bin et /usr/X11R6/bin.
  • Il est correct de s'appuyer sur une fonctionnalité apparue dans une version récente de bsd.port.mk, car les personnes sont supposées mettre à jour en entier leur arborescence des ports, ce qui inclut bsd.port.mk.
  • Préférez l'usage de update-plist pour générer et mettre à jour les listes d'empaquetage au lieu de faire les choses manuellement. Vous pouvez commenter les lignes non désirées. Le fichier update-plist peut détecter la plupart des types de fichier et copier correctement la plupart des annotations supplémentaires.
  • Dans OpenBSD, curses.h/libcurses/libtermlib sont les “nouvelles curses”. Changez :
    ncurses.h ==> curses.h 


    Les “anciennes (BSD) curses” sont disponible en définissant _USE_OLD_CURSES_ avant d'inclure curses.h (habituellement dans Makefile) et avant de lier avec -locurses.

  • Dans OpenBSD, l'hygiène du terminal a été mise à niveau de l'ancien sgtty BSD vers la nouvelle famille POSIX tcgetattr. Évitez l'ancien style dans le nouveau code. Certains codes peuvent définir tcgetattr comme étant synonyme de l'ancien sgtty, mais c'est au mieux une mesure stopgap sur OpenBSD. Le code source de xterm est un très bon exemple de ce qu'il ne faut pas faire. Essayez de gérer la fonctionnalité de votre système correctement : il vous faut un type qui retienne l'état de votre terminal (éventuellement typedef), il vous faut une fonction qui extrait l'état actuel, et une fonction qui définit le nouvel état. Les fonctions qui modifient cet état sont plus difficiles, car elles ont tendance à varier selon le système. De même, n'oubliez pas que vous avez à gérer des cas où vous ne serez pas connecté à un terminal, et que vous avez besoin de capturer les signaux : pas seulement la terminaison, mais aussi l'arrière plan (SIGTSTP). Vous devriez toujours garder le terminal dans un état sain. Faites vos tests sous un ancien shell, tel que sh, qui ne réinitialisera pas le terminal à la sortie du programme.
  • Les récents termcap/terminfo et curses, fournies avec OpenBSD, incluent les séquences standard pour contrôler les couleurs de terminaux. Vous devriez utiliser celles-ci si possible, en revenant aux séquences de couleurs ANSI standard sur d'autres systèmes. Toutefois, certaines descriptions de terminal n'ont pas été encore mises à jour, et et il vous faudra être capable de spécifier ces séquences manuellement. C'est la manière dont Vim le gère. Ce n'est strictement pas nécessaire. Excepté pour les programmes privilégiés, il est généralement possible de surcharger une définition termcap grâce à la variable TERMCAP et faire en sorte que cela fonctionne proprement.
  • La sémantique de signal est délicate, et varie d'un système à l'autre. Utilisez sigaction pour vous assurer des sémantiques spécifiques, ainsi que des autres appels mentionnés dans la page de manuel correspondante.

Informations supplémentaires

  • La page de manuel de bsd.port.mk(5). Elle documente le Makefile de l'infrastructure des ports qui est inclus à la fin du makefile de chaque port individuel. Il reste encore quelques commentaires en début du fichier, mais la plupart des informations utiles sont maintenant documentées.
  • Les pages de manuel de packages-specs(7) et library-specs(7). Celles-ci expliquent la syntaxe exacte des dépendances de packages et de librairies respectivement..
  • La page de manuel de port-modules(5). Elle documente les différents modules du port qui sont utilisés dans l'infrastructure des ports, ex., cpan, java, python, etc.

Cette page est la traduction officieuse de la page “Ports - Porting Guide” de la FAQ officielle d'OpenBSD.
En cas de doute, merci de vous y référer !

Si vous voulez participer à l'effort de traduction, merci de lire ce topic.