Vous êtes sur la page 1sur 9

La compilation spare en C

par Jessee Michal C. Edouard (Accueil)


Date de publication : 14 avril 2008 Dernire mise jour : 08 dcembre 2009

La compilation spare dsigne le fait de compiler plusieurs fichiers sources sparment puis de les lier ensuite pour gnrer le produit final qui peut tre un excutable par exemple. Elle comprend plusieurs techniques que nous allons explorer tout au long de ce tutoriel. Commentez cet article :

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

I - Gnralits.............................................................................................................................................................. 3 I-A - Compilation d'un projet.................................................................................................................................. 3 I-A-1 - Introduction............................................................................................................................................ 3 I-A-2 - Exemple avec un projet constitu de deux fichiers sources................................................................. 3 I-A-2-a - Le projet........................................................................................................................................ 3 I-A-2-b - Compilation sous Code::Blocks.................................................................................................... 3 I-B - Le mot-cl extern........................................................................................................................................... 4 I-C - Le mot-cl static............................................................................................................................................ 4 I-D - Les fichiers d'en-tte......................................................................................................................................4 I-E - Les structures opaques..................................................................................................................................5 II - Les bibliothques................................................................................................................................................... 6 II-A - Introduction....................................................................................................................................................6 II-B - Les bibliothques statiques...........................................................................................................................7 II-C - Les bibliothques dynamiques..................................................................................................................... 7 II-D - Applications. Exemples................................................................................................................................. 9 II-D-1 - La bibliothque standard du langage C...............................................................................................9 II-D-2 - Le concept d'API.................................................................................................................................. 9 III - Conclusion.............................................................................................................................................................9

-2Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

I - Gnralits I-A - Compilation d'un projet I-A-1 - Introduction


Un projet d'application en langage C est au moins constitu d'un fichier source qui sera compil, ce qui donnera un fichier objet en sortie, puis li d'autres fichiers objets pour gnrer la sortie finale qui peut tre un excutable par exemple. Dans le cas gnral, un projet est constitu de plusieurs fichiers sources.

I-A-2 - Exemple avec un projet constitu de deux fichiers sources I-A-2-a - Le projet
Nous allons crer un programme qui affiche la somme et le produit de deux nombres entiers en sparant le programme et les fonctions (somme et produit) dans deux fichiers diffrents. Fichier : exemple.c
#include <stdio.h> int somme(int a, int b); int produit(int a, int b); int main() { int a = 2, b = 5; printf("%d + %d = %d\n", a, b, somme(a, b)); printf("%d * %d = %d\n", a, b, produit(a, b)); } return 0;

Fichier : somme.c

int somme(int a, int b) { return a + b; } int produit(int a, int b) { int prod = 0; while (b-- > 0) prod += a; } return prod;

I-A-2-b - Compilation sous Code::Blocks


Pour compiler le projet, slectionnez la commande Build > Build (Ctrl + F9). Cette compilation se fait en deux phases : compilation des fichiers sources (exemple.c et fonctions.c) puis dition des liens. On peut aussi compiler les fichiers sources individuellement : Build > Compile Current File (Ctrl + Shift + F9). Dans ce cas la commande Build (Ctrl + F9) ne fera plus que l'dition des liens.

-3Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

I-B - Le mot-cl extern


En langage C, tout objet (variable ou fonction) doit toujours avoir t dclar avant d'tre utilis. Nous avons dj rsolu le problme pour les fonctions, ne reste donc plus que les variables. Supposons donc que l'on souhaite, depuis un fichier donn, accder une variable globale dfinie dans un autre fichier. On ne peut pas tout simplement dclarer une deuxime fois la variable car on aurait alors deux variables de mme nom au sein d'un mme projet ce qui conduirait une erreur lors de l'dition des liens. Le mot-cl extern permet de rsoudre le problme. Plac devant une dclaration, il permet d'indiquer que la variable ou fonction est dfinie (plus prcisment : peut tre dfinie) dans un autre fichier (source ou objet). Plac devant une dfinition, il permet d'indiquer que la variable ou la fonction est visible dans tout le projet, ce qui est dj le comportement par dfaut.

I-C - Le mot-cl static


Le mot-cl static permet de restreindre la visibilit de la variable ou de la fonction au fichier source courant. On a alors ce qu'on appelle une variable ou fonction prive. Par exemple :
#include <stdio.h> static int id(int x); /* Declaration de la fonction "privee" id() (utilisee dans main()). */ int main() { int x = 0; printf("id(%d) = %d\n", x, id(x)); } return 0;

int id(int x) { return x; }

I-D - Les fichiers d'en-tte


Les fichiers d'en-tte (*.h) permettent de rassembler des en-ttes (c'est--dire des dclarations de fonctions, des dfinitions de macros, de types, etc.) communes plusieurs fichiers sources et/ou fichiers d'en-tte. Mais puisqu'ils peuvent justement tre inclus par un grand nombre de fichiers, le risque d'tre inclus plus d'une fois dans un mme fichier est trs lev. C'est pour cette raison que les fichiers d'en-ttes doivent imprativement tre protgs contre les inclusions multiples. La technique fait appel au prprocesseur : une macro indique si le fichier est dj inclus. Il suffit donc de tester ds le dbut du fichier si la macro est dfinie ou non. Le schma est donc le suivant :
#ifndef DRAPEAU #define DRAPEAU /* --------- */ /* */ /* --------- */ #endif

Dans l'exemple de projet prcdent, on aurait pu par exemple cr un fichier somme.h contenant la dclaration des fonctions somme et produit du fichier somme.c. Fichier : somme.h
#ifndef H_SOMME_H #define H_SOMME_H -4Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

Fichier : somme.h
int somme(int a, int b); int produit(int a, int b); #endif

Le fait d'avoir choisi H_SOMME_H plutt que SOMME_H ou __SOMME_H__ comme drapeau n'est pas du tout le fruit du hasard. Il permet de ne pas entrer en conflit avec les identifiants reservs du langage. Par exemple, les identifiants commencants par E, LC_, SIG, etc. sont reservs (E pour les numros d'erreur de errno.h, LC_ pour les constantes dfinies par locale.h et SIG pour le les signaux de signal.h). H_ en dbut d'un identifiant est pour l'heure encore libre, alors en profiter. Il suffit maintenant d'inclure ce fichier partout o on a besoin des fonctions somme et produit. Par exemple : Fichier : exemple.c

#include <stdio.h> #include "somme.h" int main() { int a = 2, b = 5; printf("%d + %d = %d\n", a, b, somme(a, b)); printf("%d * %d = %d\n", a, b, produit(a, b)); } return 0;

Lorsque le nom d'un fichier est mis entre guillemets comme dans cet exemple, le prprocesseur va d'abord chercher le fichier dans le mme rpertoire que celui du fichier source puis s'il ne le trouve pas, va le chercher dans le ou les rpertoires par dfaut (spcifiques du compilateur). On peut galement spcifier un chemin absolu.

I-E - Les structures opaques


Une structure est dite opaque lorsque son implmentation (c'est--dire sa dfinition) est cache. L'accs aux champs de la structure se fait alors par l'intermdiaire de fonctions dont l'implmentation videmment est galement cache. En particulier, l'interface devra au moins fournir une fonction permettant de crer l'objet (constructeur) et une fonction permettant de le dtruire (destructeur). Par exemple, nous allons encapsuler le type int dans une structure de type integer_s. Implmentons la structure dans un fichier integer.c Fichier : integer.c
#include <stdlib.h> struct integer_s { int value; }; struct integer_s * integer_create_object() { return malloc(sizeof(struct integer_s)); } void integer_set_value(struct integer_s * p_object, int value) { p_object->value = value; } int integer_get_value(struct integer_s * p_object) { return p_object->value; }

-5Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

Fichier : integer.c

void integer_delete_object(struct integer_s * p_object) { free(p_object); }

Fournissons maintenant l'interface via un fichier d'en-tte : integer.h integer.h


#ifndef H_INTEGER #define H_INTEGER struct integer_s; struct integer_s * integer_create_object(void); void integer_set_value(struct integer_s * p_object, int value); int integer_get_value(struct integer_s * p_object); void integer_delete_object(struct integer_s * p_object); #endif

La ligne :
struct integer_s;

dclare la structure (sans la dfinir). C'est ce qu'on appelle une dclaration incomplte. Comme la dfinition de la structure n'apparat pas plus bas, La structure est alors opaque. Voici un exemple d'utilisation de integer.h : exemple.c

#include <stdio.h> #include "integer.h" int main() { struct integer_s * i = integer_create_object(); if (i != NULL) { integer_set_value(i, 100); printf("The value of i is : %d\n", integer_get_value(i)); integer_delete_object(i); } } return 0;

II - Les bibliothques II-A - Introduction


Une bibliothque (library en anglais) est en premire approximation un bouquet de fonctions. Chez certains langages elles sont appeles units ou paquetages mais le principe reste le mme. En langage C, il faut en fait galement fournir le ou les fichiers d'en-tte correspondants (contenant la dclaration des fonctions de la bibliothque, des macros et/ou types supplmentaires, etc.) avant de rellement en constituer une. La manire de crer et d'utiliser une bibliothque est trs dpendante de l'environnement avec lequel on travaille. Dans ce tutoriel nous allons expliquer essentiellement la procdure pour MS Visual Studio .NET donc videmment sous Windows.

-6Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

Comme nous le savons dj, la compilation d'un fichier source ne produit pas un excutable mais un module objet (.o ou .obj), que l'on peut considrer comme la version machine du fichier source original. Il faut ensuite lier diffrents modules objets pour produire un excutable. Un module objet est rutilisable (on peut donc voir un tel fichier comme une vritable bote outils ). C'est l d'ailleurs toute l'importance de la compilation spare. Reprenons par exemple le fichier somme.c contenant le code des fonctions somme et produit. En compilant ce fichier, on obtient un fichier somme.obj. Maintenant, crons un nouveau projet dans lequel nous allons utiliser les fonctions somme et produit. Voici le programme : Fichier : exemple.c

#include <stdio.h> int somme(int a, int b); int produit(int a, int b); int main() { int a = 2, b = 5; printf("%d + %d = %d\n", a, b, somme(a, b)); printf("%d * %d = %d\n", a, b, produit(a, b)); } return 0;

Si on compile ce fichier, il n'y a aucune erreur puisque tout est syntaxiquement correct, l'quivalent en langage machine peut donc tre gnr. Par contre si on tente de gnrer l'excutable, on aura un message d'erreur indiquant que l'dition des liens a chou car les fonctions somme et produit n'ont pu tre trouvs. Il faut donc dire au linkeur qu'il doit galement chercher dans somme.obj lors de l'dition des liens. La procdure est videmment dpendante de l'environnement de dveloppement. Sous Code::Blocks, c'est dans Project > Build Options > Linker > Link Libraries. Sous Visual Studio .NET c'est Project > Properties > Configuration Properties > Linker > Input > Additional Dependencies. Il suffit ensuite d'ajouter somme.obj. Ce n'est pas plus diffrent non plus avec les autres EDIs. Evidemment si vous ne spcifiez pas de chemin complet, le linkeur va supposer que le fichier se trouve dans le rpertoire par dfaut pour les libs (gnralement un dossier nomm LIB dans le rpertoire d'installation du compilateur) qui est bien entendu spcifique du linkeur.

II-B - Les bibliothques statiques


Une bibliothque statique (.lib ou .a) est un fichier qui regroupe un ou plusieurs modules objets. Elles s'utilisent donc de la mme manire que ces derniers. Pour crer une bibliothque statique avec Visual Studio .NET, crez un nouveau projet Win32 (Win32 Project) puis dans Paramtres de l'application (Application settings), choisissez Bibliothque statique (Static library). Cochez l'option Projet vide (Empty project) afin qu'aucun fichier source ne soit automatiquement ajout au projet. A la fin, compilez le projet l'aide du menu Gnrer (Build).

II-C - Les bibliothques dynamiques


Une bibliothque dynamique est un fichier qui ne sera effectivement li l'excutable que pendant l'excution. Cela prsente plusieurs avantages. Supposez par exemple que vous avez cr une bibliothque statique et que vous l'avez ensuite utilis dans de nombreuses applications. Si un jour vous la modifiez et que vous voulez galement mettre jour toutes vos applications, vous devrez les recompiler une par une ! Pourtant si vous avez utilis une bibliothque dynamique, la modification seule de ce fichier aura des rpercussions sur toutes les applications l'utilisant puisque la liaison avec le fichier ne se fait que pendant l'excution. De plus, si vous avez bien compris, l'utilisation des bibliothques dynamiques rend les excutables plus petits (en terme de taille) puisque ce dernier mme est incomplet. En effet, il a besoin du code contenu dans la bibliothque pour fonctionner. Sous Windows, les bibliothques dynamiques sont appeles DLLs (.dll) pour Dynamic-Link Library. Sous UNIX on les appelle Shared Objects (.so). Dans ce tutoriel, nous-nous intresserons aux DLLs.

-7Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

Nous allons donc crer une DLL (dsomme.dll) exportant deux fonctions : somme et produit. Que signifie exporter ? Ben c'est trs simple : lorsqu'on dveloppe une bibliothque, on peut spcifier quelles fonctions (ou variables) seront publiques (ou exportes), c'est--dire accessibles depuis l'extrieur, et lesquelles seront prives , c'est-dire rserves usage interne. Ce qui ne sont pas exportes sont prives. La question est donc maintenant : comment exporter une fonction. Et ben il y a plusieurs manires de le faire, par exemple l'aide du modificateur __declspec(dllexport). Bien entendu, il s'agit bien d'une extension Microsoft aux langages C et C++ (en ce qui nous concerne : le langage C) et qui fut ensuite repris par la plupart des implmentations pour Windows. Donc pas de problme que vous compilez avec MingW ou Borland C++ ... Sous Visual Studio .NET, crez un nouveau projet Win32 (Win32 Project) puis dans Paramtres de l'application choisissez DLL. Cochez l'option Projet vide afin qu'aucun fichier ne soit automatiquement ajout au projet. Ajoutez ensuite un fichier dsomme.c puis saisissez le code suivant : Fichier : dsomme.c
__declspec(dllexport) int somme(int a, int b) { return a + b; } __declspec(dllexport) int produit(int a, int b) { int prod = 0; while (b-- > 0) prod += a; } return prod;

Compilez ensuite le projet avec la commande Build du menu Build. Vous obtiendrez entre autres en sortie deux fichiers : dsomme.dll et dsomme.lib. Ce dernier, bien que portant l'extension .lib, n'est pas une bibliothque statique mais une bibliothque d'importation. C'est lui qu'il faut passer au linkeur lors de l'dition des liens pour pouvoir compiler du code dpendant d'une DLL. A l'excution, le programme doit pouvoir localiser la DLL. Cette dernire doit donc se trouver soit dans le mme rpertoire que le programme, soit dans le rpertoire courant du programme, ou encore dans un rpertoire connu du systme par exemple le rpertoire system32. La dclaration de fonctions importer depuis une DLL (via la bibliothque d'importation) peut se faire comme la dclaration d'une fonction normale , cependant le modificateur __declspec(dllimport) permet d'indiquer au compilateur (je dis bien le compilateur, pas le linkeur) que la fonction en question se trouve dans une bibliothque dynamique, ce qui lui permettra de gnrer du code plus efficace (plus direct ). Sans cela, le compilateur va tout simplement convertir chaque appel de la fonction en appel de celle qui se trouve dans le .lib, qui ne fait rien de plus qu'un appel la fonction dans la DLL ce qui fait donc finalement deux appels, ce qui est videmment plus long qu'un appel direct. Notre programme sera donc : Fichier : exemple.c

#include <stdio.h> __declspec(dllimport) int somme(int a, int b); __declspec(dllimport) int produit(int a, int b); int main() { int a = 2, b = 5; printf("%d + %d = %d\n", a, b, somme(a, b)); printf("%d * %d = %d\n", a, b, produit(a, b)); } return 0;

Et n'oubliez pas : nous devons nous lier avec dsomme.lib.

-8Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

La compilation spare en C par Jessee Michal C. Edouard (Accueil)

II-D - Applications. Exemples II-D-1 - La bibliothque standard du langage C


Sous Windows, la bibliothque standard du langage C, c'est--dire celle qui contient entre autres le code des fonctions standard du C est implmente en tant que bibliothque dynamique connue sous le nom de Microsoft C Run-Time Library (CRT), et qui correspond au fichier msvcrt.dll (ce fichier se trouve dans le rpertoire systme). Les compilateurs utilisent gnralement cette bibliothque comme corps de la bibliothque standard mais rien n'empche un compilateur particulier de disposer de sa propre bibliothque d'excution. Visual C++ 2005 (Visual C++ 8.0) par exemple utilise msvcr80.dll (msvcr80d.dll en mode Debug) au lieu de msvcrt.dll.

II-D-2 - Le concept d'API


Une API ou Application Programming Interface (Interface de Programmation d'Applications) est un ensemble de fonctions exposes par un systme ou un logiciel pour permettre d'autres logiciels d'interagir (c'est--dire de communiquer) avec lui. Par extension, toute fonction d'une API donne est galement appele : une API. Sous UNIX, les APIs du systme sont appels appels systme. Les DLLs sont trs utilises sous Windows et le systme lui-mme expose son API via de nombreuses DLLs. Les programmes conues spcifiquement pour Windows se lient donc un ou plusieurs DLLs de l'API Windows.

III - Conclusion
La compilation spare permet de mieux organiser ses projets et de dvelopper des bibliothques de fonctions. C'est donc une technique qu'il faut absolument matriser si on veut dvelopper srieusement en C.

-9Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2008 - Melem. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://melem.developpez.com/tutoriels/langage-c/compilation-separee/

Vous aimerez peut-être aussi