IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Systèmes de compilation Discussion :

[GCC/Make] Détection des fichiers orphelins lors d'une compilation


Sujet :

Systèmes de compilation

  1. #1
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut [GCC/Make] Détection des fichiers orphelins lors d'une compilation
    Bonjour,

    Je travaille sur un programme de compilation automatique de différents code.

    Je souhaiterais savoir s'il est possible avec les outils GCC, ou make de détecter les fichiers n'appartenant pas au projet. (des fichier sources temporaires par exemple) car ils sont inclus de base et donc la compilation plante alors que le programme sans ces fichiers parasites compile parfaitement...

    J'espère que je suis clair

    Merci

  2. #2
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Bonsoir,

    oui et non Tout dépend comment tu repères les fichiers qui appartiennent au projet et si tu n'utilises que gcc et make ou si tu t'autorises d'autres outils pour créer un makefile par exemple.

    Une solution lourde serait :
    1. créer une liste de fichiers contenant une fonction main
    2. pour chacun de ces fichiers, créer une cible qui construit un exécutable ainsi que les dépendances avec gcc et pour chaque dépendances (fichier.h) vérifier si un source est associé (fichier.c) puis pour chacun de ces fichier.c ajouter une dépendance sur l'exécutable ...

    Autant utiliser autoconf

    J'ai une sorte de makefile générique (mono exécutable) que je voulais déjà poster ici ... je relaisserai un petit message quand je l'aurai fait

    Edit: Et voilà ... vite fait, espérant bien fait et utile Makefile générique

  3. #3
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Bonjour,

    Alors déjà, ma méthode est de récupérer tous les fichiers sources dans le répertoire src (les fichiers headers étant dans un dossier headers) et de tout compiler donc forcément avec ma méthode c'est pas possible...

    Il faut savoir que je suis sous Windows 7 avec GnuWin32 l'équivalent de make sous Linux. Est ce que ton makefile générique pourrait fonctionner avec GnuWin32 ?

    Sinon, je ne pense pas pouvoir utiliser autoconf sous Windows

    Une solution lourde serait :
    1. créer une liste de fichiers contenant une fonction main => OK (j'ai une idée de comment faire avec un grep sous windows ^^)
    2. pour chacun de ces fichiers, créer une cible qui construit un exécutable ainsi que les dépendances avec gcc et pour chaque dépendances (fichier.h) vérifier si un source est associé (fichier.c) puis pour chacun de ces fichier.c ajouter une dépendance sur l'exécutable ...
    Même si c'est lourd, comment on pourrait faire le deuxième point ? Je suis vraiment un newbie en makefile (et même en Linux de manière générale ^^)

    Voilà, merci

  4. #4
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par Aspic Voir le message
    Bonjour,

    Alors déjà, ma méthode est de récupérer tous les fichiers sources dans le répertoire src (les fichiers headers étant dans un dossier headers) et de tout compiler donc forcément avec ma méthode c'est pas possible...

    Il faut savoir que je suis sous Windows 7 avec GnuWin32 l'équivalent de make sous Linux. Est ce que ton makefile générique pourrait fonctionner avec GnuWin32 ?

    Sinon, je ne pense pas pouvoir utiliser autoconf sous Windows
    J'ai regardé ce qu'était GnuWin32. C'est assez étrange car dans liste des packages je n'ai trouvé nulle part un shell. C'est ce qui sera le plus embêtant, car la plupart des commandes prérequises (rm, echo, ...) sont disponibles.
    Donc oui, il devrait pouvoir fonctionner avec de légères modifications (séparateur / transformé en \ je suppose) sous réserve que les commandes fonctionnent dans cmd.

    Pour autoconf (qui est bien plus puissant que mon simple Makefile, autant comparer une bombe H et un couteau à beurre) tu peux l'utiliser sous windows7. GnuWin32 propose un package.
    Il y a aussi la solution d'utiliser MSYS ou cygwin qui eux proposent un shell. Avec mingw tu peux aussi assez aisément cross-compiler depuis linux. Le désavantages de cygwin est sans doute la couche posix supplémentaire ...
    Pourquoi avoir choisi GnuWin32 ?
    Citation Envoyé par Aspic Voir le message
    Même si c'est lourd, comment on pourrait faire le deuxième point ? Je suis vraiment un newbie en makefile (et même en Linux de manière générale ^^)

    Voilà, merci
    Si on n'utilise qu'un makefile c'est très lourd car ça revient à écrire un script dans le Makefile, et un script qui ne pourra jamais être parfait Si tu veux on peut creuser plus loin.

  5. #5
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    J'utilise GnuWin32 car je ne connais que cela

    Citation Envoyé par kwariz Voir le message
    Si on n'utilise qu'un makefile c'est très lourd car ça revient à écrire un script dans le Makefile, et un script qui ne pourra jamais être parfait Si tu veux on peut creuser plus loin.
    En fait pour l'instant, j'aurais besoin d'une méthode rapide pour trouver les dépendances entre les fichiers C et virer les fichiers orphelins.
    Donc même si ce n'est pas très propre, je veux bien de l'aide

    J'ai mis en pièce jointe un code exemple bidon avec un fichier débile "InitialisationDUMMY.c" qui lorsqu'il est compilé provoque une erreur de linkage car ce fichier est orphelin (ce fichier redéfinie la fonction load()). (la compilation marche si ce fichier est supprimé).

    Voilà donc le but serait de détecter automatiquement que "InitialisationDUMMY.c" ne sert à rien et donc de ne pas le prendre en compte au linkage et/ou à la compilation.

    Merci beaucoup
    Fichiers attachés Fichiers attachés

  6. #6
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    J'ai un peu cogité sur le problème. À partir du moment où tu disposes d'un shell (regarde si tu penses pouvoir utiliser MSYS) tu pourrais essayer d'améliorer mon premier jet (qui est loin d'être parfait ni même propre, sorry).
    Je suis parti du principe qu'étant donné tu as un répertoire src et un autre headers, ça te dirait d'avoir tes objets placés dans obj et ton exécutable dans [codeinline]bin/codeinline]. Je suis aussi parti du principe que tu ne construis qu'un seul exécutable.

    Le premier pas est de pouvoir construire la liste des dépendances au format Makefile : cible: liste des dépendances. Pour cela j'ai écris un petit script shell. On part du fichier qui contient le main et on utilise gcc pour fournir les dépendances. On les obtient avec les options -E (pour ne faire que la passe préprocesseur) -MM (on ne s'occupe que des headers qui ne sont pas des headers système) -MT pour customiser le nom de la cible car elle est dans un répertoire spécifique. Il ne faudra pas oublier de passer à gcc les options pour le préprocesseur (en gros les -D et les -I en général), ici je n'ai que passé un -I vers le répertoire contenant les headers.
    Donc on part du fichier c qui contient le main, on en demande les dépendances à gcc et on les sauve dans un fichier que l'on place dans le répertoire dep. On lit ensuite le fichier pour trouver tous les .h inclus et pour chaque .h inclus on recommence l'opération avec le fichier .c correspondant si on ne l'a pas déjà traité.
    À la fin, on crée un fichier dep/dep.inc qui est la concaténation de toutes les dépendances créées, plus une ligne pour ton exécutable et une ligne pour regénérer les dépendances si on modifie un des fichiers source trouvé.
    En gros, le script checkdeps.sh
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #!/bin/bash                                                                                                                                     
     
    HEADER_DIR=headers/
    SOURCE_DIR=src/
    OBJECT_DIR=obj/
    BIN_DIR=bin/
    DEP_DIR=dep/
     
    MAIN_SOURCE=main.c
    MAIN_TARGET=monprog
    MAIN_SOURCE_LIST=""
    MAIN_OBJECT_LIST=""
    MAIN_DEP=dep.inc
     
    filesToCheck=${SOURCE_DIR}${MAIN_SOURCE}
    until [ "${filesToCheck}" == "" ]
    do
      nextRun=""
      for file in ${filesToCheck}
      do
        MAIN_SOURCE_LIST="$file ${MAIN_SOURCE_LIST}"
        MAIN_OBJECT_LIST="${OBJECT_DIR}$(basename ${file} .c).o ${MAIN_OBJECT_LIST}"
        echo -n "GENDEP $(basename ${file}) ( "
        gcc -I ${HEADER_DIR} -E -MM -MT ${OBJECT_DIR}$(basename ${file} .c).o -o ${DEP_DIR}$(basename ${file} .c).d ${file}
        for dep in $(cat ${DEP_DIR}$(basename ${file} .c).d)
        do
          if [ ${dep:$((${#dep}-2))} = .h ] && [ -e ${SOURCE_DIR}$(basename ${dep} .h).c ] && [ ! -e ${DEP_DIR}$(basename ${dep} .h).d ]
          then
            echo -n "$(basename ${dep} .h).c "
            nextRun="${SOURCE_DIR}$(basename ${dep} .h).c ${nextRun}"
          fi
        done
      done
      echo ")"
      filesToCheck="${nextRun}"
    done
    echo "${DEP_DIR}${MAIN_DEP}: ${MAIN_SOURCE_LIST}" > ${DEP_DIR}${MAIN_DEP}
    echo "${BIN_DIR}${MAIN_TARGET}: ${MAIN_OBJECT_LIST}" >> ${DEP_DIR}${MAIN_DEP}
    cat ${DEP_DIR}*.d >> ${DEP_DIR}${MAIN_DEP}
    rm ${DEP_DIR}*.d
    Le résultat avec le projet tel que tu l'as zippé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    dep/dep.inc: src/checkMemory.c src/main.c 
    bin/monprog: obj/checkMemory.o obj/main.o 
    obj/checkMemory.o: src/checkMemory.c headers/checkMemory.h
    obj/main.o: src/main.c headers/checkMemory.h
    La première ligne est importante car c'est elle qui permet de relancer la création des dépendances si on modifie un source (il faudrait peut-être rajouter les headers ? ça va dépendre de ton style)
    La seconde explique que tous les sources compilés participent à la création de l'exécutable.
    Les suivantes décrivent les dépendances découvertes par gcc.

    Le makefile est ensuite relativement simple, on commence par quelques variables d'usage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SOURCE_DIR = src/
    HEADER_DIR = headers/
    OBJECT_DIR = obj/
    BIN_DIR    = bin/
    DEP_DIR    = dep/
     
    SOURCE_MAIN = main.c
    TARGET      = monprog
     
    .DEFAULT_GOAL := $(BIN_DIR)$(TARGET)
     
    CC = gcc
    CPPFLAGS = -I $(HEADER_DIR)
    Et c'est ensuite que ca devient intéressant. On demande à make d'inclure le fichier dep/dep.inc. La première fois il ne va pas le trouver, alors il va essayer de le créer. On lui donne la recette : lancer notre script
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $(DEP_DIR)dep.inc:
            @echo GENDEP
            @./checkdeps.sh

    Les fois suivantes il ne le générera que s'il faut (cf première ligne de dep/dep.inc).
    À partir de là on a géré les dépendances. Reste à expliquer comment créer l'exécutable et les objets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $(BIN_DIR)$(TARGET):
            @echo "CCLD   $@ <- $?"
            @touch $@
     
    $(OBJECT_DIR)%.o: $(SOURCE_DIR)%.c
            @echo "CC     $@ <- $?"
            @touch $@
    Bon ici je ne fais rien de spécial sinon afficher quelles dépendances déclenchent quelles recettes. À toi de mettre les bonnes commandes

    Remarque: ton main appelle la fonction load qui n'est dans un aucun header -> ça va bugguer. Avec ce genre d'automatisation il faut faire gaffe car on se repose sur le fait que toute fonction visible d'un source est déclarée dans un header de même de nom et qu'on inclue ce header partout où on utilise les fonctions.

    J'ai fait ça à main levée alors c'est sans garantie ... si ça va dans la direction voulue on pourra mettre ça au propre. Je joins le zip modifé.

    test_projet.zip

  7. #7
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Merci pour l'explication du script

    J'ai installé MSYS pour tester (à voir après si je peux exécuter des commandes automatiquement grâce à la fonction system() en C).

    Alors pour la compilation, j'ai un petit problème :
    @(gcc -o $@ -c $^ $(CPPFLAGS) )
    Apparemment, il ne faut pas mettre les fichiers .h avec l'option -c et dans la variable $? ou $^ du makefile, j'ai le fichier c et le fichier h.

    Du coup, j'ai une erreur de GCC :
    gcc: fatal error: cannot specify -o with -c, -S or -E with multiple files
    Si je vire le -c alors j'ai une autre erreur :
    undefined reference to WinMain@16
    Si je vire le -o alors ca compile mais les fichiers ne sont pas créés dans obj/ donc après au linkage ca plante

    Sinon, si je comprends bien, si la personne en question par exemple créé un fichier "super header" nommé global.h avec tous les prototypes de fonction de tous les fichiers sources, et qu'il faut un #include "global.h" dans chaque ficheir source, ca ne marchera pas ?

    Deuxième question : si une personne créé un fichier source toto.c et un fichier header correspondant tata.h (donc les noms sont différents), est ce que ca va planter à la compilation ? (Je pense que oui)

    PS : En fait, je compile des projets d'élèves débutants en C et donc forcément, j'ai un peu tous les cas possible

  8. #8
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par Aspic Voir le message
    [...]
    Alors pour la compilation, j'ai un petit problème :

    Apparemment, il ne faut pas mettre les fichiers .h avec l'option -c et dans la variable $? ou $^ du makefile, j'ai le fichier c et le fichier h.

    Du coup, j'ai une erreur de GCC :
    Non effectivement, il ne faut jamais ajouter les headers à la commande de compilation.
    Le plus simple en général dans ce cas est soit de commencer*à lister les dépendances en commençant par le source (en général il n'y en a qu'un) suivi des headers. La variable automatique $< donne la première dépendance (donc le source) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cible.o: mon_source.c dep1.h dep2.h autredep.h
            $(CC) $(CFLAGS) -c $< -o $@
    Tu peux aussi utiliser des règles implicites (dire comment créer un .o à partir d'un .c). Tu listes d'abord les dépendances particulières (sans ordre particulier) pour une cible sans donner de recette :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cible.o: dep1.h dep2.h mon_source.c autredep.h
    puis plus loin tu décris comment construire n'importe quel fichier objet (ici le % joue le rôle d'un *=n'importe quelle chaine, mais il représente la même chaîne à gauche et à droite du :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    %.o: %.c
            $(CC) $(CFLAGS) -c $< -o $@
    Le $< te donnera toujours la première dépendance de la liste où il y a une recette. Ici en l'occurence la règle implicite.


    Citation Envoyé par Aspic Voir le message
    Si je vire le -c alors j'ai une autre erreur :

    Si je vire le -o alors ca compile mais les fichiers ne sont pas créés dans obj/ donc après au linkage ca plante

    Sinon, si je comprends bien, si la personne en question par exemple créé un fichier "super header" nommé global.h avec tous les prototypes de fonction de tous les fichiers sources, et qu'il faut un #include "global.h" dans chaque ficheir source, ca ne marchera pas ?

    Deuxième question : si une personne créé un fichier source toto.c et un fichier header correspondant tata.h (donc les noms sont différents), est ce que ca va planter à la compilation ? (Je pense que oui)

    PS : En fait, je compile des projets d'élèves débutants en C et donc forcément, j'ai un peu tous les cas possible
    Je pense qu'il vaut mieux ne jamais utiliser de «super header» sauf dans des cas particuliers (par exemple dans le cadre de la création d'une bibliothèque pour donner un header global à l'utilisateur de la bibliothèque).

  9. #9
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    C'est bon, j'ai réussi à compiler
    Citation Envoyé par kwariz Voir le message
    Je pense qu'il vaut mieux ne jamais utiliser de «super header» sauf dans des cas particuliers (par exemple dans le cadre de la création d'une bibliothèque pour donner un header global à l'utilisateur de la bibliothèque).
    Effectivement, je suis d'accord mais mes élèves ne le savent (ou n'écoutent pas) ^^ et donc ils peuvent me le faire (c'est déjà le cas). Du coup, parfois ca compile pas

    En mode HS, est ce qu'il est possible d'injecter une ligne de code juste après l'appel au main() ? Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(int argc, char** argv)
    {
    // du code
    }
    Et je voudrais injecter pour obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(int argc, char** argv)
    {
    InitCheckMemory();
    //du code
    }
    Merci encore.

  10. #10
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par Aspic Voir le message
    C'est bon, j'ai réussi à compiler

    Effectivement, je suis d'accord mais mes élèves ne le savent (ou n'écoutent pas) ^^ et donc ils peuvent me le faire (c'est déjà le cas). Du coup, parfois ca compile pas
    Si tu as donné des consignes claires et qu'elles ne sont pas respectées la solution est simple : sacque ces élèves

    Juste pour être clair, peux-tu m'expliquer ce qu'ils sont censés rendre et ce que tu fais avec ?

    Citation Envoyé par Aspic Voir le message
    En mode HS, est ce qu'il est possible d'injecter une ligne de code juste après l'appel au main() ? Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(int argc, char** argv)
    {
    // du code
    }
    Et je voudrais injecter pour obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(int argc, char** argv)
    {
    InitCheckMemory();
    //du code
    }
    Merci encore.
    Si tu demandes s'il est possible d'automatiquement exécuter du code avant main sans modifier le code la réponse est non.
    Moyen relativement simple : modifier le source.
    Moyen alambiqué (et sans garanties) avec gcc : -finstrument-functions est l'option qui à l'entrée et à la sortie de chaque fonction va appeler une fonction d'instrumentation. La doc gcc indique qu'elles s'appellent __cyg_profile_func_enter et
    __cyg_profile_func_exit. Elles ont le même prototype : deux paramètres les adresses de la fonction qui est appelée (tu peux avec d'autres fonctions récupérer le nom de cette fonction) et l'endroit où l'appel est émis. Du coup tu peux «exécuter du code avant le début de main» ... mais ce n'est ni prévu pour ni très simple.

  11. #11
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Citation Envoyé par kwariz Voir le message
    Juste pour être clair, peux-tu m'expliquer ce qu'ils sont censés rendre et ce que tu fais avec ?
    En fait, il s'agit de corriger la compilation des projets automatiquement. Il n'y avait pas de consignes claires pour cette année mais ca va changer
    Le but est de vérifier aussi la consommation mémoire des projets donc j'ai codé un programme qui redéfinie les fonctions d'allocation de mémoire. Maintenant pour initialiser ma lib, j'ai besoin d'ajouter une ligne dans le main et même aussi à la fin de l’exécution du programme afin de générer le rapport de mémoire automatiquement.

    Citation Envoyé par kwariz Voir le message
    Moyen alambiqué (et sans garanties) avec gcc : -finstrument-functions est l'option qui à l'entrée et à la sortie de chaque fonction va appeler une fonction d'instrumentation. La doc gcc indique qu'elles s'appellent __cyg_profile_func_enter et
    __cyg_profile_func_exit. Elles ont le même prototype : deux paramètres les adresses de la fonction qui est appelée (tu peux avec d'autres fonctions récupérer le nom de cette fonction) et l'endroit où l'appel est émis. Du coup tu peux «exécuter du code avant le début de main» ... mais ce n'est ni prévu pour ni très simple.
    Oui j'ai accès aux codes sources, je vais regarder de ce côté

  12. #12
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Ok ... si tu redéfinis les fonctions d'allocation de mémoire il y a peut-être une solution (toujours alambiquée mais un peu plus simple) : toujours avec gcc tu peux créer ta bibliothèque ou ton fichier objet et utiliser l'attribut de fonction constructor.
    Si tu as l'assurance qu'une fonction au moins est utilisée alors les fonction marquées de l'attribut constructor seront automatiquement appelées avant l'exécution de ton main. Il y a l'équivalent pour la terminaison : l'attribut destructor. Les fonctions doivent être de type void (*)(void). Dans ton cas tu pourrais avoir dans ton source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    static void InitCheckMemory(void) __attribute__((__constructor__));
     
    ...
     
    static void InitCheckMemory(void)
    {
      ...
    }
    Tu peux trouver un exemple de ce mécanisme dans le template de projet makefile que j'ai posté, regarde dans le répertoire lib.
    Attention : cela ne fonctionnera qu'avec gcc (et icc le compilo d'intel mais je n'en suis pas 100% certain).

  13. #13
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Merci beaucoup, effectivement cela marche avec gcc.
    Dommage qu'avec g++ ca ne marche pas mais c'est pas grave pour l'instant, on ne fait que du C.


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 12/08/2014, 17h48
  2. Réponses: 0
    Dernier message: 16/09/2010, 08h55
  3. Mise à jour des fichiers syst lors d'une installation
    Par Asdorve dans le forum Installation, Déploiement et Sécurité
    Réponses: 3
    Dernier message: 03/07/2006, 15h27
  4. Accès à des fichiers pour ouverture d'une image
    Par noutnout53 dans le forum C++
    Réponses: 4
    Dernier message: 02/06/2006, 15h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo