compilation séparée et librairies
compilation séparée et librairies
next: dépendances entre modules
up: modularité
previous: interfaces et modules
compilation séparée et librairies
la compilation d'un programme consiste à fabriquer le binaire
exécutable par le processeur de la machine. pour des programmes de
plusieurs milliers de lignes, il est bon de les découper en des
fichiers compilés séparément. dans la suite, chaque module
d'implémentation sera confondu avec un fichier source, et la notion de
module correspondra donc à la notion de fichier. la compilation
séparée dépend beaucoup du système d'exploitation utilisé (unix,
mac/os, ms-dos). dans le cas d'unix, la commande
% pc -c files-de-caracteres.p
permet d'obtenir le fichier binaire relogeable
files-de-caracteres.o qui peut être relié à d'autres modules
compilés indépendamment. supposons qu'un fichier tty.p
contenant un gestionnaire de terminaux utilise les fonctions sur les
files de caractères. en unix, on devra compiler séparément tty.p
et relier les deux binaires obtenus, ce qui s'obtient en écrivant
% pc -c tty.p
% pc -o tty tty.o files-de-caracteres.o
le binaire exécutable résultat est dans le fichier
tty. graphiquement, les phases de compilation sont représentées
par la figure .
figure: compilation séparée
quand il y a un grand nombre de fichiers binaires relogeables à relier
entre eux, par exemple tous ceux qui permettent de faire fonctionner
un gros système comme x-window, on peut pré-relier tous les binaires
relogeables entre eux dans une librairie, par exemple
libx11.a pour x-window. et la commande
% pc -o tty tty.o files-de-caracteres.o libx11.a
permet de relier les deux fichiers .o avec les
fichiers nécessaires dans libx11.a.
en thinkpascal, la notion de projet permet de combiner un
certain nombre de fichiers pascal comme files-de-caracteres.p
et tty.p, ainsi qu'un certain nombre de librairies. la commande
run exécute des commandes de compilation séparée et d'édition
de lien analogues à celles d'unix.
essayons à présent de faire coincider les notions de modules et de
compilation séparée. en pascal bsd (sur vax), on peut se servir des
fichiers include pour les interfaces, et de la directive
external. une fonction externe est une fonction qui se
trouvera dans un autre module compilé séparément. elle a le même
format que la directive forward (cf appendice a). en pascal
bsd, on peut inclure un fichier avant la partie implémentation ou
utilisatrice de l'interface. dans le cas des files de caractères, on
pourra avoir le fichier interface files-de-caracteres.h suivant
const
fctaillebloc = 12;
type
fctype = ^cellule; (* - *)
blocptr = ^bloc;
basedeplacement = record
b: blocptr;
d: integer;
end;
cellule = record
cc: integer;
debut, fin: basedeplacement;
end;
bloc = record
suivant: blocptr;
contenu: array[1..fctaillebloc] of char;
end;
procedure fcinit;
(* - *)
(* - *)
external;
procedure fcvide (var x: fctype);
(* - *)
external;
procedure fcajouter (x: fctype; c: char);
(* - *)
external;
function fcsupprimer (x: fctype): char;
(* - *)
(* - *)
external;
remarquons que la syntaxe acceptée par pascal, nous interdit
de cacher le corps de la structure de donnée fctype. pour
l'utilisation de l'interface, le fichier tty.p sera
program tty;
#include "files-de-caracteres.h"
... un programme ou un module normal
end.
et la partie implémentation files-de-caracteres.p sera
#include "files-de-caracteres.h"
var listelibre: blocptr;
procedure fcinit;
var i: integer;
bp: blocptr;
begin
listelibre := nil;
for i := 1 to fcnbblocs do
begin
new(bp); bp^.suivant := listelibre;
listelibre := bp;
end;
end;
procedure fcajouter {x: fctype; c: char};
var bp: blocptr;
begin
if x^.cc = 0 then
...
on a inclut le fichier d'interface pour au moins garantir
que les types des objets manipulés par le corps des programmes sont du
type indiqué par l'interface. a ce propos, pascal interdit de
redéclarer la signature des fonctions external, comme pour les
directives forward. donc nous avons mis des accolades de
commentaires plutôt que des parenthèses dans la définition de
fcajouter. en thinkpascal, il faut utiliser des directives très
spécifiques unit, uses et implementation. le
fichier files-de-caracteres.p devient:
unit filesdecaracteres;
interface
-
-
implementation
-
end.
et le fichier utilisateur tty.p
program tty;
uses filesdecaracteres;
le reste du programme
on peut remarquer que think autorise à redéclarer la
signature des fonctions dans la partie implémentation. de même, il
n'est pas nécessaire de mettre external après les définitions
de l'interface. en think, il faut bien faire attention à mettre les
modules dans le bon ordre dans le projet pour que la compilation se
passe bien.
mais nous allons garder uniquement la technique de pascal
bsd, car elle est très similaire à ce que l'on fait dans le langage c
avec le préprocesseur (cf la section ).
enfin, on doit encore remarquer qu'il est très difficile de cacher les
noms des objets privés d'un module en pascal. pour les types, nous
avons vu que le langage nous impose de rendre publics les composants
du type. pour les variables et fonctions, les noms sont toujours
déclarés comme externes par l'éditeur de liens d'unix,
contrairement à c (voir la directive static de la section
). si on veut éviter les collisions entre noms
identiques de variables ou de fonctions différentes de modules
différents, il est préférable d'utiliser le nom du module comme
préfixe des noms de variables ou de fonctions privées du module (comme
nous l'avons fait pour fc_nouveaubloc). le principe de coupler
les notions de compilation séparée et de modules est donc de se servir
de l'éditeur de liens pour rendre inaccessibles les variables cachées
d'un module.
next: dépendances entre modules
up: modularité
previous: interfaces et modules
compilation séparée et librairies Précédent 434 Précédent 433 Précédent 432 Précédent 431 Précédent 430 Précédent 429 Précédent 428 Précédent 427 Précédent 426 Précédent 425 Précédent 424 Précédent 423 Précédent 422 Précédent 421 Précédent 420 Précédent 419 Précédent 418 Précédent 417 Précédent 416 Précédent 415 Précédent 414 Précédent 413 Précédent 412 Précédent 411 Précédent 410 Précédent 409 Précédent 408 Précédent 407 Précédent 406 Précédent 405 Suivant 436 Suivant 437 Suivant 438 Suivant 439 Suivant 440 Suivant 441 Suivant 442 Suivant 443 Suivant 444 Suivant 445 Suivant 446 Suivant 447 Suivant 448 Suivant 449 Suivant 450 Suivant 451 Suivant 452 Suivant 453 Suivant 454 Suivant 455 Suivant 456 Suivant 457 Suivant 458 Suivant 459 Suivant 460 Suivant 461 Suivant 462 Suivant 463 Suivant 464 Suivant 465