cours 6 - compilation séparée, classes de stockage et makefile



Documents pareils
Cours Langage C/C++ Programmation modulaire

Quelques éléments de compilation en C et makefiles

Notes de Cours - Programmation Pascal Ferraro

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Introduction au langage C

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Chaîne de production d un programme

UE Programmation Impérative Licence 2ème Année

Le prototype de la fonction main()

Programmation en langage C

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Programmation système I Les entrées/sorties

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Notes du cours 4M056 Programmation en C et C++ Vincent Lemaire et Damien Simon

Programmation C. J.-F. Lalande. 15 novembre 2012

Cours Programmation Système

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Cours de C/C++ par la pratique. Hugues Talbot

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Bases de programmation. Cours 5. Structurer les données

Algorithmique et Programmation, IMA

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

3IS - Système d'exploitation linux - Programmation système

Arguments d un programme

Compression de Données - Algorithme de Huffman Document de Conception


Testez votre installation. Créer un répertoire vide

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Chapitre 10 : Logiciels

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Initiation. àl algorithmique et à la programmation. en C

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence

Le langage C. Introduction, guide de reference

Programmation C. Apprendre à développer des programmes simples dans le langage C

Mon premier rpm. 7 juin Avant de commencer RPM URPMI RPMBUILD... 2

Systeme d'exploitation

Outils pour la pratique

Programmation système de commandes en C

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Construction de logiciel et packaging

I00 Éléments d architecture

REPUBLIQUE ALGERIENNE DEMOCRATIQUE ET POPULAIRE UNIVERSITE M HAMED BOGARA DE BOUMERDES

Optimisation de logiciels de modélisation sur centre de calcul

Support de Cours de Langage C. Christian Bac

Gestion Electronique de Document (ECM/GED)

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Cours 6 : Tubes anonymes et nommés

Projet De Stijl Plate-forme pour robots mobiles

Programmation système en C/C++

Langages et Concepts de Programmation Introduction à la programmation en langage C

INF 104 (SELC) Introduction au langage C

Rappels Entrées -Sorties

Programmation en langage C Eléments de syntaxe

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

SUPPORT DE COURS. Langage C

Cours de programmation avancée. Le langage C. Université du Luxembourg

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

Programmation en langage C d un µcontrôleur PIC à l aide du compilateur C-CCS Sommaire

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Les techniques de protection du logiciel

Introduction à C++ et à wxwidgets

Programmation impérative

Environnements de développement (intégrés)

I. Introduction aux fonctions : les fonctions standards

Programmation en C. École Nationale Supérieure de Techniques Avancées. Pierre-Alain Fouque et David Pointcheval

Architecture des ordinateurs

30.avr.10 Présentation miniprojet. 9.mars.10 Cours 3 4.mai.10 Cours C mars.10 Cours 4 11.mai.10 Cours C++ 2

Les structures. Chapitre 3

Généralités sur le Langage Java et éléments syntaxiques.

La mémoire. Un ordinateur. L'octet. Le bit

Cours d initiation à la programmation en C++ Johann Cuenin

1 Description générale de VISFIELD

OS Réseaux et Programmation Système - C5

Cours de Programmation 2

Corrigés des premiers exercices sur les classes

Langage Éric Guérin 5 octobre 2010

L informatique en BCPST

INTRODUCTION À LA PROGRAMMATION PRATIQUE DU LANGAGE C. M. Le Gonidec

Méthodes de programmation systèmes UE n NSY103. Notes de cours. Nombre d'heures : 55h (~ cours de 3 heures)

Algorithmique, Structures de données et langage C

Programmation impérative

Compléments de documentation Scilab : affichage de texte et formatage de nombres

Cours Java Native Interface

INITIATION A LA PROGRAMMATION

Unix : Programmation Système

Introduction à l héritage en C++

PROJET ALGORITHMIQUE ET PROGRAMMATION II

MINIMUM. connaissances nécessaires à la programmation des microcontrôleurs PIC18 en langage C (une introduction au langage c A.N.S.

Introduction au Langage de Programmation C

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

Le traitement du temps

Programmation en C/C++

Gestion de la mémoire

Tp 1 correction. Structures de données (IF2)

PRÉSENTÉ PAR : NOVEMBRE 2007

Haka : un langage orienté réseaux et sécurité

IFT Systèmes d exploitation - TP n 1-20%

Transcription:

cours 6 - compilation séparée, classes de stockage et makefile G. Bianchi, G. Blin, A. Bugeau, S. Gueorguieva, R. Uricaru 2015-2016 Programmation 1 - uf-info.ue.prog1@diff.u-bordeaux.fr

la programmation modulaire Trois grands principes à suivre L utilisation de constantes symboliques définies au moyen de la directive #define La factorisation du code à l aide de fonctions pour éviter la duplication de code La fragmentation du code en plusieurs fichiers afin d augmenter la lisibilité et la réutilisation aisée de portions de code par d autres applications Compilation séparée 1

compilation séparée

principe de base Chaque fichier source contient un ensemble de fonctions généralement correspondant à un thème (e.g., fonctions d affichage) Les fichiers sources sont compilés séparément Les binaires produits seront liés lors de l édition des liens 3

exemple main.c #include <stdlib.h> #include <stdio.h> #define GOLDEN_RATIO 1.618 float daligoldenrectangle(float x){ return x*golden_ratio; int main(void){ float a=1, b=0, c=0; b=daligoldenrectangle(a); c=daligoldenrectangle(a+b); printf( (%f,%f)\n,a,b); printf( (%f,%f)\n,a+b,c); return EXIT_SUCCESS; gcc -std=c99 -Wall -c main.c gcc -std=c99 -Wall -c dali.c gcc -o example main.o dali.o La déclaration de la fonction daligoldenrectangle dans main.c est obligatoire ici dali.c #define GOLDEN_RATIO 1.618 float daligoldenrectangle(float x){ return x*golden_ratio; main.c #include <stdlib.h> #include <stdio.h> float daligoldenrectangle(float x); int main(void){ float a=1, b=0, c=0; b=daligoldenrectangle(a); c=daligoldenrectangle(a+b); printf( (%f,%f)\n,a,b); printf( (%f,%f)\n,a+b,c); return EXIT_SUCCESS; 4

fichier en-tête d un fichier source Pour que le programme reste modulaire, on place la déclaration de la fonction daligoldenrectangle dans un fichier entête dali.h que l on inclut dans main.c à l aide de #include Ce fichier contient les déclarations des fonctions utilisables en dehors du fichier ainsi que les définitions des constantes symboliques et des macros utilisées Le fichier d en-tête doit être inclus dans tous les fichiers sources utilisant une des fonctions définies dans le fichier source correspondant (e.g., dali.c) y compris dans le fichier source lui-même L inclusion du fichier d en-tête (e.g., dali.h) dans le fichier source correspondant (e.g., dali.c) permet au compilateur de vérifier la compatibilité de la déclaration et de la définition de la fonction 5

exemple main.c #include <stdlib.h> #include <stdio.h> #define GOLDEN_RATIO 1.618 float daligoldenrectangle(float x){ return x*golden_ratio; int main(void){ float a=1, b=0, c=0; b=daligoldenrectangle(a); c=daligoldenrectangle(a+b); printf( (%f,%f)\n,a,b); printf( (%f,%f)\n,a+b,c); return EXIT_SUCCESS; #include <foo.h> - recherche dans la librairie standard #include foo.h - recherche dans le répertoire local dali.h #define GOLDEN_RATIO 1.618 float daligoldenrectangle(float x); dali.c #include dali.h float daligoldenrectangle(float x){ return x*golden_ratio; main.c #include <stdlib.h> #include <stdio.h> #include dali.h int main(void){ float a=1, b=0, c=0; b=daligoldenrectangle(a); c=daligoldenrectangle(a+b); printf( (%f,%f)\n,a,b); printf( (%f,%f)\n,a+b,c); return EXIT_SUCCESS; 6

fichier en-tête Les fichiers d en-tête ne doivent pas être compilés Il faut empêcher la possible double inclusion et donc les possibles définitions multiples d un fichier d en-tête A l aide d une constante symbolique, habituellement appelée _NOM_H_ définie au début du fichier nom.h et dont l existence est précédemment testée Si cette constante est définie alors c est que le fichier en-tête nom.h a déjà été inclus Sinon, on définit la constante et on prend en compte le contenu du fichier nom.h 7

inclusion conditionnelle en pratique #ifdef NOM permet de prendre en compte toutes les instructions jusqu au #else, #elif ou #endif correspondant si et seulement si la macro NOM a été définie #ifndef NOM a un comportement identique dans le cas où la macro NOM n a pas été définie sum.h #ifndef _DALI_H_ #define _DALI_H_ #define GOLDEN_RATIO 1.618 float daligoldenrectangle(float x); #endif 8

classes de stockage

extern Le mot clef extern permet de déclarer quelque chose sans le définir, ni réserver l espace mémoire correspondant Pour une fonction, cela ne fait pas de différence mais montre explicitement qu elle n est pas définie dans le même fichier #include <stdlib.h> #include <stdio.h> #define GOLDEN_RATIO 1.618 extern float daligoldenrectangle(float x); //Better include headers int main(void){ float a=1, b=0, c=0; b=daligoldenrectangle(a); c=daligoldenrectangle(a+b); printf( (%f,%f)\n,a,b); printf( (%f,%f)\n,a+b,c); return EXIT_SUCCESS; 10

extern Même si cela doit être évité, il est parfois nécessaire d utiliser une variable commune à plusieurs fichiers sources Le compilateur doit comprendre que deux variables portant le même nom mais déclarées dans deux fichiers différents correspondent en fait à une seule variable commune H2G2.c int shared_variable=42; void ultimate_question(){ printf( Answer of the Ultimate Question of Life, the Universe \ and Everything : %d\n, shared_variable); Base13.c int shared_variable; void six_by_night(){ printf( Six times Night in base 13 : %d\n, shared_variable); 11

extern La variable doit être déclarée une et une seule fois de manière classique (réservation de l espace mémoire correspondant) Dans les autres fichiers qui l utilisent, il faut déclarer cette variable à l aide du mot clef extern (cela ne donne pas lieu à une réservation d espace mémoire) H2G2.c int shared_variable=42; void ultimate_question(){ printf( Answer of the Ultimate Question of Life, the Universe \ and Everything : %d\n, shared_variable); Base13.c extern int shared_variable; void six_by_night(){ printf( Six times Night in base 13 : %d\n, shared_variable); 12

variable partagée Même avec la protection par macros, si on met une variable dans un.h, des problèmes persistent const.h #ifndef _CONST_H_ #define _CONST_H_ extern void foo(void); int MODE=12; #endif foo.c #include const.h void foo(void) { MODE=MODE+5; main.c #include <stdio.h> #include const.h int main(int argc,char* argv[]) { foo(); return 0; $>gcc -Wall -std=c99 main.c foo.c ccs3baaa.o(.data+0x0):foo.c: multiple definition of MODE ccmqbaaa.o(.data+0x0):main.c: first defined here 13

variable partagée Solution: mettre la variable dans un.c et sa déclaration externe dans le.h const.h #ifndef _CONST_H_ #define _CONST_H_ extern void foo(void); extern int MODE; #endif const.c int MODE=42; foo.c #include const.h void foo(void) { MODE=MODE+5; main.c #include <stdio.h> #include const.h int main(int argc,char* argv[]) { foo(); return 0; 14

restriction de la visibilité d une variable Le mot clef static permet de ne pas rendre visible de l extérieur une variable globale ou une fonction foo.c static int var1; int var2; static void foo1(void) { void foo2(void) { test.c extern int var1, var2; extern void foo1(void); extern void foo2(void); int main(int argc,char* argv[]) { foo1(); foo2(); return 0; $>gcc -Wall -std=c99 test.c foo.c foo.c:1: warning: var1 defined but not used foo.c:4: warning: foo1 defined but not used cc8qbaaa.o(.text+0x1f):test.c: undefined reference to foo1 15

variable glocale Une variable locale static correspond à une variable globale non visible de l extérieur de la fonction /** * This function counts the number of * function calls */ void count_calls(){ static int count=0; // only initialized once count=count+1; 16

variable à accès rapide Le mot clef register permet de demander à utiliser un registre pour une variable (dans la mesure du possible) #define LIM 2000 int main(int argc,char* argv[]) { OPT unsigned int i, j, k, res; res=0; for (i=0;i<lim;i++){ for (j=0;j<lim;j++){ for (k=0;k<lim;k++){ res=res+i+j+k; return 0; $>gcc -Wall -std=c99 -DOPT= z.c $>time -p a.out real 23.81 user 23.66 sys 0.02 $>gcc -Wall -std=c99 -DOPT=register $>time -p a.out real 12.95 user 12.88 sys 0.01 17

makefile

make L utilitaire make d Unix permet d automatiser la compilation d un programme fragmenté en plusieurs fichiers sources L idée principale de make est d effectuer uniquement les étapes de compilation nécessaires à la création d un exécutable Seuls les fichiers modifiés sont recompilés La commande make recherche par défaut dans le répertoire courant un fichier de nom makefile, ou Makefile si elle ne le trouve pas Ce fichier spécifie les dépendances entre les différents fichiers sources, objets et exécutables 19

le fichier makefile Un fichier Makefile est composé d une liste de règles de dépendance de la forme : cible: liste de dependances <tabulation> commandes UNIX La première ligne spécifie un fichier cible, puis la liste des fichiers dont il dépend (séparés par des espaces) Les lignes suivantes, qui commencent par une tabulation, indiquent les commandes Unix à exécuter dans le cas où l un des fichiers de dépendance est plus récent que le fichier cible 20

exemple de makefile ## Premier exemple de Makefile ex1: main.c sum.c sum.h gcc -std=c99 -Wall -o ex1 main.c sum.c L exécutable ex1 dépend des deux fichiers sources sum.c et main.c, ainsi que du fichier en-tête sum.h Il résulte de la compilation de ces deux fichiers en suivant la norme c99 avec tous les avertissements possibles Les commentaires sont précédés du caractère 21

exemple de makefile ## Premier exemple de Makefile ex1: main.c sum.c sum.h gcc -std=c99 -Wall -o ex1 main.c sum.c Pour effectuer la compilation et obtenir un fichier cible, on lance la commande make suivie du nom du fichier cible souhaité $> make ex1 21

exemple de makefile ## Premier exemple de Makefile ex1: main.c sum.c sum.h gcc -std=c99 -Wall -o ex1 main.c sum.c Par défaut, si aucun fichier cible n est spécifié au lancement de make, c est la première cible du fichier Makefile qui est prise en compte Au premier lancement de la commande make, la compilation est effectuée puisque le fichier exécutable ex1 n existe pas % make gcc -std=c99 -Wall -o ex1 main.c sum.c 22

exemple de makefile ## Premier exemple de Makefile ex1: main.c sum.c sum.h gcc -std=c99 -Wall -o ex1 main.c sum.c Par défaut, si aucun fichier cible n est spécifié au lancement de make, c est la première cible du fichier Makefile qui est prise en compte Sans modification des fichiers sources ou en-tête, lors d un nouveau lancement de la commande make, la compilation n est pas effectuée puisque le fichier ex1 est plus récent que les trois fichiers dont il dépend % make make: ex1 is up to date. 23

a better makefile Afin de profiter pleinement des possibilités offertes par la compilation séparée, il est préférable de diviser la compilation d un projet en sous-étapes ## Better example of Makefile ex1: sum.o main.o gcc -o ex1 main.o sum.o main.o : main.c sum.h gcc -std=c99 -Wall -c main.c sum.o : sum.c sum.h gcc -std=c99 -Wall -c sum.c Les fichiers objet main.o et sum.o dépendent respectivement des fichiers sources main.c et sum.c, et du fichier entête sum.h 24

a better makefile Afin de profiter pleinement des possibilités offertes par la compilation séparée, il est préférable de diviser la compilation d un projet en sous-étapes ## Better example of Makefile ex1: sum.o main.o gcc -o ex1 main.o sum.o main.o : main.c sum.h gcc -std=c99 -Wall -c main.c sum.o : sum.c sum.h gcc -std=c99 -Wall -c sum.c Les fichiers objet sont obtenus en effectuant la compilation de ces fichiers sources sans édition de liens 24

a better makefile Afin de profiter pleinement des possibilités offertes par la compilation séparée, il est préférable de diviser la compilation d un projet en sous-étapes ## Better example of Makefile ex1: sum.o main.o gcc -o ex1 main.o sum.o main.o : main.c sum.h gcc -std=c99 -Wall -c main.c sum.o : sum.c sum.h gcc -std=c99 -Wall -c sum.c Le fichier exécutable ex1 est obtenu en effectuant l édition de liens des fichiers sum.o et main.o 24

a better makefile ## Better example of Makefile ex1: sum.o main.o gcc -o ex1 main.o sum.o main.o : main.c sum.h gcc -std=c99 -Wall -c main.c sum.o : sum.c sum.h gcc -std=c99 -Wall -c sum.c Au premier lancement de la commande make, la compilation est effectuée puisque le fichier exécutable ex1 n existe pas % make gcc -std=c99 -Wall -c sum.c gcc -std=c99 -Wall -c main.c gcc -o ex1 main.o sum.o 25

a better makefile ## Better example of Makefile ex1: sum.o main.o gcc -o ex1 main.o sum.o main.o : main.c sum.h gcc -std=c99 -Wall -c main.c sum.o : sum.c sum.h gcc -std=c99 -Wall -c sum.c Si l on modifie le fichier sum.c, le fichier main.o est encore à jour donc seules deux des trois commandes sont exécutées % make gcc -std=c99 -Wall -c sum.c gcc -o ex1 main.o sum.o L option -MM de gcc permet de déterminer facilement les dépendances entre fichiers % gcc -MM main.c main.o: main.c sum.h 26

mr propre On rajoute habituellement dans un fichier Makefile une cible appelée clean permettant de supprimer les fichiers intermédiaires produits par la compilation ## Better example of Makefile ex1: sum.o main.o gcc -o ex1 main.o sum.o main.o : main.c sum.h gcc -std=c99 -Wall -c main.c sum.o : sum.c sum.h gcc -std=c99 -Wall -c sum.c clean: rm -f ex1 *.o 27

macros et abbréviations On peut utiliser un certain nombre de macros de la forme nom_de_macro = valeur_de_la_macro Lors de l appel à la commande make toutes les occurences du type $(nom de macro) dans le Makefile sont remplacées par la valeur de la macro ## An even better Makefile # Compiler definition CC = gcc # Flags to be used for.o generation CFLAGS = -Wall -std=c99 -c ex1: sum.o main.o $(CC) -o ex1 main.o sum.o main.o : main.c sum.h $(CC) $(CFLAGS) main.c sum.o : sum.c sum.h $(CC) $(CFLAGS) sum.c clean: rm -f ex1 *.o 28

quelques options de gcc

options de compilation Le compilateur gcc se lance par la commande gcc [options] fichier.c [-llibrairies] Par défaut, le fichier exécutable s appelle a.out Les éventuelles librairies sont déclarées via l option -llibrairie Le fichier liblibrairie.a est recherché dans le répertoire /usr/lib/ Par exemple, les fonctions mathématiques de la librairie math.h ne sont accessibles qu après inclusion de la librairie libm.a (qui nécessite donc d ajouter l option -lm) 30

options de compilation Le compilateur gcc se lance par la commande gcc [options] fichier.c [-llibrairies] -c permet de produire un fichier objet sans procéder à l édition de liens -E n active que le préprocesseur et affiche le résultat -g produit un fichier objet contenant des informations symboliques nécessaires au débogueur 30

options de compilation Le compilateur gcc se lance par la commande gcc [options] fichier.c [-llibrairies] -Inom-de-repertoire ajoute un répertoire où rechercher des fichiers d en-tête -Lnom-de-repertoire ajoute un répertoire où rechercher des librairies pré-compilés -o nom-de-fichier spécifie le nom du fichier produit 30

options de compilation Le compilateur gcc se lance par la commande gcc [options] fichier.c [-llibrairies] -O, -O1, -O2, -O3 autorise le compilateur à optimiser le code produit suivant un niveau d optimisation (-O1 : faible, -O3 : élevé) -S n active que le préprocesseur et le compilateur et produit un fichier assembleur -Wall fournit tous les messages d avertissement -Werror fournit tous les messages d avertissement comme des erreurs de compilation 30

doggy bag

to take away... Des constantes symboliques doivent être définies Le code doit être factorisé et fragmenté en plusieurs fichiers Les fichiers d en-tête doivent être protégés par des macros La visibilité d une variable ou d une fonction peut être contrôlée à l aide des mot clefs extern et static Tous les fichiers résultant d une étape de la compilation d un programme sont accessibles via des options de gcc 32

Questions? 33