Commençons avec le simple module "Bonjour vous !" :
#include "module.h"
int module_init(moduleoption *opt)
{
debug("Bonjour vous !");
debug("Poids: %d", option_int(opt, "weight"));
return(0);
}
Comme vous pouvez le voir, ce module ne contient que la fonction module_init().
Cette fonction est appelée juste après que le noyau a chargé le module et est la seule qui doit être définie pour tous les modules d'ajustage écrits pour la branche 0.2.x de Tablix (le prototype de cette fonction est défini dans le fichier modsup.h, voir init_f).
Aucune autre fonction ne sera appelée, à moins que vous en fassiez l'appel dans module_init().
Note:
module_init()est équivalent à la fonctioninit_mod()de la branche 0.1.x .
Le paramètre opt de la fonction module_init() est une structure comprenant toutes les options du module qui ont été spécifiées dans le fichier de configuration (en utilisant les balises <option>).
Vous pouvez récupérer les valeurs de ces options de la structure moduleoption en utilisant les deux fonctions suivantes :
option_str(moduleoption *opt, char *name)
Cette fonction retourne la chaîne de caractère correspondant à la valeur de l'option nommée name ou retourne NULL si l'option n'est pas spécifiée dans le fichier de configuration XML. Vous devrez ensuite libérer l'espace mémoire utilisé par la chaîne de caractères retournée en utilisant la fonction free().
option_int(moduleoption *opt, char *name)
Cette fonction est équivalente à option_str().
Elle convertit le contenu de l'option en un entier. Si ce n'est pas possible, ou si l'option n'a pas été trouvée, elle retourne INT_MIN.
Deux options sont toujours définies :
le poids, option weight, qui est toujours un entier (celui donné dans le fichier XML).
Le caractère obligatoire, option mandatory, qui est toujours l'entier 0 ou l'entier 1, en fonction du choix "yes" ou "no" dans le fichier de configuration.
| Attention |
|
Le pointeur vers la liste chaînée des options du module est uniquement passé à la fonction |
Ce module simple montre également l'utilisation des fonctions de rapport d'erreurs qui sont définies dans le fichier error.h. Les fonctions error(), info() et debug() peuvent être utilisées pour rapporter des avertissements et des erreurs variés à l'utilisateur. Elles sont utilisées à peu de chose près comme la fonction printf de la librairie standard.
Vous pouvez aussi constater que la fonction module_init() retourne la valeur 0 .
Cela signifie qu'il n'y a pas d'erreur. Lorsque c'est le cas, cette fonction doit retournée une valeur négative. Cela vaut pour toutes les fonctions de module que nous verrons plus tard. C'est en fait le cas pour la plupart des fonctions de Tablix qui retourne un entier.
Vous devez éviter d'utiliser la fonction fatal() dans les modules, car l'appel de cette fonctionne arrête immédiatement le noyau.
Utilisez error() pour rapporter des erreurs et utilisez ensuite la valeur de retour appropriée pour signaler qu'une erreur fatal est arrivée dans l'exécution du module. Le noyau terminera alors plus proprement.
Il y a deux moyens de compiler votre module. Dans la plupart des cas, vous utiliserez la première méthode. La deuxième, décrite ici, requiert les outils "autotools" récents pour votre système et est recommandée uniquement si vous voulez que le module soit compilé exactement de la même manière que tous les modules officiels de la distribution.
Créer un sous-répertoire dans l'arbre des sources de Tablix, par exemple local/. Nommez le fichier le fichier contenant les sources du module hello.c et sauvegardez le dans le sous-répertoire que vous venez de créer.
Créez maintenant un fichier nommé Makefile, dans le même répertoire, avec le contenu suivant (vous devez utiliser la tabulation pour indenter -mettre en retrait- les lignes !):
CFLAGS = -Wall -O2
INCLUDES = -I../src -I..
MODULES = hello.so
all: $(MODULES)
%.so: %.o
gcc -shared -Wl,-soname,$@ -o $@ $< -lc
%.o: %.c
gcc $(CFLAGS) $(INCLUDES) -c -o $@ $<
clean:
-rm *.o *.so
install:
cp $(MODULES) /usr/local/lib/tablix2
Plus tard, lorsque vous ajouterez d'autres modules personnalisés, vous pourrez ajouter leurs noms à la ligne MODULES =, après hello.so. Assurez-vous de remplacer l'extension .c par .so.
Les modules sont généralement installés dans /usr/local/lib/tablix2, mais cela peut être différent sur votre système, si l'option --prefix a été utilisée pour la configuration de Tablix, ou que les paquets utilisés pour l'installation utilisent un autre chemin.
Vous pouvez connaitre l'endroit où sont enregistrés les modules en exécutant la commande :
$ tablix -v
Modifiez le chemin dans la règle d'installation du Makefile si nécessaire.
Vous pouvez maintenant compiler et installer le module en exécutant les commandes suivantes :
$ make $ make install
Note: Cette méthode requiert une version récente d'Autoconf, d'Automake et des logiciels associés. C'est la méthode utilisée pour compiler les modules officiels de la distribution.
Si vous obtenez des erreurs bizarres pendant l'exécution d'autoconf ou d'automake, cela provient dans 99% des cas d'une mauvaise version des autotools. Les avertissements à propos des "underquoted definitions" sont normales et peuvent être ignorées (elles n'ont rien à voir avec Tablix).
Mettez le fichier des sources de votre module dans le sous-répertoire modules . Vous devez ensuite éditer le fichier Makefile.am . Tout d'abord, ajouter les deux lignes suivantes en fin de fichier
hello_la_SOURCES = hello.c hello_la_LDFLAGS = -module -avoid-version
Ajoutez ensuite hello.la à la fin de la ligne commençant par pkglib_LTLIBRARIES.
Vous devez maintenant exécuter autoconf et automake depuis le répertoire du plus haut niveau et relancer le script ./configure pour rafraîchir les Makefiles existants. Vous pouvez aussi lancer make -f Makefile.cvs si vous utilisez la version CVS.
Vous pouvez maintenant compiler et installer votre modules en lançant les commandes suivantes :
$ make $ make install
Tout d'abord, nous avons besoin d'un fichier de configuration qui utilise notre nouveau module. Parce que ce module simplissime ne fait rien du tout, nous pouvons utiliser un fichier XML aussi simple que possible.
Nous avons simplement besoin de définir une ressource et un évènement pour satisfaire le noyau.
<?xml version="1.0" encoding="iso-8859-1"?>
<ttm version="0.2.0">
<modules>
<module name="hello.so" weight="10" mandatory="yes"/>
</modules>
<resources>
<variable>
<resourcetype type="dummy-type">
<resource name="dummy-resource"/>
</resourcetype>
</variable>
</resources>
<events>
<event name="dummy-event" repeats="1"/>
</events>
</ttm>
Enregistrez cette configuration dans un fichier nommé hello.xml et lancez Tablix.
Comme nous utilisons la fonction debug() dans le module, nous devons lancer Tablix avec l'option -d5 pour voir le message "Bonjour vous !" .
Quelques écrans de messages défileront dans la console pendant l'exécution de Tablix. Puisque le module ne définit aucune valeur d'ajustage, tous les emplois du temps sont affectés d'une valeur d'ajustage nulle et Tablix ne réalisera que quelques centaines de générations avant de déclarer qu'il a trouvé une solution.
Quelque part au début du fichier de sortie, vous trouverez le message "Bonjour vous !".
$ tablix2 -d5 hello.xml
TABLIX version 0.2.1, PGA general timetable solver
Copyright (C) 2002-2005 Tomaz Solc
[tablix] PGA using 4 nodes on 1 host
[tablix] maximum 1 node will do local search
[tablix] multicasting XML data
[tablix] Initializing nodes
...
[xxxxx] xmlsup: variable dummy-type: 1 resources
[xxxxx] xmlsup: Loading module /home/avian/software/lib/tablix2/hello.so
[xxxxx] xmlsup: Bonjour vous !
[xxxxx] xmlsup: Weight: 10
[xxxxx] kernel: I have 1 tuples
...