Quand utiliser les "ifdefs" ?

La base du code Mozilla est utilisée dans de nombreux projets et produits, incluant Firefox, Thunderbird, XULRunner et bien d'autres. Ce code de base est parfois utilisé dans plusieurs projets mais des différences dans certains endroits sont parfois nécessaires. Les "ifdefs", ou instructions conditionnelles, sont alors utilisées pour obtenir un code différent.

Qu'est-ce qu'un "ifdef" ?

Un "ifdef" est une directive de compilation conditionnelle pour le préprocesseur qui permet de sélectionner certains bouts de code lorsque certaines conditions sont remplies. Dans ce document, le terme est utilisé en vrac pour désigner n'importe quel type de conditions qui permettent de générer différentes configurations.

Quand les "ifdefs" sont utilisés ?

Il existe 3 principaux cas d'utilisations dans l'arborescence de Mozilla : les ifdefs pour la partie "platform/widget", les ifdefs définissant certaines fonctionnalités et les ifdefs spécifiques à une application:

ifdefs pour "Platform/widget"

Le code dans Mozilla aura fréquemment besoin d'être différent pour certaines plateformes et widgets. Ces ifdefs sont pour la plupart acceptés. La seule fois où ils peuvent poser problèmes est lorsque l'on a du code d'une extension multi-plateforme ou pour la localisation: étant donné que ces codes sont téléchargés à travers plusieurs plateformes, les ifdefs spécifiques à une seule plateforme sont interdits.

Pour un exemple d'ifdef spécifique à une plateforme, voir nsCRT.h.

ifdefs pour les fonctionnalités (ou "feature")

Le code dans Mozilla contient beaucoup de fonctionnalités pouvant être activées/désactivées via des flags dans un fichier configure. Par exemple, il est possible de désactiver une grande partie du moteur de rendu de XUL en spécifiant --disable-xul quand on crée une configuration pour un build. Quand on ajoute des ifdefs qui implémente ces flags de configuration, une grande attention doit être portée sur les dépendances de construction (build dependencies). Par exemple, XPCOM, le moteur Javascript SpiderMonkey et le moteur réseau ne connaissent rien de XUL et ne devraient avoir aucun ifdefs basé sur --disable-xul.

Un ifdef spécial mérite votre attention : "MOZ_XUL_APP". Cette variable permet de "marquer" toutes applications utilisant le "toolkit". Les ifdefs sur MOZ_XUL_APP ne sont pas acceptables pour le tier 9, mais sont tolérés (et parfois même indispensable) pour les tiers suivants.

Pour un exemple d'ifdef gérant des caractéristiques, voir layout/Makefile.in.

ifdefs spécifiques aux applications

Pour finir, chaque application/projet a besoin de générer différents morceaux de code. Les ifdefs liés à une application ne devraient se trouver que dans du code spécifique à cette application. C'est le ifdef le plus délicat à placer car il est souvent difficile de savoir quel code est partagé et quel code est spécifique à une application. En règle général, tout code dans le tier 2, tier 9, ou tier 50 est du code partagé et ne devrait pas contenir d'ifdef spécifique à une application. N'importe quel code dans les tiers suivants est spécifique à une application. Cette règle comporte de nombreuses exceptions dont certaines sont listées ici :

  • Le code dans editor/ui/ est généré pour la suite et la version standalone de l'éditeur de texte Mozilla composer ainsi que pour thunderbird mais il est considéré comme étant du code spécifique à une application (application-specific).
  • Le code dans xpfe/ (excepté pour xpfe/appshell/ et xpfe/components/shistory/) est un mélange de code "toolkit" et "application-specific". Ce code est destiné à être déplacé ailleurs (la plupart dans toolkit/ ou suite/), mais pour le moment la plupart des ifdefs spécifique à une application sont autorisés car la situation est difficile à changer. Si vous souhaitez plus de détails, demander à Benjamin Smedberg.

Pour un exemple d'ifdef spécifique à une application mauvais et qui devrait être supprimé, voir nsNativeAppSupportWin.cpp.

Types d'ifdef

Il existe deux grands types d'ifdef : les ifdef pour le préprocesseur et les ifdefs pour le Makefile. Les ifdefs pour le préprocesseur sont généralement facile à repérer: dans du code C, C++ on les trouve avec des instructions comme #ifdef ou #if.

Les ifdefs dans un Makefile sont cependant plus dur à repérer et peuvent indirectement provoquer des erreurs ce qui est bien plus grave. Les ifdefs d'un Makefile sont utilisés pour construire ou non certains répertoires. Cela signifie qu'il existe des interfaces complètement différentes mais portant le même nom qui sont construites via des conditions. Par exemple (au moment de la rédaction), il existe 2 interfaces nsIExtensionManager : toolkit version et suite version. Les ifdefs du Makefile qui choisissent l'un ou l'autre ne sont pas évidents à trouver (voir Makefile.in et xpfe/components/Makefile.in).

Si vous introduisez un quelconque ifdef dans un makefile, veuillez demander une revue de votre code à un des mainteneurs du "build-config": Benjamin Smedberg sera généralement ravi de vérifier vos changements.

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : thomasj
 Dernière mise à jour par : thomasj,