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 :
-
0 : l'expansion n'est autorisée que lorsqu'elle n'accroît
pas la taille du code ;
- 1 : c'est la valeur par défaut, elle accepte une légère
augmentation de la taille du code ;
- n > 1 : augmente la tolérance d'accroissement de la taille
du code expansé.
Boucle d'interaction
La boucle d'interaction ne possède que deux options pour son lancement :
-
-I catalogue : qui ajoute le chemin indiqué en tête de
la liste des chemins de recherche des fichiers sources ou compilés ;
- -unsafe : qui indique au compilateur de ne plus tester
les débordements d'indice de tableaux ou de chaînes de
caractères.
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.