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. ====Fonctions pures virtuelles==== Ces méthodes peuvent augmenter la taille du code avec l'ajout des méthodes __cxa_pure_virtual __stack_chk_fail On peut remplacer facilement : virtual void doIt() = 0; par virtual void doIt(){} =====Méthode automatique===== Options de GCC ([[https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc.pdf|Using the GNU Compiler Collection]] {{ :prog:gcc:gcc-7.2.0.pdf |Archive}}) : ''-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.
''-fno-enforce-eh-specs''
Don’t generate code to check for violation of exception specifications at run time. This option violates the C++ standard, but may be useful for reducing code size in production builds, much like defining NDEBUG. This does not give user code permission to throw exceptions in violation of the exception specifications; the compiler still optimizes based on the specifications, so throwing an unexpected exception results in undefined behavior at run time.
Option pour le lieur : ''-Wl,%%--%%gc-sections'' ([[https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gnat_ugn.pdf|GNAT User’s Guide for Native Platforms]], {{ :prog:gnat:gnat_ugn-7.2.0.pdf |Archive}}) g++ -Wl,--gc-sections example_cpp example.o =====Supprimer toutes références à malloc (ou autre)===== 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 ''weak'' ''%%__%%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 microcontrôleur 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 une 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'ont é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 et réussi à compiler sans les objets précédemment supprimés, il est maintenant possible de remettre en place les librairies statiques (''libc.a'' et ''libcstdc++.a'') d'origine et normalement, la dépendance ne devrait pas réapparaitre.