Travaux dirigés : Outils pour la programmation C

ENSEIRB - MATMECA


  1. Télécharger le programme matrix.c dans un répertoire dédié à ce TP et compilez-le.
  2. Compiler le programme en deux étapes: d'abord la compilation elle-même (option -c), puis la construction de l'exécutable avec l'édition de lien.
  3. Effacer l'exécutable matrix puis taper
     make LDFLAGS=-lm matrix
    Que se passe-t-il ? Que se passe-t-il si on exécute une seconde fois la commande ? Taper
     touch matrix.h
    Quel est l'effet de cette commande ? Refaire la commande de compilation. Expliquer.
  4. Écrire un fichier Makefile minimal tel que la commande make (sans arguments) compile en deux étapes. On veut aussi que make clean efface les fichiers matrix et matrix.o.
  5. À quoi servent les instructions assert qui se trouvent dans le programme ? Déclencher un de ces assert en essayant par exemple de créer un vecteur de dimension 0.
  6. Afficher l'espace mémoire total occupé par un vecteur de taille 7. Dans quels secteurs de la mémoire se trouve cet espace ?
  7. Exécuter votre programme avec l'outil valgrind afin de détecter les fuites de mémoire. Écrire deux fonctions pour libérer l'espace alloué dynamiquement:
      void free_vector(vector_t v);
      void free_matrix(matrix_t m);
  8. Créer trois sous-répertoires bin, include et src. Réorganiser le fichier matrix.c en trois fichiers: Les fichiers .c incluent le fichier matrix avec la directive
      #include<matrix.h>
    On peut indiquer au compilateur où trouver les fichiers d'entête avec l'option -Irépertoire. Penser à mettre en place dans le fichier matrix.h un mécanisme permettant d'éviter que le contenu du fichier soit inclus plusieurs fois.
  9. Modifier le fichier Makefile de sorte que chaque binaire .o correspondant à un fichier .c soit compilé dans le répertoire bin et que l'exécutable prog soit créé dans le répertoire de travail. À l'aide de la commande nm vérifier les fonctions utilisées et accessibles dans chaque fichier .o
  10. Séparer ce qui concerne uniquement les vecteurs et ce qui concerne les matrices en deux fichiers disjoints respectivement vector.c et matrix.c avec des entêtes dans vector.h et matrix.h (on suppose que matrix.h dépend de vector.h et pas le contraire). Compiler avec cette nouvelle architecture.
  11. On peut regrouper plusieurs fichiers objets dans une archive qui forme une bibliothèque statique avec la commande:
     ar crs lib•••.a •••.o •••.o
    Créer un répertoire lib et ajouter une cible libmat au Makefile qui crée une bibliothèque libmat.a dans le répertoire lib. Modifier le Makefile de sorte que l'exécutable soit créé en se liant avec cette bibliothèque. On peut utiliser l'option -Lrépertoire pour indiquer au compilateur où trouver les bibliothèques de l'utilisateur.
  12. Plutôt qu'une bibliothèque statique, on veut maintenant créer une bibliothèque dynamique.
    1. ajouter l'option -fpic lors de la compilation; ceci permet que les adresses des fonctions dans le fichier .o ne soient plus absolues mais relatives;
    2. utiliser gcc avec l'option -shared pour produire un fichier libmat.so à partir des fichiers .o;
    3. effectuer l'assemblage comme s'il s'agissait d'une bibliothèque statique;
    4. lancer le binaire; vous obtenez une erreur. Le système ne sait pas où trouver la bibliothèque dynamique qu'il doit charger pour exécuter le programme. Il faut pour cela indiquer le bon répertoire dans la variable d'environnement LD_LIBRARY_PATH.
    Modifier votre Makefile pour qu'il compile une biliothèque dynamique au lieu d'une biliothèque statique. Modifier le programme pour que la fonction v_print affiche le vecteur délimité par des parenthèses au lieu de crochets. Recompiler la bibliothèque (make lib/libmat.so) et relancer le programme pour vérifier que le comportement a bien changé.