• Aucun résultat trouvé

La compilation séparée

N/A
N/A
Protected

Academic year: 2022

Partager "La compilation séparée"

Copied!
20
0
0

Texte intégral

(1)

La compilation séparée

Thèmes abordés

• La compilation séparée

Déco page de projets en fichiers séparés – Découpage de projets en fichiers séparés – Compilation séparée

– Conception de bibliothèques

(2)

Introduction

• Constat

Logiciel : intégration de nombre ses fonctionnalités – Logiciel : intégration de nombreuses fonctionnalités.

– Les logiciels ont tendance à croître fortement en taille.

• Difficile de comprendre un très long fichier de code source.

• Modification d’une ligne -> recompilation de tout le fichier.

– Temps de compilation de plus en plus élevés.

• Objectif

– Décomposer un logiciel volumineux en modules

Analyse et programmation 2 - La compilation séparée 2

p g

La compilation séparée

Principes généraux

module module module

1 immense fichier contenant tout le programme

module

module module

module module

d l module

module module

(3)

Analyse

• Avantages

Ecrit re de mod les pl s petits pl s faciles à comprendre – Ecriture de modules plus petits, plus faciles à comprendre.

– Recompilation d’un module -> plus rapide.

– Donne une structure plus lisible au programme.

– Possibilité de réutilisation de certains modules.

• Mais cela requiert :

– Un petit travail d’analyse supplémentaire.

Un petit effort de mise en place des modules

Analyse et programmation 2 - La compilation séparée 4

– Un petit effort de mise en place des modules.

– Effort rapidement compensé par les bénéfices.

La compilation séparée

La chaîne de compilation du langage C - rappel

main.c stdlib.h stdio.h

fichier1.c

2. Compilateur Code source complet 1. Préprocesseur de texte

Exécutable complet main.o

3. Editeur de liens

crt.lib fichier1.o

(4)

Constitution d’un module

• Que peut apporter un module ?

– Des inclusions – Des inclusions.

– Des définitions de symboles.

– Des types de données.

– Des constantes, des variables.

– Des fonctions.

• Structure d’un module en langage C

– Fichier en-tête : .h l dé l

Analyse et programmation 2 - La compilation séparée 6

• Comporte toutes les déclarations.

• Décrit les services offerts par le module.

• C’est l’interface du module.

– Fichier source : .c

• Comporte l’implémentation.

La compilation séparée

Première solution – Répétition des prototypes

voidrotation(vecteur_plan* u, double angle) {

fichier vecteur_plan.c

voidrotation(vecteur_plan* u, double angle);

traitement_image.c {

vecteur_plan copie;

copie = *u;

u->x = copie.x * cos(angle) – copie.y * sin(angle);

u->y = copie.x * sin(angle) + copie.y * cos(angle);

}

. . . . recalage_image() {

rotation(. . . .);

}

voidrotation(vecteur_plan* u, double angle);

main.c

. . . . main()

Que se passe-t-il si on

(5)

Première solution – Répétition des prototypes - Conséquences

• Propagation des modifications

Une modification de protot pe doit être propagée dans to s les – Une modification de prototype doit être propagée dans tous les

fichiers utilisateurs.

– Travail fastidieux.

– Coûteux en temps.

– Risque d’oubli

• Avec des conséquences fatales pour le logiciel.

Analyse et programmation 2 - La compilation séparée 8

La compilation séparée

Constitution d’un module – utilisation de fichiers en-tête

#

fichier vecteur_plan.h

#

fichier vecteur_plan.c

#define _USE_MATH_DEFINES

#include <math.h>

#define TAILLE_LISTE 1000 typedef struct

{

double x, y;

} vecteur_plan;

const vecteur_plan I = { 1.0, 0.0 };

const vecteur_plan J = { 0.0, 1.0 };

#include "vecteur_plan.h"

double produit_scalaire(vecteur_plan u, vecteur_plan v)

{

return u.x * v.x + u.y * v.y;

}

voidrotation(vecteur_plan* u, double angle) {

vecteur_plan copie;

copie = *u;

u->x = copie.x * cos(angle) – double produit_scalaire(vecteur_plan u,

vecteur_plan v);

void rotation(vecteur_plan* u, double angle);

u >x copie.x cos(angle) copie.y * sin(angle);

u->y = copie.x * sin(angle) + copie.y * cos(angle);

}

(6)

Exemple d’utilisation

vecteur_plan.h Inclusion multiple de vecteur_plan.h !

graphique.h

graphique.c

trajectoire.h

trajectoire.c

vecteur_plan.c

Analyse et programmation 2 - La compilation séparée 10

main.c

Problème à la compilation

Error 1:'vecteur_plan' : redefinition; different basic types vecteur_plan.h 9

La compilation séparée

Conséquences de la double inclusion

#include "trajectoire.h"

main.c

#include "vecteur plan.h"

trajectoire.h

typedef struct vecteur_plan.h j

#include "graphique.h" _p yp

{

double x, y;

} vecteur_plan;

#include "vecteur_plan.h"

graphique.h

typedef struct {

vecteur_plan.h {

double x, y;

} vecteur_plan;

Définition multiple de vecteur_plan !

(7)

Protection contre la duplication des définitions

#ifndef __VECTEUR_PLAN_H_

#define __VECTEUR_PLAN_H_

#define _USE_MATH_DEFINES

#include <math.h>

#define TAILLE_LISTE 1000 typedef struct

{

double x, y;

} vecteur_plan;

Analyse et programmation 2 - La compilation séparée 12

constvecteur_plan I = { 1.0, 0.0 };

constvecteur_plan J = { 0.0, 1.0 };

double produit_scalaire(vecteur_plan u, vecteur_plan v);

void rotation(vecteur_plan* u, double angle);

#endif

La compilation séparée

Problème de définition multiple des constantes et variables

Problème à la liaison

Error 1 error LNK2005: I already defined in main.obj vecteur plan.obj_ y j _p j Error 2 error LNK2005: _J already defined in main.obj vecteur_plan.obj Error 3 error LNK2005: _I already defined in main.obj trajectoire.obj Error 4 error LNK2005: _J already defined in main.obj trajectoire.obj Error 5 fatal error LNK1169: one or more multiply defined symbols found

#include "trajectoire.h"

main.c

vecteur plan h trajectoire.h

#include "vecteur_plan.h"

c

constvecteur_plan I = { 1.0, 0.0 };

constvecteur_plan J = { 0.0, 1.0 };

vecteur_plan.h

#include "trajectoire.h"

trajectoire.c

_I _J main.obj

_I _J trajectoire.obj

compilation

(8)

Comment éviter les définitions multiples - extern

#

fichier vecteur_plan.h

#

fichier vecteur_plan.c

#ifndef __VECTEUR_PLAN_H_

#define __VECTEUR_PLAN_H_

#define _USE_MATH_DEFINES

#include <math.h>

#define TAILLE_LISTE 1000 typedef struct

{

double x, y;

} vecteur_plan;

#include "vecteur_plan.h"

constvecteur_plan I = { 1.0, 0.0 };

constvecteur_plan J = { 0.0, 1.0 };

double produit_scalaire(vecteur_plan u, vecteur_plan v) {

return u.x * v.x + u.y * v.y;

}

voidrotation(vecteur_plan* u, double angle)

Analyse et programmation 2 - La compilation séparée 14

extern const vecteur_plan I;

extern const vecteur_plan J;

double produit_scalaire(vecteur_plan u, vecteur_plan v);

void rotation(vecteur_plan* u, double angle);

#endif

double angle) {

vecteur_plan copie;

copie = *u;

u->x = copie.x * cos(angle) - copie.y * sin(angle);

u->y = copie.x * sin(angle) + copie.y * cos(angle);

La compilation séparée

Partage de constantes et de variables

• Dans le fichier en-tête (.h)

extern type variable;

extern type variable;

extern const type constante;

• Dans le fichier source (.c)

type variable;

const type constante = valeur;

(9)

Structure du projet

Analyse et programmation 2 - La compilation séparée 16

Tous les fichiers .c doivent être inclus dans le projet.

Chaque .c produit un .obj

La compilation séparée

Recette de cuisine – le fichier .h

#ifndef __VECTEUR_PLAN_H_

#define VECTEUR PLAN H

Protection contre l’inclusion multiple

#ifndef

#define . . .

#endif // Tout à la fin du fichier Vecteur_plan.h

#define __VECTEUR_PLAN_H_

#define _USE_MATH_DEFINES

#include <math.h>

#define TAILLE_LISTE 1000 typedef struct

{

double x, y;

} vecteur_plan;

extern const vecteur_plan I;

#endif // Tout à la fin du fichier

Inclusion des fichiers contenant des symboles utilisés dans ce .h

Définition de symboles.

Définition de types.

extern const vecteur_plan J;

double produit_scalaire(vecteur_plan u, vecteur_plan v);

voidrotation(vecteur_plan* u, double angle);

#endif

Déclarations de constantes et variables globales partagées précédées par « extern »

Déclaration de prototypes de fonctions.

(10)

Recette de cuisine – le fichier .c

#include "vecteur_plan.h"

Inclusion du .h

Définition des constantes et variables Vecteur_plan.c

constvecteur_plan I = { 1.0, 0.0 };

constvecteur_plan J = { 0.0, 1.0 };

double produit_scalaire(vecteur_plan u, vecteur_plan v) {

return u.x * v.x + u.y * v.y;

}

voidrotation(vecteur_plan* u, double angle) {

vecteur plan copie;

Définition des fonctions dont le prototype est dans le .h, ou de nouvelles fonctions.

globales partagées précédées par « extern »

Analyse et programmation 2 - La compilation séparée 18

vecteur_plan copie;

copie = *u;

u->x = copie.x * cos(angle) - copie.y * sin(angle);

u->y = copie.x * sin(angle) + copie.y * cos(angle);

La compilation séparée

Recompilation efficace d’un projet

• Compilation incrémentale

To s les fichiers c n’ont pas besoin d’être recompilés à chaq e – Tous les fichiers .c n’ont pas besoin d’être recompilés à chaque

changement d’un fichier source.

– En exploitant le graphe de dépendances, le compilateur détermine quels fichiers doivent être recompilés.

– Temps de compilation divisés par 10 ou plus !

(11)

Recompilation – quel module doit être recompilé après un changement ?

vecteur plan h

graphique.h trajectoire.h

vecteur_plan.h

vecteur_plan.c

Analyse et programmation 2 - La compilation séparée 20

main.c

graphique.c trajectoire.c

modifié

modifié

recompilé

La compilation séparée

Recompilation – quel module doit être recompilé après un changement ?

vecteur plan h

graphique.h trajectoire.h

vecteur_plan.h

vecteur_plan.c

main.c

graphique.c modifié trajectoire.c

modifié

recompilé

(12)

Recompilation – quel module doit être recompilé après un changement ?

vecteur plan h

graphique.h trajectoire.h

vecteur_plan.h

vecteur_plan.c

modifié

Analyse et programmation 2 - La compilation séparée 22

main.c

graphique.c trajectoire.c

modifié

recompilé

La compilation séparée

Recompilation – quel module doit être recompilé après un changement ?

vecteur plan h modifié

graphique.h trajectoire.h

vecteur_plan.h

vecteur_plan.c modifié

graphique.c trajectoire.c

(13)

La compilation séparée

Types de compilation avec Visual Studio

tous les projets de la solution

Compilation complète de tous les projets de la solution

Effacement de tous les .obj de tous les projets de la solution

Compilation incrémentale du projet en cours

Compilation complète du projet en cours

Analyse et programmation 2 - La compilation séparée 24

projet en cours

Effacement de tous les .obj de tous les projets de la solution.

La compilation séparée

Problèmes potentiels – incohérence des prototypes

#

fichier main.c

#

fichier vecteur_plan.c

#include <stdio.h>

#include <stdlib.h>

#include "vecteur_plan.h"

int main() {

vecteur_plan v1 = { 3.0, 4.0 };

double norme1;

norme1 = norme(v1);

printf("Norme du vecteur v1"

"(%lf, %lf) : %lf\n", v1.x, v1.y, norme1);

#include "vecteur_plan.h"

double produit_scalaire(vecteur_plan u, vecteur_plan v) {

return u.x * v.x + u.y * v.y;

}

double norme(vecteur_plan u) {

return sqrt(produit_scalaire(u, u));

} v1.x, v1.y, norme1);

system("PAUSE");

return 0;

}

(14)

Problèmes potentiels – incohérence des prototypes

• Absence de prototype dans le .h

Par défa t la fonction norme est considérée comme étant – Par défaut, la fonction norme est considérée comme étant

int norme(vecteur_plan u);

– Or, elle retourne un double.

– Aucune détection du problème par le compilateur.

• Résolution

– Ajouter simplement le prototype de norme dans vecteur_plan.h double norme(vecteur plan u);

Analyse et programmation 2 - La compilation séparée 26

double norme(vecteur_plan u);

La compilation séparée

Problèmes potentiels – recompilation incohérente

• Manque de fiabilité de la gestion des graphes de dépendance

dépendance

– Rencontrée lors du remplacement d’un fichier source par un fichier plus ancien.

• En cas de doute:

– Toujours forcer la recompilation complète.

– Surtout avant un test en vraie grandeur.

(15)

Graphe de dépendance – références circulaires

#

fichier a.h

#

fichier b.h

#include "fichier_b.h" #include"fichier_a.h"

NON COMPILABLE

Analyse et programmation 2 - La compilation séparée 28

Problème à la compilation

Error 1 fatal error C1014: too many include files : depth = 1024 fichier_b.h 1 main.c

La compilation séparée

Graphe de dépendance – résolution des références circulaires

fichier a.h fichier b.h

#include "fichier_a.h"

#include "fichier_b.h"

fichier a.c

#include"fichier_a.h"

#include"fichier_b.h"

fichier b.c

main.c

Solution :

-Eliminer la dépendance entre interfaces (.h)

-Conserver la dépendance entre implémentations (.c)

(16)

Bibliothèques distribuables

• La compilation séparée

Permet de créer des fichiers h et c indépendants – Permet de créer des fichiers .h et .c indépendants.

– Pouvant contenir des fonctions d’usage général.

– Pouvant être réutilisées sur plusieurs projets.

• On ne souhaite pas toujours livrer le code source (.c)

– Il contient une propriété intellectuelle à protéger.

– L’intégration de fichiers .c entraine des temps de compilation.

C t di t ib l f ti li l ?

Analyse et programmation 2 - La compilation séparée 30

• Comment distribuer les fonctions sans livrer les sources ?

La compilation séparée

Bibliothèques distribuables - Exemple

• Livraison de

To s les fichiers h

vecteur_plan.h

– Tous les fichiers .h

– Tous les fichiers compilés .obj

trajectoire.obj Vecteur_plan.obj

graphique.obj graphique.h

• Malcommode

trajectoire.h

(17)

Bibliothèques distribuables – Exemple – Livraison empaquetée

• Livraison de

To s les fichiers h pl s n fichier q i incl t to s les a tres

Robotique.lib

vecteur_plan.h

– Tous les fichiers .h, plus un fichier qui inclut tous les autres.

– Tous les fichiers compilés rassemblés dans un seul fichier .lib.

Vecteur_plan.obj

graphique.obj graphique.h

robotique.h

Analyse et programmation 2 - La compilation séparée 32

• Plus commode

– Il faut inclure seulement robotique.h dans les programmes – Il faut lister seulement robotique.lib dans les options du lieur.

trajectoire.obj trajectoire.h

La compilation séparée

Bibliothèques distribuables - création

• La plupart des outils de développement C

Permettent de créer n lib à partir de obj – Permettent de créer un .lib à partir de .obj

• Avec Visual Studio

– Il existe un modèle de projet appelé « static library » – Lister simplement les

fichier de code source .c – La compilation produit

un fichier .lib

(18)

Bibliothèques distribuables - utilisation

• Les fichiers .h doivent se trouver

A n emplacement conn d compilate r : #incl de – A un emplacement connu du compilateur : #include <>

– Ou dans le répertoire du projet : #include " "

• Le fichier .lib

– Doit être fourni explicitement au lieur

– Une option de liaison existe avec tous les outils.

• Avec Visual studio, paramétrage dans les options de projet.

Analyse et programmation 2 - La compilation séparée 34

La compilation séparée

Bibliothèques distribuables - utilisation

(19)

Qu’avons-nous appris ?

• Comment utiliser la compilation séparée pour modulariser

modulariser.

• Comment gérer les problèmes liés à l’inclusion multiple.

• Comment partager des fonctions, des variables, des constantes entre modules.

• L’importance des prototypes avec la compilation séparée.

Analyse et programmation 2 - La compilation séparée 36

• Comment distribuer une bibliothèque de fonctions réutilisable.

Vos questions

(20)

Références

Documents relatifs

Reprendre l'exercice 1 de la partie TP7, et rajouter comme fonctionnalité à votre programme, le fait de pouvoir stocker les notes saisies dans un fichier, et de pouvoir

Par rapport à la stratégie adoptée par S MART E IFFEL , les avantages sont forcément plus modestes : la qualité de l’analyse de types peut être identique dans les deux approches,

Pour cette raison, les variables et fonctions qui repr´esentent ou renvoient des caract`eres sont souvent d´eclar´ees int, non char : n’importe quelle valeur appartenant au type

plus pauvres. Stimuler l’application des technologies dans une optique de réduction des coûts. Accroître les services dans les zones rurales, reculées et peu peuplées. Renforcer

Tolman (1886-1959), béhavioriste “rebelle” 5Nécessité d’aménager des moments d’« explorations libres » des élèves dans des situations d’apprentissage,

Aussi si vous avez choisi de venir ici pour aider l’humanité, pour remplir votre mission d’éveil de conscience tout autour de vous, chacun et chacune à votre

Il est question à travers cette étude de faire un diaporama de la gouvernance de la forêt Boucher dans la ville de Gatineau, en s’intéressant particulièrement

Résultats : vitesse au dernier palier complété Tests Triangulaires.. ➢ Il existe deux protocoles