Plugins
Un article de SmartEiffelWiki, l'encyclopéde libre.
*** *** Cette page est écrite en Anglais. Si vous lisez l'Anglais, vous pouvez traduire la page *** correspondante en utilisant la version Anglaise comme modèle. *** Si vous décidez de traduire cette page, d'abord merci ; commencez par ajouter ici *** une note avec trois étoiles *** pour éviter les traductions multiples. *** S'il-vous-plaît, lisez d'abord nos conseils aux auteurs ! *** Merci d'avance. *** *** La version la plus récente est en Anglais. Les modifications doivent être *** apportées à la version française. --Cyril 24 jul 2006 à 13:05 (CEST) ***
Les plugins sont un moyen d'augmenter de manière spectaculaire les capabilités de SmartEIffel, en ajoutant des bibliothèques qui ont la couleur, l'odeur et le goût des bibliothèques standard. Il s'agit en fait d'un extension d'un mécanisme Eiffel standard, les externals.
Le but des plugins est l'indépendance du back-end. Cela signifie que, potentiellement, la même bibliothèque pourrait être utilisée à la fois par compile_to_c et compile_to_jvm. Noter que nous souhaitons à l'avenir fournir d'autres back-ends. Dans ce cas, le système de plugin devient encore plus important.
| Sommaire |
Comment ça marche ?
Un plugin est formé de deux parties interdépendantes :
- le côté Eiffel, qui fournit une interface utilisable par d'autres objets Eiffel ;
- le côté externe, qui implante l'interface du plugin pour un ou plusieurs back-end (par exemple, C et Java).
Le côté Eiffel est du code 100% Eiffel, et il utilise des features external qui permettent de passer la barrière vers l'autre côté du plugin. La barrière est gérée par SmartEiffel : le compilateur associe les fonctions externes aux features external en utilisant des fichiers de configuration fournis par le plugin.
Côté Eiffel
Le côté Eiffel utilise des features external. La syntaxe est la suivante :
feature
my_plugin_feature is
external "plug_in"
alias "{
location: "/chemin/vers/mes/plugins"
module_name: "mon_plugin"
feature_name: "feature"
}"
Bien entendu, une feature peut prendre des arguments, et retourner un résultat ! (après tout, c'est un external) ;-)
Attention cependant, il est nécessaire de ne passer et de retourner uniquement des types de base : soit des expanded de base (INTEGER, BOOLEAN, etc.) soit un POINTER (usage classique : a_string.to_external).
- location indique le répertoire où vous rangez un ou plusieurs de vos plugins. Cette chaîne peut contenir des variables d'environnement (soit des vraies variables, soit des variables définies dans la section [Environment] de votre fichier de configuration).
Par exemple, les bibliothèques standard de SmartEiffel sont définies en utilisant la location suivante :
location: "${sys}plugins"
- module_name contient le nom du plugin en lui-même. Ce devrait le nom d'un sous-répertoire de location qui contient un répertoire par back-end (par exemple, c pour le générateur C, java pour le générateur Java). Le contenu de chacun de ces sous-répertoires dépend du générateur, et est explicité ci-dessous.
- feature_name enfin est le nom de la feature, fonction, méthode etc. appelée par le back-end (par exemple, C appelle des fonctions, Java appelle des méthodes). Peu importe : ce sont des features ;-)
Côté obscur
Génération C
Le back-end C utilise un sous-répertoire de votre plugin appelé c. les fichiers utilisés sont :
- tous les fichiers .c, qui seront insérés dans un des fichiers C générés
- tous les fichiers .h, qui seront insérés dans un le fichier d'entête généré
- le fichier includes, qui contient une description des chemins où trouver les entêtes des bibliothèques.
- le fichier libs, qui contient la description des bibliothèques natives à lier
- le fichier paths, qui contient une description des chemins où trouver ces bibliothèques
- le fichier includes, qui contient une description des chemins où trouver les fichiers d'entête
Les fichiers .c et .h sont inclus dans l'ordre alphabétique.
Les fichiers includes, libs et paths utilisent une syntaxe identique à celle du fichier de configuration.
Les sections portent le nom du système d'exploitation, de l'arôme (flavor dans le fichier de configuration) et enfin du compilateur C utilisés, dans cet ordre et séparés par un point. Si le plugin ne dépend pas de l'un de ces éléments, il peut être omis.
Les clés de ces fichiers sont uniquement informatives ; par contre, les valeurs sont utilisées pour générer la ligne de commande (les appels au compilateur C).
Vous pouvez, par exemple, regarder les fichiers de configuration de Vision.
Note : lorsqu'il n'y a pas d'argument, les noms sont générés sans parenthèse. Cela permet d'accéder aux attributs, aux variables, aux macro. L'absence de parenthèses n'est donc pas un bug mais bien un comportement souhaité. Dans le cas où on souhaite accéder à une fonction sans argument, il suffit de passer par l'intermédiaire d'une macro qui remplace un nom sans parenthèse par le nom de la fonction à appeler.
Génération Java
Pour le back-end Java, le sous-répertoire du plugin doit s'appeller java. Le compilateur utilise les fichiers suivants :
- les fichiers .java sont compilés avec l'aide des options en ligne de commande et/ou du fichier de configuration (voir compile_to_jvm pour plus de détail). Les fichier .class ainsi générés sont automatiquement copiés dans le répertoire de compilation du programme.
- les fichiers .class, s'ils sont présents et s'ils sont plus récents que les fichiers .java correspondants sont utilisés en lieu et place d'une compilation du fichier .java, à la manière de la commande make sous UNIX.
Pour améliorer le temps de compilation d'un programme dépendant des plugins fournis avec le compilateur (comme par exemple le plugin io), l'installeur compile les fichiers .java à l'installation pour que le compilateur puisse s'en servir directement.





