Outils pour utilisateurs

Outils du site


amelioration:taille:c

Ceci est une ancienne révision du document !


Comment réduire la taille d'un programme

Cette page n'est utile que si la taille du programme est critique. À défaut, la simple option -Os est suffisante.

Collecter les informations

Map file

Ajouter l'option -Wl,-Map,binaire.map au LDFLAGS de la librairie ou de l'exécutable à générer.

Cela permet de récupérer la liste des symboles et la taille de toutes les fonctions que contiennent le binaire généré.

Binaire désassemblé

Modifier Makefile.am de la façon suivante :

all: all-am
  $(OBJDUMP) -h -S .libs/binaire.so > binaire.so.lss

objdump permet de désassembler un programme. Le code source sera aussi intégré si le code a été compilé avec des options de debug.

Cette méthode doit être utilisée et non gcc -S. L'objectif est d'analyser la taille de l'ensemble du projet et pas des fichiers objets indépendamment. Surtout que le lieur fait du gros ménage et se débarrasse de toutes les fonctions et symboles qui ne sont pas utilisés.

Méthode automatique

Options de GCC : -ffunction-sections -fdata-sections même si la documentation semble dire l'inverse.

g++ -ffunction-sections -fdata-sections -c -o example.o example.cpp

When you specify these options, the assembler and linker create larger object and executable files and are also slower.Source, Archive

Option pour le lieur : -Wl,–gc-sections

g++ -Wl,--gc-sections example_cpp example.o

TODO

Comment supprimer toutes références à malloc dans les micro-controleurs.

Tout d'abord s'assurer que ni malloc ni free n'est utilisé mais également aucun new ni delete.

Ensuite, il convient de “surcharger” la fonction C register_exitproc. Il s'agit d'une fonction exécutée au démarrage du programme qui est nécessaire pour que l'application s'arrête correctement. Le problème est que cette fonction fait appel à la fonction malloc. De plus, un microcontroleur n'a pas besoin de s'arrêter proprement, il est censé tourner 24 heures sur 24. Si cette fonction n'est pas définie, gcc ajoute donc la sienne. Il suffit donc de la définir quelque part dans le code. #if defined (cplusplus) extern “C” { #endif int register_exitproc(int type, void (*fn) (void), void *arg, void *d) { return -1; } #if defined (cplusplus) } #endif

Ensuite, en regardant le fichier .map du programme compilé, il est constaté la présence d'une variable malloc_av_ avec un espace mémoire de taille 0x408 (1032 octets). L'objectif va donc être de récupérer cet espace mémoire. Il est indiqué qu'elle est définie dans libc.a(lib_a-mallocr.o) Faire sauvegarde du fichier libc.a d'origine puis exécuter les commandes suivantes dans un dossier vide après avoir copier la librairie statique concernée : ar -x libc.a del lib_a-mallocr.o lib_a-freer.o lib_a-malloc.o libc.a ar r libc.a *.o Tous les fichiers objets supprimés précédemment l'on été par itération. Par exemple freer dépend de mallocr. Renouveler l'opération suivante avec le fichier libstdc++.a : ar -x libstdc++.a del del_op.o “libstdc++.a” ar r “libstdc++.a” *.o Cependant, avec la programmation orientée objet, le compilateur va mal vivre le fait de ne plus avoir de destructeur. Il est alors nécessaire de déclarer l'opérateur delete, en c++ uniquement. void operator delete(void *) { } Et alors, la variable malloc_av_ aura alors disparu comme par magie. Mais il faut bien noter que le compilateur ne sera plus en mesure d'effectuer de malloc/new ni de free/delete. Il s'agit donc d'une modification à faire dans un environnement contrôlé.

Après avoir détecté l'origine de la dépendant, il est maintenant possible de remettre en place les librairies static (libc.a et libcstdc++.a) d'origine et normalement, la dépendance ne devrait pas réapparaitre.

amelioration/taille/c.1498848021.txt.gz · Dernière modification : 2017/06/30 20:40 de root