Précédent Index Suivant

Modes de compilation

La distribution d'un langage dépend du processeur et du système d'exploitation. Pour chaque architecture (couple processeur, système d'exploitation), une distribution d'Objective CAML contient la boucle d'interaction, le compilateur de code-octet et dans la plupart des cas le compilateur natif sur cette architecture.

Noms des commandes

La figure 7.5 donne les noms des commandes des différents compilateurs que l'on rencontre dans les distributions d'Objective CAML. Les quatre premières commandes sont disponibles pour toute distribution.


ocaml boucle d'interaction
ocamlrun interprète de code-octet
ocamlc compilateur en ligne de code-octet
ocamlopt compilateur en ligne de code natif
ocamlc.opt compilateur en ligne optimisé de code-octet
ocamlopt.opt compilateur en ligne optimisé de code natif
ocamlmktop constructeur de nouvelles boucles d'interaction

Figure 7.5 : Commandes de compilation


Les compilateurs optimisés ont été eux-mêmes compilés avec le compilateur natif, produisant un exécutable plus rapide.

Unité de compilation

L'unité de compilation correspond à la plus petite décomposition d'un programme Objective CAML pouvant être compilée. Pour la boucle d'interaction, l'unité de compilation correspond à une phrase du langage. Par contre pour les compilateurs en ligne, l'unité de compilation est un couple de fichiers  : le fichier source et le fichier interface. Le fichier interface est optionnel. S'il n'existe pas, alors toutes les déclarations globales du fichier source seront visibles par une autre unité de compilation. La construction des fichiers d'interface sera décrite dans le chapitre sur la programmation modulaire (14). La liaison entre ces deux fichiers utilise les conventions de nommage des extensions de fichiers.

Nommage des extensions de fichiers

La figure 7.6 présente les extensions des différents fichiers utilisés pour les programmes Objective CAML et C.


extension signification
.ml fichier source
.mli fichier interface
.cmo fichier objet (code-octet)
.cma fichier d'une bibliothèque objet (code-octet)
.cmi fichier interface compilé
.cmx fichier objet (natif)
.cmxa fichier d'une bibliothèque objet (natif)
.c fichier source C
.o fichier objet C (natif)
.a fichier d'une bibliothèque objet C (natif)

Figure 7.6 : Extension des fichiers


Les fichiers exemple.ml et exemple.mli forment une unité de compilation. Le fichier d'interface compilé (exemple.cmi) est commun au compilateur de code-octet et au compilateur natif. Les fichiers provenant du monde C sont utilisés pour l'interfaçage de Objective CAML avec des bibliothèques C (12).

Compilateur de code-octet

La forme générale de la commande d'un compilateur en ligne est la suivante :



Objective CAML suit la même règle. On tapera, par exemple :
ocamlc -c exemple.ml
Les options passées au compilateur sur la ligne de commande suivent les conventions du système Unix. Elles sont précédées du caractère -. Les extensions des fichiers sont interprétées de la manière décrite à la figure 7.6. Dans l'exemple ci-dessus, le fichier exemple.ml est considéré comme un fichier source Objective CAML et sera donc compilé, ce qui produira les fichiers exemple.cmo et exemple.cmi car l'option -c indique au compilateur de n'engendrer que le code objet. Sans cette option, le compilateur ocamlc produit aussi un fichier exécutable a.out, c'est-à- dire qu'il effectue aussi l'édition de liens.

Le tableau de la figure 7.7 décrit les principales options du compilateur de code-octet. Le tableau de la figure 7.8 indique les autres options possibles.

Principales options
-a construit une bibliothèque
-c compile sans faire l'édition de liens
-o nom_executable spécifie le nom de l'exécutable
-linkall indique de lier avec toutes les bibliothèques utilisées
-i affiche toutes les déclaration globales compilées
-pp commande utilise commande comme pré-processeur
-unsafe bascule en mode sans vérification des indices
-v affiche la version du compilateur
-w liste choisit selon liste le niveau des messages d'avertissement (voir fig. 7.9)
-impl fichier indique que fichier est un source Caml (.ml)
-intf fichier indique que fichier est une interface Caml (.mli)
-I catalogue ajoute catalogue dans la liste des catalogues

Figure 7.7 : Principales options du compilateur de code-octet



Autres options
processus légers -thread (19, page ??)
mise au point -g, -noassert (10, page ??)
exécutables autonomes -custom, -cclib, -ccopt, -cc (voir page ??)
runtime -make-runtime , -use-runtime
interface C -output-obj (12, page ??)

Figure 7.8 : Autres options du compilateur de code-octet


Pour obtenir l'affichage de l'ensemble des options du compilateur de code-octet, il suffit de lui passer l'option -help.

Les niveaux de message d'avertissement (warning) sont décrits à la figure 7.9. Un niveau de message est une bascule (activée/désactivée) représentée par une lettre. Une majuscule active ce niveau et une minuscule le désactive.

Principaux niveaux  
A/a active/désactive tous les messages
F/f application partielle dans une séquence
P/p pour les filtrages incomplets
U/u pour les cas inutiles d'un filtrage
X/x active/désactive tous les autres messages
pour la couche objet M/m et V/v (voir chapitre 15)

Figure 7.9 : Description des avertissements de compilation


Par défaut le niveau maximal (A) est choisi par le compilateur.

Un exemple d'utilisation du compilateur de code-octet est donné figure 7.10.



Figure 7.10 : Session avec le compilateur de code-octet


Compilateur natif

Le compilateur natif possède un comportement proche de celui du compilateur de code-octet bien que les fichiers produits soient différents. Les options de compilation sont globalement les mêmes que celles décrites aux figures 7.7 et 7.8. Il faut cependant retirer les options liées au runtime de la figure 7.8. Les options spécifiques au compilateur natif sont données à la figure 7.11. Les différents niveaux de warning sont les mêmes.

-compact optimise en espace le code produit
-S conserve le code assembleur dans un fichier
-inline niveau indique le grain de traduction d'une fonction à plat

Figure 7.11 : Options particulières pour le compilateur natif.


L'expansion en ligne (inlining) est une version élaborée de la macro-expansion du prétraitement. Elle remplace l'appel d'une fonction par le corps de la fonction où les arguments sont fixés. Plusieurs appels différents correspondront à une nouvelle traduction du corps de la fonction. On évite ainsi d'exécuter la séquence d'appel de fonction, mais la taille du code peut s'en trouver accrue. Les principaux niveaux d'inlining sont :

Boucle d'interaction

La boucle d'interaction ne possède que deux options pour son lancement : La boucle d'interaction possède plusieurs directives de compilation qui permettent de modifier interactivement son comportement. Elles sont décrites à la figure 7.12. Toutes les directives commencent par le caractère # et se terminent par les habituels ;;.

#quit;; sort de la boucle d'interaction
#directory catalogue ;; ajoute un chemin en tête
#cd catalogue ;; change de catalogue courant
#load fichier_objet ;; charge un fichier .cmo
#use fichier_source ;; compile et charge un fichier source
#print_depth profondeur ;; modifie la profondeur d'affichage
#print_length largeur ;; idem pour la largeur
#install_printer fonction ;; spécifie une fonction d'affichage
#remove_printer fonction ;; repasse à l'afficheur standard
#trace fonction ;; trace les arguments d'une fonction
#untrace fonction ;; enlève la trace d'une fonction
#untrace_all ;; enlève toutes les traces

Figure 7.12 : Directives de la boucle d'interaction


Les directives sur les catalogues respectent les conventions du système d'exploitation utilisé.

Les directives de chargement n'ont pas exactement le même comportement. La directive #use lit le fichier source indiqué comme s'il avait été tapé directement en interactif. La directive #load charge le fichier d'extension .cmo indiqué. Dans ce dernier cas, les déclarations globales de ce fichier ne sont pas directement accessibles.
Pour cela il faut utiliser la notation pointée. Si le fichier exemple.ml contient la déclaration globale f, alors une fois chargé le code-octet (#load "exemple.cmo";;), on accédera à la valeur de f par Exemple.f, où la première lettre du fichier est remplacée par une majuscule. Cette notation vient du système de modules d'Objective CAML (voir chapitre 14, page ??).

Les directives de paramétrage de la profondeur et de la largeur d'affichage permettent de contrôler l'affichage des valeurs. Ce qui est utile quand des valeurs volumineuses doivent être affichées.

Les directives de redéfinition des fonctions d'impression pour des types donnés permettent de définir leur présentation. Pour qu'elles s'intègrent bien avec l'affichage par défaut, il sera nécessaire d'utiliser la bibliothèque Format (8) pour les définir.

Les directives de traçage des arguments et du résultat de fonctions sont particulièrement utiles pour la mise au point des programmes. Elles seront manipulées au chapitre sur l'analyse de programme (10).

La figure 7.13 montre une session avec la boucle d'interaction.



Figure 7.13 : Session avec la boucle d'interaction


Construction de nouvelles boucles d'interaction

La commande ocamlmktop permet de construire de nouvelles boucles d'interaction dans lesquelles un certain nombre de bibliothèques ou modules sont préchargés. Outre le fait de ne plus avoir besoin d'effectuer les #load en début de session, cela est indispensable pour intégrer des bibliothèques écrites en C car il est alors nécessaire de modifier la bibliothèque d'exécution.

Les options de cette commande sont un sous-ensemble des options du compilateur de code-octet (ocamlc) :
-cclib libname, -ccopt option, -custom, -I catalogue et -o nom_executable
Le chapitre sur la programmation graphique (5, page ??) utilise cette commande pour construire un toplevel contenant la bibliothèque Graphics de la manière suivante :
ocamlmktop -custom -o mytoplevel graphics.cma -cclib \ 
           -L/usr/X11/lib -cclib -lX11
Cette commande construit l'exécutable de nom mytoplevel, contenant la bibliothèque de code-octet graphics.cma. Cet exécutable autonome (-custom (voir section suivante) sera lié à la bibliothèque X11 (libX11.a) qui elle-même sera recherchée dans le chemin /usr/X11/lib.


Précédent Index Suivant