GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann man die Größe von generierten Binärdateien verringern?

Abgesehen von dem Offensichtlichen (-Os -s ), das Ausrichten von Funktionen auf den kleinstmöglichen Wert, der nicht abstürzt (ich kenne die ARM-Ausrichtungsanforderungen nicht), kann einige Bytes pro Funktion ausdrücken.
-Os sollte Ausrichtfunktionen sind bereits deaktiviert, aber dies kann immer noch auf einen Wert wie 4 oder 8 voreingestellt sein. Wenn Sie z.B. auf 1 ist mit ARM möglich, das könnte einige Bytes sparen.

-ffast-math (oder das weniger aggressive -fno-math-errno ) setzt errno nicht und vermeidet einige Überprüfungen, wodurch die Codegröße reduziert wird. Wenn Sie, wie die meisten Leute, errno sowieso nicht lesen, ist das eine Option.

Korrekte Verwendung von __restrict (oder restrict ) und const entfernt redundante Lasten, wodurch der Code sowohl schneller als auch kleiner (und korrekter) wird. Das richtige Markieren reiner Funktionen als solche eliminiert Funktionsaufrufe.

Die Aktivierung von LTO kann hilfreich sein, und wenn dies nicht verfügbar ist, kompilieren Sie alle Quelldateien auf einmal in eine Binärdatei (gcc foo.c bar.c baz.c -o program anstatt foo.c zu kompilieren , bar.c , und baz.c zuerst Dateien zu Objekten zu machen und dann zu verknüpfen) hat einen ähnlichen Effekt. Es macht alles auf einmal für den Optimierer sichtbar, wodurch er möglicherweise besser arbeiten kann.

-fdelete-null-pointer-checks kann eine Option sein (beachten Sie, dass dies normalerweise mit einem "O" aktiviert wird, aber nicht auf eingebetteten Zielen).

Statische Globals (hoffentlich haben Sie nicht so viele, aber trotzdem) in eine Struktur einzufügen, kann viel Overhead eliminieren sie zu initialisieren. Das habe ich gelernt, als ich meinen ersten OpenGL-Loader geschrieben habe. Alle Funktionszeiger in einer Struktur haben und die Struktur mit = {} initialisieren generiert einen Aufruf an memset , während die Initialisierung der Zeiger auf die "normale Weise" hundert Kilobyte Code generiert, nur um jeden einzeln auf Null zu setzen.

Vermeiden Sie statische local mit nicht-trivialem Konstruktor Variablen wie der Teufel (POD-Typen sind kein Problem). Gcc wird nicht-trivial-konstruktorische statische Locals threadsicher initialisieren, es sei denn, Sie kompilieren mit -fno-threadsafe-statics , die viel verlinkt von zusätzlichem Code (auch wenn Sie überhaupt keine Threads verwenden).

Die Verwendung von etwas wie libowfat anstelle des normalen crt kann großartig sein Reduzieren Sie Ihre Binärgröße.


Wenn Sie den letzten Tropfen Platz aus Ihren Binärdateien herausquetschen wollen, müssen Sie wahrscheinlich Assembler lernen. Eine sehr interessante (und unterhaltsame) Einführung finden Sie unter diesem Link:

Ein Wirbelwind-Tutorial zum Erstellen wirklich winziger ausführbarer ELF-Dateien für Linux


Sie können auch verwenden -nostartfiles und/oder -nodefaultlibs oder die Kombination aus beiden -nostdlib . Falls Sie keine Standard-Startdatei möchten, müssen Sie dann Ihre eigene _start-Funktion schreiben. Siehe auch diesen Thread (archiviert) auf oompf:

(Zitat von 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

Zusammenfassung:Das obige Snippet ergab eine Binärdatei von 294 Bytes , jedes Byte 8 Bit.


Vorausgesetzt, dass auch ein anderes Tool erlaubt ist;-)

Dann betrachten Sie UPX:den ultimativen Packer für Binärdateien, der Laufzeitdekomprimierung verwendet.

Viel Spaß beim Programmieren.


Linux
  1. Linux – Wie kombiniere ich den Baum mit der Verzeichnisgröße?

  2. So ändern Sie die MTU-Größe unter Linux

  3. So finden Sie die Socket-Puffergröße von Linux

  4. Wie kann ich die Größe von Dateien und Verzeichnissen in Linux sehen?

  5. Wie ändere ich die Schriftgröße in Dwarf-fortress?

So erhalten Sie die Größe eines Verzeichnisses in Linux

So ermitteln Sie die Größe eines Verzeichnisses in Linux

So ermitteln Sie die Gesamtgröße eines Verzeichnisses in Linux

Wie finden Befehle wie fdisk -l die Sektorgröße?

Wie bestimme ich die Blockgröße einer ext3-Partition unter Linux?

So bestimmen Sie die beste Bytegröße für den Befehl dd