Question

test.c:

int main()
{
    return 0;
}

Je ne l'ai pas utilisé de drapeaux (je suis un newb à gcc), juste la commande:

gcc test.c

Je l'ai utilisé la dernière TDM construction de GCC sur win32. L'exécutable résultant est presque 23KB, trop grand pour un programme vide.

Comment puis-je réduire la taille de l'exécutable?

Était-ce utile?

La solution

Ne pas suivre ses suggestions, mais pour l'amour d'amusement, lisez ce ' histoire ' de faire le plus petit possible binaire ELF.

Autres conseils

  

Comment puis-je réduire sa taille?

  • Ne pas le faire. Vous venez de perdre votre temps.
  • Utilisez -s drapeau pour dépouiller les symboles (gcc -s)

Par défaut des bibliothèques standard (par exemple exécution C) liée à l'exécutable. Vérifiez clés --nostdlib --nostartfiles --nodefaultlib pour plus de détails. Options de lien décrit .

Pour le programme réel deuxième option est d'essayer options d'optimisation , par exemple -OS (pour optimiser la taille).

Abandonner. Linux x86, gcc 4.3.2 produit un binaire de 5 km. Mais attendez! C'est avec liaison dynamique! statiquement binaire est lié plus d'un demi meg: 516K. Détendez-vous et apprendre à vivre avec le ballonnement.

Et ils ont dit Modula-3 ne serait jamais aller nulle part à cause d'un 200K bonjour binaire monde!


Dans le cas où vous vous demandez ce qui se passe, la bibliothèque C Gnu est structurée de manière à inclure certaines fonctions si votre programme dépend ou non. Ces caractéristiques comprennent des trivia comme malloc et libre, dlopen, un certain traitement de chaîne, et son ensemble bucketload de choses qui semble avoir à faire avec les locales et l'internationalisation, bien que je ne peux pas trouver toutes les pages man correspondantes .

Créer des petits executables pour les programmes qui ont besoin de services minimum est pas un objectif de conception pour glibc. Pour être juste, il a également été pas un objectif de conception pour chaque système la gestion du temps que j'ai jamais travaillé avec (environ une demi-douzaine).

En fait, si votre code ne fait rien, est-il même juste que le compilateur crée encore un exécutable? ; -)

Eh bien, sous Windows ne importe quel exécutable serait encore ont une taille, mais il peut être raisonnablement petit. Avec l'ancien système MS-DOS, une application complète ne rien faire serait juste quelques octets. (Je pense que quatre octets d'utiliser l'interruption de 21 h pour fermer le programme.) Là encore, les applications ont été chargés directement dans la mémoire. Lorsque le format EXE est devenu plus populaire, les choses ont changé un peu. Maintenant eXecutables avait des informations supplémentaires sur le processus lui-même, comme le déplacement des segments de code et de données ainsi que quelques checksums et informations sur la version. L'introduction de Windows a ajouté un autre en-tête au format, de dire MS-DOS qu'il n'a pas pu exécuter l'exécutable car il avait besoin de fonctionner sous Windows. Et Windows reconnaîtra sans problème. Bien sûr, le format exécutable a également été étendu avec des informations de ressources, comme les bitmaps, les icônes et les formes de dialogue et beaucoup, beaucoup plus.

Un exécutable qui ne fait rien serait aujourd'hui entre 4 et 8 kilo-octets en taille, en fonction de votre compilateur et chaque méthode que vous avez utilisé pour réduire sa taille. Il serait à une taille où UPX entraînerait effectivement dans les grandes executables! octets supplémentaires dans votre exécutable peuvent être ajoutées parce que vous avez ajouté certaines bibliothèques à votre code. En particulier, les bibliothèques avec des données initialisées ou des ressources ajouteront une quantité considérable d'octets. L'ajout d'informations de débogage augmente également la taille de l'exécutable.

Mais alors que tout cela fait un exercice agréable à réduire la taille, on peut se demander si elle est pratique de simplement continuer à se soucier de ballonnement des applications. disques durs modernes se divisent les fichiers en segments et pour les disques vraiment grandes, la différence serait très faible. Toutefois, le montant de la difficulté qu'il faudrait pour garder la taille aussi petite que possible va ralentir la vitesse de développement, sauf si vous êtes un développeur expert qui est utilisé pour ces optimisations. Ces types d'optimisations ne tendent pas à améliorer les performances et compte tenu de l'espace disque moyen de la plupart des systèmes, je ne vois pas pourquoi il serait pratique. (Pourtant, j'optimiser mon propre code de la même façon, mais là encore, je suis expérimenté avec ces optimisations.)


Intéressé tête EXE ? Il est commence par les lettres MZ, pour « Mark Zbikowski ». La première partie est l'ancienne tête MS-DOS pour executables et est utilisé comme un bout à MS-DOS disant que le programme est pas un exécutable MS-DOS. (Dans le binaire, vous pouvez trouver le texte qui est essentiellement tout ce qu'il fait « Ce programme ne peut pas être exécuté en mode DOS. »:. Afficher ce message suivant est l'en-tête PE, lequel Windows reconnaîtra et utiliser au lieu de la MS-DOS en-tête. Il commence par les lettres PE Portable Executable. Après cela, deuxième en-tête, il y aura l'exécutable lui-même, divisé en plusieurs blocs de code et des données. l'en-tête contient des tableaux de réallocation spéciaux qui indique au système d'exploitation où charger un bloc spécifique. et si vous pouvez garder cela à une limite, l'exécutable final peut être inférieur à 4 Ko, mais 90% serait alors l'information-tête et aucune fonctionnalité.

J'aime la façon dont le DJGPP FAQ a abordé cette il y a beaucoup de nombreuses années :

  

En général, à en juger la taille de code en regardant la taille des programmes « Hello » n'a pas de sens, parce que ces programmes se composent principalement du code de démarrage. ... La plupart de la puissance de toutes ces caractéristiques gaspillée dans des programmes passe comme « Bonjour ». Il n'y a pas de point à passer tout ce code juste pour imprimer une chaîne de 15 octets et la sortie.

Quel est le but de cet exercice?

Même avec aussi bas un langage de niveau C, il y a encore beaucoup de configuration qui doit se produire avant que principal peut être appelé. Une partie de cette configuration est assurée par le chargeur (qui a besoin de certaines informations), une partie est gérée par le code qui appelle principal. Et puis il y a probablement un peu de code de la bibliothèque que tout programme normal devrait avoir. Au moins, il y a probablement fait référence aux bibliothèques standard, si elles sont dll.

Examiner la taille binaire du programme vide est un exercice sans valeur en soi. Il ne vous dit rien. Si vous voulez apprendre quelque chose sur la taille du code, essayez d'écrire des programmes non vides (et de préférence non triviales). Comparer les programmes qui utilisent des bibliothèques standard avec des programmes qui font tout eux-mêmes.

Si vous voulez vraiment savoir ce qui se passe dans ce binaire (et pourquoi il est si grand), puis trouver le format exécutable obtenir un outil de vidage binaire et prendre la chose à part.

Qu'est-ce que « size a.out » vous dire au sujet de la taille du code, les données et les segments de bss? La majorité du code est susceptible d'être le démarrage code (crt0.o classique sur des machines Unix) qui est invoquée par le o / s et fait mettre en place le travail (comme le tri des arguments de ligne de commande dans argc, argv) avant d'invoquer main().

bande Exécuter sur le binaire pour se débarrasser des symboles. Avec la version gcc 3.4.4 (cygming spéciale) Je laisse tomber de 10k à 4 Ko.

Vous pouvez lier un temps de course sur mesure (la partie qui appelle principal) pour configurer votre environnement d'exécution. Tous les programmes utilisent le même pour configurer l'environnement d'exécution qui vient avec gcc mais pour votre exécutable que vous n'avez pas besoin de données ou la mémoire zero'ed. Les moyens que vous pourriez se débarrasser des fonctions de bibliothèque inutilisées comme memset / memcpy et de réduire la taille crt0. Lorsque vous cherchez plus d'infos sur ce regard sur GCC dans un environnement intégré. développeurs de systèmes embarqués sont en général les seules personnes qui utilisent des environnements d'exécution personnalisés.

Le reste est frais généraux pour le système d'exploitation qui charge le fichier exécutable. Tu ne vas pas à même beaucoup là à moins que vous syntoniser que la main?

En utilisant GCC, compiler votre programme en utilisant -Os plutôt que l'un des autres drapeaux d'optimisation (ou de -O2 -O3). Cela indique à optimiser la taille plutôt que la vitesse. Soit dit en passant, il peut parfois faire des programmes courir plus vite que les optimisations de vitesse aurait, si un segment critique arrive à adapter plus bien. D'autre part, -O3 peut effectivement induire une augmentation de taille de code.

Il pourrait aussi y avoir des drapeaux de l'éditeur de liens lui disant de laisser de code inutilisé du binaire final.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top