From Mageia wiki
Revision as of 12:05, 16 March 2018 by Papoteur (talk | contribs) (Débogage des dépendances récursives)
Jump to: navigation, search

Template:Bandeau multi-langues-fr

Accueil [en] Accueil Équipes Packageurs Consignes


Template:Information

Warning!
Cette page est en cours d'élaboration et doit être réadapté à la politique d'empaquetage de Mageia. N'hésitez pas à la relire et la corriger. Les passages en Italique sont à revoir.

Contents

Consignes d'empaquetage de Mageia

Ces consigues sont basées sur les consignes de Fedora, OpenSUSE, Meego et d'autres distributions.

Maintenir un paquet

Tous les paquet de Mageia doivent être tenus par un mainteneur (maintainer) (alias titulaire (owner), (bug owner)). Chaque paquet sans mainteneur sera automatiquement reconsidéré comme à supprimer de Mageia. Un mainteneur d'un paquet est responsable et s'assure que :

  • son paquet est à jour avec les dernières sources en amont (upstream)
  • son paquet est toujours construit dans le système d'empaquetage de Mageia et répare les échecs lorsqu'elles ont lieux
  • les méta-données (meta-data) du fichier SPEC du RPM est exact
  • la licence du paquet est correcte
  • il/elle suit les sources en amont pour répondre aussi rapidement que possible aux mises à jours de sécurité critiques
  • elle/il fournit les informations à propos des changement majeur aux autres empaqueteurs (packagers) et mainteneurs (maintainers) pour leurs laissez assez de temps pour régler les problèmes de compatibilités.

Actuellement les données à propos du titulaire des paquets sont suivis dans http://pkgsubmit.mageia.org/data/maintdb.txt et les paquets non maintenus sont listés dans http://pkgsubmit.mageia.org/data/unmaintained.txt. Ils seront intégré et géré ultérieurement et nous laissons une période de grâce pour les paquets non maintenus. Après cette période de grâce, ces paquet sans mainteneurs serons reconsidéré pour la suppression.

Pour vous ajouter comme mainteneur d'un paquet, veuillez suivre ces étapes :

  • mettez à jour à la version la plus récente de mgarepo
  • Identifiez le paquet dont vous seul seriez le mainteneur unique
  • Pour chaque paquet que vous souhaitez maintenir faites :
 mgarepo maintdb set [NomDuPaquet] [VotreIdentifiant]
  • Ceci peut être uniquement fait par les empaqueteur, les apprentis n'ont aucun droit pour sur la commande maintdb
  • Vous pouvez le faire uniquement si le paquet est maintenu par personne (nobody) !'
  • Votre requête sera immédiatement traité et vous serez donc le mainteneur du paquet. Acte de bienveillance, vous aidez à sauver quelques paquets non-maintenus. Allez et montrer leur que vous les aimez :)

L'état actuel est visible ici : http://pkgsubmit.mageia.org/data/maintdb.txt ou si vous avez un compte comme empaqueteur complet (par exemple n'étant pas un apprenti) vous pouvez directement questionner la base de donné des mainteneur avec :

 mgarepo maintdb get [packagename]

ou vous pouvez demander à Sophie sur un chat de Mageia :

 :maint [packagename]

Convention des noms de paquet

  • Les noms de paquet de base (utilisé pour svn et src.rpm) doit être le même nom que celui du projet du logiciel en amont, toujours en minuscule. Le nom en amon peut contenir des chiffres, des '+', '_' ou '.', mais aucun autre caractère exceptionnel. Dans des cas exceptionnellement rares des majuscules peuvent être acceptés s'il y a une raison qui le justifie (ex : les paquets perl) ou pour des raisons historiques.
  • Les noms de paquet construit pour Mageia depuis leurs noms en amont doivent uniquement juxtaposer des suffixes en utilisant le délimiteur "-" (par exemple foo-devel ou foo-plugins comme dérivé du paquet foo). Tous "_" et "+" dans les noms des paquet doivent uniquement venir du nom du paquet en amont ! Les "." dans les noms de paquet doivent venir aussi de l'amont ou du schéma standard du versionnage.
  • Le fichier SPEC doit être nommé en suivant le schéma %{nom}.spec, c.a.d le nom du paquet source et du répertoire svn doivent être utilisés comme nom pour le SPEC.

Version et Révision (release)

La version du paquet a cette allure : X.Y.Z - R mga V
avec :

  • X.Y.Z le numéro de 'version' qui est devrait représenter la version du projet
  • R est l'étiquette de révision qui est toujours incrémenté après chaque changement du paquet et avant de le soumettre pour une nouvelle construction
  • mga est le suffixe de la distribution
  • V est la version de la distribution

Version

Le champ 'version' du fichier spec est là où vous inscrivez la version courante du logiciel à empaqueter. Il y a des cas où la version en amont ne correspond pas au standard et contient des caractères non numériques :

  • Paquets en prérévision (pre-release) : les paquets sortie en version "pre-révision" avant une version "final". Elle inclue par exemple des étiquettes "alpha", "beta", "rc", "cvs", "git", "svn", etc et doit être ajouté à l'étiquette révision (release) et non pas à l'étiquette "version". Vous trouverez des détails en dessous.

Versions de pré-révision

Pour les paquet de développement ou de pré-révision l'étiquette Release (révision) doit commencer par "0." ainsi quand le logiciel devient "final" et ne change pas de version, nous pouvons assurer une mise à jour sûre vers une version stable simplement en changeant Release à 1.

Par exemple :

monFichierSource-2.9rc2.tar.gz a un fichier de spécification (specfile) contenant les champs Version : 2.9 et Release : %mkrel 0.rc2.1

Pour chaque reconstruction du même paquet "pré-révisé" (pre-released), incrémentez simplement l'étiquette Release; comme ici 0.rc2.1 deviendrait 0.rc2.2 etc.

Il est recommandé d'utiliser la macro "%mkrel -c rc2 1" pour générer 0.rc2.1.

Pour les amonts de svn ou git, il est préférable d'inclure la date de la prise en compte, avec ou sans le numéro de révision ou du git hash (qui devrait être au moins en commantaire dans le fichier spec). Les exemples suivants sont acceptable :

%mkrel -c svn20130213 1
%mkrel -c 20130213svn85423 1
%mkrel -c git20130213 1
%mkrel -c 20130213gitae25f2 1

rtmpdump peut aider a gérer ces dates de prise en compre, avec les variables %snap et %mkrel : http://svnweb.mageia.org/packages/cauldron/rtmpdump/current/SPECS/rtmpdump.spec?view=markup

Révisions (release)

Le numéro de révision (release) doit commencer par 1, et doit revenir à 1 à chaque nouvelle version, et s'incrémenter à chaque changement du paquet.

Sous-révision (sub-release) (applicable uniquement aux mises à jours)

Veuillez vous référer la section de nos conventions des mises à jours (en).

Étiquettes

  • L'étiquette de l'empaqueteur (Packager) ne doit pas être utilisé dans le fichier Spec. Les identités des empaqueteurs sont évident depuis les entrées du registre des changements (changelog). En évitant d'utiliser l'étiquette "Packager" vous éviter de retrouver des fichiers binaires compilé par quelqu'un d'autre avec votre nom dans les entêtes. Voir aussi Maximum RPM definition of the Packager tag (en). Si vous avez besoin d'inclure des informations à propos de l'empaqueteur dans les RPM que vous construisez, utilisez plutôt %packager dans votre ~/.rpmmacros.
  • L'étiquette du vendeur (Vendor) ne pas non plus être utilisé. Il est automatiquement réglé par le système de construction (build system).
  • Ordinairement, l'étiquette PreReq doit être remplacé par entièrement par Requires. Pour plus d'information voir Maximum RPM fine grained dependencies chapter (en).
  • L'étiquette Source informe où trouver la source à l'amont du rpm. Dans la plus part des cas ça doit être le lien internet complet vers l'archive en amont (upstream tarball). La meilleur pratique veut l'utilisation de macros comme %version et %name pour permettre des mises à jours automatiques, mais ce n'est pas nécessaire.

L'étiquette résumé (Summary)

Cette étiquette décrit en une seule ligne le paquet. De longueur maximum de 79 caractères, elle commence avec une lettre majuscule et non pas avec un espace. Le sommaire doit finir avec un point ".". Si ça vous dérange d'un point de vue grammatical, asseyez vous, prenez une profonde inspiration et surmontez cette épreuve.

Le nom du paquet ne doit pas être répété dans le résumé. C'est une information redondante et donne un aspect étrange dans certains résultat de programme.

Il doit être adapté à toutes les situations standard et ne pas se préoccuper de contexte spéciaux. Il est utile dans les listes de paquets ordonnées alphabétiquement ou non, comme dans les listes de tous les paquets.

Il doit décrire la fonction principale du paquet et les propriétés particulières de ce paquet pour aider l'utilisateur à comparer des paquets aux noms ou fonctions similaires. Par exemple les deux mots "navigateur web" sont dans les résumés de tous navigateurs we, mais utilisant des adjectifs en plus (comme minimal, complexe, GNOME, KDE, rapide, ou l'auteur etc) aide à spécifier un paquet.

Le résumé dois être bref et précis sans inclure d'information redondante.

Le fichier SPEC du RPM contient uniquement la version anglaise afin de garde la base de donnée RPM petite.

L'étiquette de groupe RPM (RPM Group)

L'étiquette de groupe RPM est utilisé pour des groupes de paquets par leurs types de fonctionnalités qu'ils fournissent, et façonne la liste visible dans rpmdrake. Il est impératif que les groupes gardent leurs titres anglais, vous trouverez la liste de groupes existants à utiliser pour vos paquets sur la page Mageia policy (en). Actuellement la liste est différente de l'originelle inventé par Red Hat, car pour nous, de notre point de vue, elle n'est plus adaptée aux distributions d'aujourd'hui. Vous pouvez encore la trouver ici.

L'étiquette buildRoot

L'étiquette BuildRoot est obsolète et devrait être supprimée là où elle est rencontrée puisse que sa fonctionnalité est directement gérée par rpm dans mageia.

L'étiquette PreReq

Les paquets ne doivent pas utiliser l'étiquette PreReq. À l'époque, pour résoudre le serpent qui se mort la queue dans la récursion de dépendances, cette étiquette était utilisée pour désigner un "vainqueur" par rapport à ces dépendances et donc déterminer l'ordre de leur installation. Ce cas n'est plus le cas.

L'étiquette dépendances (requires) / dépendances explicites (explicit requires)

Les paquets doivent contenir uniquement des "Requires" (dépendances) si elles sont absolument nécessaires pour que les logiciels fonctionnent correctement. Utilisez des dépendances versionnées au besoin comme expliqué plus loin.

Les paquet ne doivent pas contenir "explicit Requires" (dépendances explicites) sur des librairies sauf lorsque c'est absolument nécessaire et si tel est le cas il doit y avoir un commentaire le justifiant dans le fichier SPEC.

De manière général on comptre sur RPMbuild pour ajouter automatiquement les dépendances par le SONAME des librairies (le SONAME est le nom de la librairie suivit de sa révision, comme libGL.so.1 est le SONAME de libGL.so.1.2.0), les interpréteurs de script shell, et les modules utilisés par les programmes écrits dans des langages de script populaires comme Perl et Python. Les outils de gestion de paquets les plus récents sont capables de résoudre leurs dépendances et de déterminer quel paquets sont nécessaires pour d'autres. Les dépendances explicites sur le nom du paquet peuvent aider l'utilisateur inexpérimenté qui s'apprête à installer un paquet RPM manuellement, mais, l'histoire a montré que de telles dépendances ajoutaient de la confusion quand, la librairie ou les fichiers étaient déplacés d'un paquet à un autre, quand, les paquets étaient renommés, ou quand, l'un des multiples paquets alternatifs aurait suffit. De plus, dans quelques cas, d'ancienne dépendances explicites sur le nom du paquet imposait des mises à jours et des reconstructions inutiles.

RPMbuild ajoutera automatiquement des dépendances versionnées dans quelques cas : avec le SONAME d'une librairie, le symbole faible de version de glibc, et des versions d'API de Perl ou Python quand elles installés comme binaires ou des modules d'extension versionnées. Des dépendances versionnées explicites sont requises quand on a besoin de permettre des mises à jours correctes vers une révision stable ou de mises à jours d'une révision à une autre, et aident quand on rétro-porte des paquets. Quoi qu'il en soit, elles peuvent périmer, devenir inexacte et superflues après quelque temps et doivent être reconsidérées lorsque ces versions deviennent de l'histoire ancienne. La règle du pouce est d'ajouter (ou de garder) une version explicite s'il est nécessaire pour la mise à jours des deux dernières révisions stables.

Des dépendances versionnées sont particulièrement critiques pour des paquet mis à jours ou rétro-porté à une révision stable. Les utilisateurs pourraient choisir d'installer un sous-ensemble de paquets pendant la mise à jour ou laisser des versions anciennes des paquets installées nécessaires et le résultat est un système non fonctionnel.

Exemple rationnel pour une dépendance versionnée explicite :

  # The automatic dependency on libfubar.so.1 is insufficient,
  #    (La dépendance automatique de libfoo.so.1 est insuffisante,)
  # as we strictly need at least the release that fixes two segfaults.
  #    (car on a besoin au minimum d'une révision qui répare deux erreurs de segmentations.)
  Requires: libfubar >= 0:1.2.3-7

Exceptions des dépendances/fournisseurs générées automatiquement

Comme tous les fichiers d'un paquet sont scannés automatiquement pour savoir ce dont ils ont besoin ou ce qu'ils fournissent, il est parfois nécessaire de changer quelques fonctions soit d'en exclure. Pour le faire, vous pouvez procéder ainsi :

  # Suppress automatically generated Requires for devel packages
  #    (supprime automatiquement les dépendances générées pour)
  #    (le paquet de développement                            )
  %global __requires_exclude devel\(.*\)

ou


Cette édition est nécessaire puisse que le code à changé (octobre 2014) This requires some editing as the code has changed (October 2014)

Utilisez maintenant pour les paquets de pear : %global __requires_exclude pear\\(Blowfish/DefaultKey.php\\)


  # Suppress automatically generated Requires for pear packages
  #    (Supprime les dépendances générées automatiquement pour)
  #    (les paquets de pear                                   )
  %global __requires_exclude pear(vendor/autoload.php)\\|pear(xmlapi.php)
  # we don't want to provide private python extension libs
  #    (Nous ne voulons pas fournir d'extensions privées pour )
  #    (les librairies Python.                                )
  %define __provides_exclude_from ^(%{python_sitearch}/.*\\.so\\|%{python3_sitearch}/.*\\.so)$

Vous pouvez aussi voir cette page du wiki de Fedora pour plus d'information à ce sujet.

Débogage des dépendances récursives

Il y a une erreur récurrente lorsque des règles de dépendances sont trop nombreuses et contradictoires. Alors librpm doit briser cette chaîne de dépendances et le fait un peu aléatoirement en ayant un semblant de chaîne puisqu'il est impossible d'en finir lorsqu'il y a ces conflits dans les étiquettes de dépendances.

Il est possible d'utiliser une commande comme "urpmi --debug-librpm --deploops" afin de déboguer ce genre de situations.

Mettre à jour depuis une révision précédente peut être résolu en cassant les boucles de dépendances.

L'étiquette des dépendances de constructions (BuildRequires)

Dans les paquets pour développement et test, veuillez vérifier que votre paquet ne manque d'aucune dépendance construite nécessaire. Avoir les dépendances propre pour la construction épargne beaucoup de temps au développeur et testeurs ainsi qu'un système de construction car il ne serait pas nécessaire de chercher manuellement les dépendances manquantes. Ça apporte aussi une sureté et prévient d'un échec de construction du paquet mais il manquera des fonctionnalités cruciales. Par exemple, une application graphique pourrait exclure le support PNG après que son script de configuration détecte que libpng n'est pas installé.

BuildRequires should be listed one per line for maximum readability; instead of cramming multiple BuildRequires on a single line, use one BuildRequires tag per dependency. While RPM may be able to quickly “view” that really long line of BuildRequires, humans cannot and while this may make the spec longer, it makes it easier to read. Before adding BuildRequires to any package, please be comfortable with Requires . Also please check that you don't add unnecessary BuildRequires. If you BuildRequire package "A" and this has Requires on package "B" and "C" it's useless to buildrequire package "B" and "C" additionally. You can check this with urpmq -pd on package "A".

You should always use architecture-independent virtual provides as BuildRequires. Arch-independent virtual provides are for example %name-devel (which has to manually added according to our library policy (en) or pkgconfig(name) (which is available for many packages already, and automatically generated)

For example don't use libsqlite3-devel, but use either sqlite3-devel or pkgconfig(sqlite3). You can check which virtual provides a -devel package has like so:

 rpm -q --provides lib64sqlite3-devel

which would result in these:

libsqlite3-devel = 3.7.6.2-3.mga1
sqlite3-devel = 3.7.6.2-3.mga1
pkgconfig(sqlite3) = 3.7.6.2
devel(libsqlite3(64bit))
lib64sqlite3-devel = 3.7.6.2-3.mga1
lib64sqlite3-devel(x86-64) = 3.7.6.2-3.mga1

As you can see, only the two recommended above bear no reference to the architecture, unlike devel(libsqlite3(64bit)) or lib64sqlite3-devel(x86-64).

IMPORTANT: If you use some binaries like desktop-file-install you must buildrequire the packages which contain them, otherwise the package will fail to build on the Mageia build system.


When you build a package locally, you can easily install the BuildRequires of package foo using the command:

 urpmi foo.spec

(or urpmi --buildrequires foo.spec or urpmi --buildrequires foo.src.rpm which would be the more correct syntax) It will pull in all packages listed in the spec-file as BuildRequires.

Les étiquettes sur les architectures (ExclusiveArch / ExcludeArch / %ifarch / %ifnarch)

Use ExclusiveArch when you are sure the package only works on some architectures. Use ExcludeArch when you know the package doesn't work on some arch, but don't know the exact arches it does work on.

For x86 (i586) the macro to use is %ix86.

%ifarch/%ifnarch should be avoided as much as possible, at least for patching. In general, you should not apply a patch conditionally only for one architecture. This will also give an rpmlint warning:


%ifarch-applied-patch
A patch is applied inside an %ifarch block. Patches must be
applied on all architectures and may contain necessary configure
and/or code patch to be effective only on a given arch.

L'étiquette sources

Source files must begin with Source0, do not use Source: and then Source1:; if a package has exactly one source file, still use Source0 as it may not always continue to have exactly one source file. If a source file has a downloadable URL that it came from, it must be included. In most cases this should be a complete URL to the upstream tarball. Best practice would be to use macros like %version and %name for this URL where possible to allow for automatic updates, but this is not necessary.

L'étiquette patches

Each problem should be solved in a separate patch. To allow easy maintenance of patches, the source of the patch should be indicated, especially if the patch may need to be updated from the same source in the future. When the patch is first added, the source of the patch should be stated in the commit message. It also helps to have a comment in the SPEC where the patch comes from, which should be a complete URL to the upstream if this is not obvious, and a description what the patch does in short simple words, if that is not clearly self-evident from the patch name.

Patches should start from Patch0 keyword in SPEC, similar to the Source tag. Patches should be named in a very explicit manner to make it very clear against which version of the software the patch was originally generated or applied. To that end, patch names usually follow the convention of [package_name]-[version]-[description].[filename suffix]:

  • [package_name] is the name of the package it applies against, such as 'shadow-utils' or 'gnupg'
  • [version] is the version of the program this patch was developed against, such as 1.0. If a patch is rediffed because the old patch does not apply to a new version, a new patch must be created with the appropriate name – it is inappropriate to rediff foo-1.0-linking-fix.patch against foo-1.2 and continue to use the same patch name. The new patch must be named foo-1.2-linking-fix.patch. For historical purposes, patches should be moved in svn; instead of doing “svn rm foo-1.0-linking-fix.patch” and “svn add foo-1.2-linking-fix.patch”, the original patch should be moved and then the newly-derived patch copied and committed; i.e. “svn mv foo-1.0-linking-fix.patch foo-1.2-linking-fix.patch; svn commit”
  • [description] is a short description of the patch's purpose
  • [filename suffix] Normally this is .patch or in some cases, mostly when reusing upstream patches .diff

Patches should be in the unified format (diff -u) and should be applied with 1 strip level in the spec file (%patch -p1). The only exceptions are the patches obtained from an another primary source site. The original name, suffix, and format is preserved in this case. Each patch should be kept in plaintext format and uncompressed, to allow for usage with SVN web frontend for example.

For the patches to be applied, the patches should be mentioned in %prep below %setup, and should be done as follows

%patch0 -p1 -b .foobar
  • -p1 is the patch level, relative from where the patch is applied from
  • -b is the suffix that is appended to the backup files which the patch command creates, in this case .foobar, this should similar to or derived from the [description] part of the patch filename (see above).

To create patches, you can ease your work by using something like http://labix.org/patcher

  • Using %apply_patches

This may be used to replace all the %patchN lines in %prep and can save space in the spec file (especially in packages with many upstream patches) as it will apply all patches listed with one command. However, for this to work all the patches must be -p1 and the PatchN: keyword definitions must be placed immediately following the SourceN: definitions in the spec file, otherwise they may be silently ignored (no error messages during build) so be careful. Alternatively, the macro %autopatch -p1 may be used, which works essentially the same way. This is a new standard macro from upstream RPM, and therefore provides better compatibility with other distributions.

L'étiquette %clean

The %clean section is deprecated and should be removed where encountered, as it is handled directly by rpm in Mageia.

La documentation

Any relevant documentation included in the source distribution should be included in the package. Irrelevant documentation include build instructions, the omnipresent INSTALL file containing generic build instructions, for example, and documentation for non-Linux systems, e.g. README.MSDOS. Pay also attention about which subpackage you include documentation in, for example API documentation belongs in the -devel subpackage, not the main one. Or if there's a lot of documentation, consider putting it into a subpackage. In this case, it is recommended to use *-doc as the subpackage name, and Documentation as the value of the Group tag.

Also, if a package includes something as %doc, it must not affect the runtime of the application. To summarize: If it is in %doc, the program must run properly if it is not present.

Check that documentation file permissions allow reading by normal users.

When only English man pages are available, install them uncompressed to %{buildroot}%{_mandir}/manX/ (where X is the appropriate section number). They will be automatically compressed before being packaged, so they must be referred to in the %files section with a wild card, e.g. %{_mandir}/man1/xyzzy.1*. Man pages will be automatically given the %doc attribute, so don't add that explicitly.

Paquet de développement

If the software being packaged contains files intended solely for development, those files should be put in a -devel subpackage. The following are examples of file types which should be in -devel:

  • Header files (such as .h files)
  • Unversioned shared libraries (such as libfoo.so). Versioned shared libraries (such as libfoo.so.3, libfoo.so.3.0.0) should not be in -devel.

A good rule of thumb is if the file is used for development and not needed for the base package to run properly, it should go in -devel.

.a files and .la files should generally not be included anywhere. They are only useful when one wants to statically link a program against the library (i.e. include the library in the program binary itself, so the library isn't needed at run-time), which is generally not done in Mageia. Libtool archives, foo.la files, should not be included. Packages using libtool will install these by default even if you configure with --disable-static, so they may need to be removed before packaging. Due to bugs in older versions of libtool or bugs in programs that use it, there are times when it is not always possible to remove *.la files without modifying the program. In most cases it is fairly easy to work with upstream to fix these issues. Note that if you are updating a library in a stable release (not devel) and the package already contains *.la files, removing the *.la files should be treated as an API/ABI change -- ie: Removing them changes the interface that the library gives to the rest of the world and should not be undertaken lightly.

Dépendant du paquet de base

Devel packages must require the base package using a fully versioned dependency: Requires: %{name} = %{version}-%{release} Usually, subpackages other than -devel should also require the base package using a fully versioned dependency.

Fichiers Pkgconfig

The placement of pkgconfig(.pc) files depends on their usecase. Since they are almost always used for development purposes, they should be placed in a -devel package. A reasonable exception is when the main package itself is a development tool not installed in a user runtime, such as gcc or gdb.

Librairies partagées

Whenever possible (and feasible), Mageia Packages containing libraries should build them as shared libraries.

An ldconfig isn't needed anymore for libraries in %post and %postun, this is handled automagically by RPM filetriggers . If this is encountered, please remove the ldconfig calls and if this is the only purpose of %post / %postun then remove the whole %post / %postun section

See Libraries policy (en) for more details on how to package libraries.

Fichiers de configuration

Configuration files must be marked as such in packages.

As a rule of thumb, use %config(noreplace) instead of plain %config unless your best, educated guess is that doing so will break things. In other words, think hard before overwriting local changes in configuration files on package upgrades. An example case when /not/ to use noreplace is when a package's configuration file changes so that the new package revision wouldn't work with the config file from the previous package revision. Whenever plain %config is used, add a brief comment to the specfile explaining why.

Don't use %config or %config(noreplace) under /usr. /usr is deemed to not contain configuration files in Mageia.

Gestion de Service / Initscripts

Since Mageia 3 systemd is the only init system offered, however it is still able to support SystemV-style initscripts with the caveat that they must contain valid LSB headers to allow for proper dependency information to be extracted.

Mageia 2 supported both SystemV and systemd boots and thus required both a SystemV-style initscript and (optionally) a systemd unit.

Mageia 1 only supported SystemV.

For more information on packaging services see the System Service policy (en).

Fichiers desktop

If a package contains a GUI application, then it needs to also include a properly installed .desktop file. For the purposes of these guidelines, a GUI application is defined as any application which draws an X window and runs from within that window. Installed .desktop files MUST follow the desktop-entry-spec , paying particular attention to validating correct usage of Name, GenericName, Categories , StartupNotify entries. Please always validate .desktop files via desktop-file-validate from the package desktop-file-utils.

La clé Icon des fichiers Desktop

The icon key can only be specified in one way:

  • Short name without file extension/path:

Icon=comical

The short name without file extension allows for icon theming (it assumes .png by default, then tries .svg and finally .xpm)

Création du fichier .desktop

If the package doesn't already include and install its own .desktop file, you need to make your own. You can do this by generating a .desktop file you create as a Source: (such as Source3: %{name}.desktop) or generating it in the spec file via a "here document". Here is an example for such a here document, the green part is the contents of the .desktop file


 mkdir -p %{buildroot}%{_datadir}/applications
 cat > %{buildroot}%{_datadir}/applications/%{name}.desktop << EOF
 [Desktop Entry]
 Name=Ginkgo
 Comment=Ginkgo is a graphical front-end for Nepomuk
 Exec=%{_bindir}/%{name}
 Icon=nepomuk
 Type=Application
 Categories=Utility;KDE;Qt;
 EOF

Localiser les fichiers .desktop

The values of Name or GenericName are displayed as captions to the graphical desktop icon, so they should be localized according to the Desktop Entry Specification. Most of the time, only language codes or language/country codes are needed to select the intended system locale. For example:

[Desktop Entry]
Type=Application
Name=Clocks
Name[de]=Uhrzeit
Name[es]=Relojes
Name[fr]=Horloges
Name[pt_BR]=Relógios
Name[zh_CN]=时钟

In the above .desktop file, [de] specifies the German language locale, covering any German-speaking locale, such as de_DE or de_AT.

Note: Since a language/country code (e.g. pt_BR) is more specific than a language code (e.g. pt), a string for the pt_BR locale will not be used for the Portuguese language locale (pt). If a string is appropriate for every Portuguese locale, you can use "Name[pt]" instead.

Utilisation de desktop-file-install

desktop-file-install SHOULD be used if there are changes desired to an upstream provided .desktop file (such as add/removing categories, etc). Note: The limited available editing options can be queried via desktop-file-install --help-edit or desktop-file-install --help-all

Here are some usage examples:


 desktop-file-install --vendor="%{_real_vendor}" \
 --remove-category="Application" \
 --add-category="Settings;HardwareSettings;" \
 --dir %{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/%{name}.desktop


 desktop-file-install --vendor="%{_real_vendor}" \
 --dir=%{buildroot}%{_datadir}/applications \
 --remove-category='Application' \
 --remove-category='Utility' \
 --add-category='System' \
 --add-category='Settings' \
 --add-category='Printing' \
 --add-category='Qt' \
 --add-category='HardwareSettings' \
 --add-category='X-Mageia-CrossDesktop' \
 --remove-key='Version' \
 %{buildroot}%{_datadir}/applications/hplip.desktop

The installation of the desktop file on the target system does not have to be handled manually any more as had to be done previously in %post/%postun, this is automagically handled now via RPM filetriggers (en). Just make sure that all desktop files you want to install are correct and validated as pointed out above.

Catégorie spécial MandrivaLinux

In many older .desktop files in packages imported from Mandriva there are deprecated X-MandrivaLinux category entries. They were used when switching from Debian Menu System to Freedesktop XDG menu system, and are deprecated and should be replaced by standard Freedesktop categories. Those can be seen in Freedesktop specification

The only Mandriva one that has an equivalent in Mageia is X-MandrivaLinux-CrossDesktop. This is for applications which have toolkit-related categories (like GTK, QT, KDE) in their desktop files (and would thus be shown in More submenu in other desktop environment) when we want them to not go to the More submenu on any desktop. These entries should be replaced by X-Mageia-CrossDesktop. For reference have a look at this bugreport: Bug 2449 - X-MandrivaLinux-* should be dropped

Here's one example on how it should be done. totem.desktop file from Totem media player contains:

 Categories=GTK;GNOME;AudioVideo;Player;Video;X-MandrivaLinux-CrossDesktop;X-MandrivaLinux-Multimedia-Video;

So X-MandrivaLinux-CrossDesktop should be replaced by X-Mageia-CrossDesktop (or one could remove the GTK and GNOME categories from the desktop file, but this will also remove information which could be useful to some desktop environments)

Also X-MandrivaLinux-Multimedia-Video is such a deprecated category and should definitely not be used anymore, instead replaced by the main Freedesktop category AudioVideo and supplemented by at least one additional category from http://standards.freedesktop.org/menu-spec/latest/apa.html. As this is already the case (AudioVideo;Player;Video; see above) this X-MandrivaLinux category should simply be removed.

Macros vs variables

%{buildroot} and %{optflags} vs $RPM_BUILD_ROOT and $RPM_OPT_FLAGS There are generally two styles of defining the rpm BuildRoot and Optimization Flags in a spec file:

macro style variable style
Build Root %{buildroot} $RPM_BUILD_ROOT
Opt. Flags %{optflags} $RPM_OPT_FLAGS

According to our SPEC syntax policy (en) variables which are really definitions, such as $RPM_OPT_FLAGS or $RPM_BUILD_ROOT must not be used. Macros like %{optflags} and %{buildroot} must be used instead. Keep "$*" variables strictly limited to shell constructs and not RPM-based definitions.

Tenue des fichiers d'internationalisation

Locale files, also known as localisations or (as an abbreviation) l10n files or i18n files (short form of internationalisation, the number shows how many letters have been left out) are compiled .mo files. This section is not about man pages.


(If a package includes translations, it is no longer needed to add the gettext BuildRequire, because gettext is already present in the build environment.)

Mageia includes an rpm macro called %find_lang. This macro will locate all of the locale files that belong to your package (by name), and put this list in a file. You can then use that file to include all of the locales. %find_lang should be run in the %install section of your spec file, after all of the files have been installed into the buildroot. The correct syntax for %find_lang is usually:

%find_lang %{name}

In some cases, the application may use a different "name" for its locales. You may have to look at the locale files and see what they are named. If they are named myapp.mo, then you will need to pass myapp to %find_lang instead of %{name}. After %find_lang is run, it will generate a file in the active directory (by default, the top level of the source dir). This file will be named based on what you passed as the option to the %find_lang macro. Usually, it will be named %{name}.lang. You should then use this file in the %files list to include the locales detected by %find_lang. To do this, you should include it with the -f parameter to %files.

%files -f %{name}.lang
%{_bindir}/foobar
...

If you are already using the -f parameter for the %files section where the locales should live, just append the contents of %{name}.lang to the end of the file that you are already using with -f. (Note that only one file may be used with %files -f.)

Why do we need to use %find_lang?

Using %find_lang helps keep the spec file simple, and helps avoid several other packaging mistakes.

  • Packages that use %{_datadir}/* to grab all the locale files in one line also grab ownership of the locale directories, which is not permitted.
  • Most packages that have locales have lots of locales. Using %find_lang is much easier in the spec file than having to do:
%{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/be/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/cs/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/de/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/es/LC_MESSAGES/%{name}.mo
...
  • As new locale files appear in later package revisions, %find_lang will automatically include them when it is run, preventing you from having to update the spec any more than is necessary.

Keep in mind that usage of %find_lang in packages containing locales is a MUST.

Scriptlets

Great care should be taken when using scriptlets in Mageia packages. If scriptlets are used, those scriptlets must be sane.


Scriptlets requirements Do not use the Requires(pre,post) style notation for scriptlet dependencies, because of two bugs in RPM. Instead, they should be split like this:

Requires(pre): ...
Requires(post): ...

For more information, see www.redhat.com .

Running scriptlets only in certain situations When the rpm command executes the scriptlets in a package it indicates if the action preformed is an install, erase, upgrade or reinstall by passing an integer argument to the script in question according to the following:

macro install erase upgrade reinstall
%pre 1 - 2 2
%post 1 - 2 2
%preun - 0 1 -
%postun - 0 1 -

This means that for example a package that installs an init script with the chkconfig command should uninstall it only on erase and not upgrade with the following snippet:

%preun
if [ $1 -eq 0 ] ; then
/sbin/chkconfig --del %{name}
fi

See also /usr/share/doc/rpm-*/triggers, which gives a more formal, generalized definition about the integer value(s) passed to various scripts.

Scriplets are only allowed to write in certain directories Build scripts of packages (%prep, %build, %install, %check and %clean) may only alter files (create, modify, delete) under %{buildroot}, %{_builddir} and valid temporary locations like /tmp, /var/tmp (or $TMPDIR or %{_tmppath} as set by the rpmbuild process) according to the following matrix

/tmp, /var/tmp, $TMPDIR, %{_tmppath} %{_builddir} %{buildroot}
%prep yes yes no
%build yes yes no
%install yes yes yes
%check yes yes no
%clean yes yes yes

Further clarification: That should hold true irrespective of the builder's uid.

L'usage de l'étiquette Epochs

The Epoch tag in RPM is to be used only as a last resort, and should be avoided whenever possible. However, it is sometimes necessary to use an Epoch to handle upstream versioning changes or to ease transition from third party repositories.


Créer un paquet à partir de rien

If you want to create a package from scratch, here is a skeleton SPEC where you just need to replace foo with the proper values according to these guidelines

Name:		foo	
Version:	1.0
Release:	%mkrel 1
Summary:	foo
License:	foo
Group:		foo
URL:		foo
Source0:	%name-%version.tar.bz2

%description
foo


%prep
%setup -q

%build
%configure2_5x

%make

%install
%makeinstall

%find_lang %name

%files -n %name

Modifier un paquet existant

If you base a new package on an existing non-Mageia package, make sure you verify the correctness of the package and it's spec file to understand exactly what has been done to package the software. Do not submit a package without knowing what those strange, but innocent looking commands do.

In particular, you should

  • ensure that original tarballs are self-contained pristine tarballs. The tarball should not contain symlinks that reference outside the tarball root directory
  • verify any sources and patches and remove patches or sources that:
    • are related to platforms we do not support (example: sparc, ia64, ppc, ...)
    • Implement features we do not support (example: selinux)
    • Read every patch and understand what it does, if it is needed, put an explanation in the header justifying why the patch is needed.
  • verify that the license stated in the spec file matches the actual license of the software, for this it is advised to also look/grep in the header files of the source code to verify the license information
  • skim the summary and description for typos and oddities (see Summary and description ),
  • make sure that the correct build root is used,
  • ensure that macro usage is consistent and that the macros are available in Mageia (see Macros )

Keep old changelog entries to credit the original authors. Entries that are several years old or refer to ancient versions of the software may be erased. If you end up doing radical changes and re-write most of the spec file anyway, feel free to start the changelog from scratch. In other words, use your best judgement.

Registre des changements

This section describes the Mageia policy for RPM changelogs. (Original changelogs included in the original source are not affected by this policy.)

Please consider that a "normal end user with some technical skills" should be able to read and understand an RPM changelog. Changelog entries have to be in reverse chronological order: newer change log entries are listed above older entries, with the first entry being the most recent.

Please bear in mind that Mageia changelogs will be automatically parsed to prepare distribution release notes and to report on bugs and CVEs and malformed entries may not be read correctly.

Informations générales

  • Changelogs are stored in the SVN commit logs, but should still be considered as part of the final spec when committing to svn (see below)
  • The %changelog section must not be used in the .spec file as the svn commit logs produce the RPM changelog upon build
  • one supplies a commit message when commiting changes, either via svn ci or mgarepo ci via the option -m '- this is my commit message'
  • provide meaningful and detailed commit messages and make them verbose enough that those coming later do not need to look at a diff of changes to see what actually happened.
  • A bad example would be:
 - fixed foo

This tells no one anything and after a year, whomever made the commit likely has no idea what they did in that commit.

  • A good example would be:
 - rediffed description.patch to fix foo
 - added foo-manpages.tar.bz2 to provide such and such for foo
 - dropped cvsfix32.patch; merged upstream

The above is far more telling as to what was actually done. Note that source files must be referred to by their full name (in the above, foo-manpages.tar.bz2, not "S23" or "source23" or something similar). Patches do not need to be referred to by their full names, but can be referred to by the "description" portion of the patch. For instance, the first comment is "rediffed description.patch to fix foo", where description.patch is noted. The patch could in reality be named foo-1.2-mga-description.patch; the prefix (foo-1.2-mga) can be dropped as it should be fairly straightforward to determine what patch has modified/added/removed based on the unique description of the patch. If the patch name is not unique (i.e. there is foo-1.2-mga-description.patch and foo-1.0-cvs-description.patch), then one of the patch names can (and probably should) be changed or the entire patch name should be noted in the changelog. Do not refer to source files or patch numbers numerically (i.e. using S23 or P12) as patches and source files may be renumbered from time to time and a patch number is not guaranteed to remain consistent.

  • when adding multi-line commit messages, every seperate entry must begin with the '-' character. Like
 - Bumped release
 - Added foo.patch

This is optional for single line messages, as in that case it's automatically added if not present To create a multi-line message simply leave the current line unterminated (no final quote mark) and hit ENTER and continue writing. Finally terminate the last line with a quote mark. Or write the commit messages into a file and use the -F option for svn ci / mgarepo ci.

Références externes

Each external reference (bug numbers etc) should be of the form:

"(" + external reference code + bug number +")"

Currently defined:

  • Mageia Bugs : mga#
  • Common Vulnerability / Exposure : CVE

Bug Numbers in the change log

During maintenance of a distribution, every change has to be marked with the correct bug number. Normally this has to be a number from https://bugs.mageia.org/. Add an entry with the bugzilla number and a short description of the bug summary. For example:

- Removed invalid desktop Category "Application" (mga#4654).
- Symlink icon to pixmaps dir (mga#2108)
- Added gnome-ui-properties to control-center (mga#1960).

New packages related to new features will refer also to the corresponding bug number in bugzilla, For example:

- Adding Qt Contacts support (mga#8011)

CVE numbers in change log

As with bug numbers: Add a short description (normally the CVE summary should be enough), the Bugzilla and the CVE number to the changelog entry, and also the name and origin of the patch fixing that CVE. Example:

- fix CVE-2012-1234, denial of service through user stupidity (fix-cve-2012-1234.patch, from upstream).

Modifications du fichier de spécification

Be as precise as possible! This is especially important if you remove something from the spec file.

  • Removing original source code must be declared in spec file with a comment ("useful for FreeBSD only" for example) - not necessary to repeat the comment in specfile.
  • Extra commands (for example during %install) can be illustrated with a short comment in spec file
  • Adding/Removing packages from Requires/Provides must be described in the changelog
  • one thing which should not be done without communicating with the maintainer beforehand, is reindentation of some parts of the SPEC file. Albeit only small changes in the spec itself (like exchanging a space by one/two tabs between the Tags in the preamble and the values) the diff which is produced by this will be huge.

Modification du code source

Document the most important changes but limit verbosity.

  • look into the source changelog and pick up the most important changes for the distribution (changes for other operating systems are not important). Include what has changed in the new version, usually in the level of detail of a NEWS file; the change log files are usually too long. More than 10-15 lines shouldn't be necessary to describe the most important changes.
  • arrange the original changes behind the version update information. Example:
 - Update to 1.3.2:
   + fixes memory leak in import function
   + new API command: unlock_client()
   + the following bugs are closed by this new upstream release:
   ++ ............ [mga:332]
   ++ ............ [mga:337]
 - split of devel package
  • If upstream does not provide a meaningful change log, then only do best effort. Don't waste too much time over it.
  • If the upstream tarball really has not changed except for the version number, just the version number in the change log would be fine. Same goes for packages just containing some graphics or theming (unless upstream already provides something that fits). If the upstream changes just consist of "updated translation" or "several bug fixes" even that can be sufficient for a changelog entry (unless these bug fixes contain something you find worth mentioning).

Empaquetage des librairies statiques

Packages including libraries should exclude static libs as far as possible (eg by configuring with --disable-static). Static libraries should only be included in exceptional circumstances. Applications linking against libraries should as far as possible link against shared libraries not static versions.

.a files and .la files should generally not be included anywhere. They are only useful when one wants to statically link a program against the library (i.e. include the library in the program binary itself, so the library isn't needed at run-time), which is generally not done in Mageia. Libtool archives, foo.la files, should not be included. Packages using libtool will install these by default even if you configure with --disable-static, so they may need to be removed before packaging. Due to bugs in older versions of libtool or bugs in programs that use it, there are times when it is not always possible to remove *.la files without modifying the program. In most cases it is fairly easy to work with upstream to fix these issues. Note that if you are updating a library in a stable release (not devel) and the package already contains *.la files, removing the *.la files should be treated as an API/ABI change -- i.e. removing them changes the interface that the library gives to the rest of the world and should not be undertaken lightly.


Empaquetage des librairies statiques

  • In general, packagers are strongly encouraged not to ship static libs unless a compelling reason exists.
  • We want to be able to track which packages are using static libraries (so we can find which packages need to be rebuilt if a security flaw in a static library is fixed, for instance). There are two scenarios in which static libraries are packaged:
  1. Static libraries and shared libraries. In this case, the static libraries must be placed in a *-static-devel subpackage. Separating the static libraries from the other development files in *-devel allow us to track this usage by checking which packages BuildRequire the *-static-devel package. The intent is that whenever possible, packages will move away from using these static libraries, to the shared libraries.
  2. Static libraries only. When a package only provides static libraries you can place all the static library files in the *-devel subpackage.
  • If (and only if) a package has shared libraries which require static libraries to be functional, the static libraries can be included in the *-devel subpackage.

Lier statiquement les exécutables

  • Static linkage is a special exception and should be decided on a case-by-case basis. The packager must provide rationale for linking statically, including precedences where available, to release engineering for approval.

Rendre un paquet obsolète

When a package is no longer needed in the distribution it should be obsoleted and removed from cauldron.

To obsolete and remove a package from cauldron :

  • on svn, move the package to the directory svn+ssh://svn.mageia.org/svn/packages/obsolete/ (see also How to drop a package from SVN (en) )
  • if the package is replaced by an other one which provides the same functionality, add it as obsolete in the new package. Using versioned obsoletes is recommended (Obsoletes: foo < last cauldron version + 1) - This applies for all subpackages which should be obsoleted!
  • if the package is not replaced by an other one and is simply dropped, obsolete it by the task-obsolete package. Don't forget to add a comment with the reason for obsoleting, or a link to the discussion on the mailing list explaining the reasons.). Using versioned obsoletes is recommended (Obsoletes: foo < last cauldron version + 1) - This applies for all subpackages which should be obsoleted!

When a package is obsoleted by another package it will automatically be removed from the cauldron repository.

This was imported from MeeGo wiki licensed under CC-By 3.0
As the wiki doesn't exist anymore, have a look at the archived version: http://wayback.archive.org/web/20130903235324/http://wiki.meego.com/Main_Page

Langages de programmation spécifiques

Nodejs packaging (en)