GNU/Linux >> Tutoriels Linux >  >> Linux

Comment diminuer la taille des binaires générés ?

Outre l'évidence (-Os -s ), l'alignement des fonctions sur la plus petite valeur possible qui ne plantera pas (je ne connais pas les exigences d'alignement ARM) peut extraire quelques octets par fonction.
-Os devrait désactivez déjà les fonctions d'alignement, mais cela peut toujours être par défaut une valeur comme 4 ou 8. Si l'alignement par ex. à 1 est possible avec ARM, cela peut économiser quelques octets.

-ffast-math (ou le moins abrasif -fno-math-errno ) ne définira pas errno et évitera certaines vérifications, ce qui réduit la taille du code. Si, comme la plupart des gens, vous ne lisez pas errno de toute façon, c'est une option.

Utiliser correctement __restrict (ou restrict ) et const supprime les charges redondantes, rendant le code à la fois plus rapide et plus petit (et plus correct). Marquer correctement les fonctions pures comme telles élimine les appels de fonction.

L'activation de LTO peut aider, et si cela n'est pas disponible, compiler tous les fichiers source dans un binaire en une seule fois (gcc foo.c bar.c baz.c -o program au lieu de compiler foo.c , bar.c , et baz.c aux fichiers objets d'abord, puis à la liaison) aura un effet similaire. Il rend tout visible à l'optimiseur en même temps, lui permettant éventuellement de mieux fonctionner.

-fdelete-null-pointer-checks peut être une option (notez que ceci est normalement activé avec n'importe quel "O", mais pas sur les cibles embarquées).

Mettre des globals statiques (vous n'en avez, espérons-le, pas autant, mais quand même) dans une structure peut éliminer beaucoup de frais généraux en les initialisant. J'ai appris cela lors de l'écriture de mon premier chargeur OpenGL. Avoir tous les pointeurs de fonction dans une structure et initialiser la structure avec = {} génère un appel à memset , tandis que l'initialisation des pointeurs de la "manière normale" génère une centaine de kilo-octets de code juste pour mettre chacun à zéro individuellement.

Évitez les constructeurs non triviaux static local variables comme le diable (les types de POD ne posent aucun problème). Gcc initialisera les threads locaux statiques non triviaux à moins que vous ne compiliez avec -fno-threadsafe-statics , qui contient beaucoup de liens de code supplémentaire (même si vous n'utilisez pas du tout de threads).

Utiliser quelque chose comme libowfat au lieu du crt normal peut grandement réduisez votre taille binaire.


Si vous voulez extraire jusqu'à la dernière goutte d'espace de vos fichiers binaires, vous devrez probablement apprendre l'assemblage. Pour une introduction très intéressante (et divertissante), consultez ce lien :

Un tutoriel Whirlwind sur la création d'exécutables ELF vraiment Teensy pour Linux


Vous pouvez également utiliser -nostartfiles et/ou -nodefaultlibs ou la combinaison des deux -nostdlib . Si vous ne voulez pas de fichier de démarrage standard, vous devez alors écrire votre propre fonction _start. Voir aussi ce fil (archivé) sur oompf :

(citant Perrin)

# man syscalls
# cat phat.cc
extern "C" void _start() {
        asm("int $0x80" :: "a"(1), "b"(42));
}
# g++ -fno-exceptions -Os -c phat.cc
# objdump -d phat.o

phat.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <_start>:
   0:   53                      push   %rbx
   1:   b8 01 00 00 00          mov    $0x1,%eax
   6:   bb 2a 00 00 00          mov    $0x2a,%ebx
   b:   cd 80                   int    $0x80
   d:   5b                      pop    %rbx
   e:   c3                      retq
# ld -nostdlib -nostartfiles phat.o -o phat
# sstrip phat
# ls -l phat
-rwxr-xr-x 1 tbp src 294 2007-04-11 22:47 phat
# ./phat; echo $?
42

Résumé :l'extrait ci-dessus a généré un binaire de 294 octets , chaque octet 8 bits.


En supposant qu'un autre outil est également autorisé;-)

Considérez alors UPX :l'Ultimate Packer for Binaries qui utilise la décompression d'exécution.

Bon codage.


Linux
  1. Comment augmenter la limite de taille de téléchargement de fichiers dans Apache

  2. Comment trouver la taille du tampon de socket de Linux

  3. Comment puis-je voir la taille des fichiers et des répertoires sous Linux ?

  4. Comment changer la taille de la police dans Dwarf-fortress ?

  5. Comment trouver la taille d'une partition non montée sous Linux ?

Comment obtenir la taille d'un répertoire sous Linux

Comment trouver la taille d'un répertoire sous Linux

Comment trouver la taille totale d'un répertoire sous Linux

À quel point les données sont-elles brouillées sur un disque RAID5 ?

Comment obtenir la taille physique d'un fichier sous Linux ?

Comment les commandes telles que fdisk -l trouvent-elles la taille du secteur ?