www.mikrocontroller.net

Forum: Compiler & IDEs Unbenutzten Code durch GCC entfernen lassen


Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Liebe GCC-Spezialisten,

ich erstelle ein Programm in C mit GCC und möchte jetzt gerne den 
unbenutzten Code durch den GCC rauschmeißen lassen. Dazu nehme ich nach 
WEB-Anleitung den Compilerswitch

CFLAGS += -ffunction-sections

hinzu, der mir die functions jeweils in eine eigene Section packt. Das 
klappt, denn wenn ich das ohne Rauschmeissen zusammenlinke gehts.

Dann sage ich dem Linker mit

LDFLAGS = -Wl,-Map=$(TARGET).map,-gc-sections,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)

dass er die unbenutzten Sections rausschmeissen soll.
Das scheint auch zu klappen, das .elf File ist kleiner.
Der Umbau des .elf Files zum ladbaren .hex file gelingt aber nicht, das 
.hex file wird dann sehr kurz, 13 Byte.

Die commandline lautet dazu:
avr-objcopy -O ihex -R .eeprom main.elf main.hex

Was mache ich denn da falsch?

THX
Cheers
Detlef

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu wenig Information, daher nur Gestocher:
text.* oder text* im Linker-Skript? Entry im Linker-Skript gesetzt? Nur 
von der Hardware "direkt" aufgerufenen Code (Interrupt-Handler und/oder 
Vector-Tabelle(n)) per KEEP im Linker-Skript vor unused-code-removal 
geschützt?

Minimale Beispielanwendung mit allen notwendigen Dateien und 
Beschreibung, wie das Problem nachzuvollziehen ist erzeugen, 
zusammenpacken und als Attachment hier einstellen.

Autor: OlliW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

die Antwort auf die Frage wie man den avr-gcc dazu bringt unbenutzte 
Funktionen rauszuschmeissen würde mich auch interessieren.

Suchen - und ich bin eigentlich ein fleissiger Sucher - hat mich bisher 
nicht weiter gebracht (sorry). Ich verstehe dass auch nicht so ganz, 
warum macht ein optimierender Compiler die einfachste Optimierung nicht 
automatisch selber?

Ciao,
  Olli


PS: Ich gebe zu ein Windowsuser zu sein, Dinge wie Linkerskripte oder 
make-Files lösen bei mir keine Begeisterung aus. Ich benutze WinAvr + 
AVR-Studio. Beispiel C-Program ist einfach: Standard includes, zwei 
Funktionen definieren, im main nur eine davon aufrufen. Das .lst File 
zeigt Code für beide Funktionen an, und das .hex File ist auch grösser 
als wenn man die unbenutze Funktion per Hand auskommentiert.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OlliW schrieb:

> Suchen - und ich bin eigentlich ein fleissiger Sucher - hat mich bisher
> nicht weiter gebracht (sorry). Ich verstehe dass auch nicht so ganz,
> warum macht ein optimierender Compiler die einfachste Optimierung nicht
> automatisch selber?

Weil das keine Sache des Compilers ist, sondern des Linkers.

Der Compiler kennt nur im Ausnahmefall das komplette Programm. Aber 
abgesehen davon, sieht er immer nur Bruchstücke. Wenn er eine Funktion 
vorgeworfen bekommt, weiß er nicht, wo diese Funktion überall verwendet 
wird, es könnte ja auch in einem ganz anderen *.c ein Aufruf dieser 
Funktion stehen.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Beste ist immer noch, wenn man seinen Code selber von "Hand" 
ausmistet und den nicht benötigten Müll rauswirft! Nur so bleiben 
Projekte überschaubar bzw. man behält als Programmierer den Überblick!

Ausnahme: Wenn man seine eigene Funktionssammlung als "Lib" übersetzt, 
pickt sich der Linker nur die wirklich benötigten Funktionen raus!

Autor: OlliW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Weil das keine Sache des Compilers ist, sondern des Linkers.

OK, da war ich schlampig, also neuer Versuch: Ich verstehe dass auch 
nicht so ganz, warum wird ein optimierender Compiler mit einem Linker 
verpackt der die einfachste Optimierung nicht automatisch selber macht? 
:-)

@Peter: das ist Ansichtssache. Ich programmiere sonst mit VisualC und 
finde es sehr angenehm dass der mir meinen "Müll" rauswirft :-)

Olli

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Müll rauswerfen und total optimieren:

--combine
-fwhole-program


Peter

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ich erstelle ein Programm in C mit GCC und möchte jetzt gerne den
>unbenutzten Code durch den GCC rauschmeißen lassen.
Unbenutzten Code schmeißt man nicht rau, man schreibt ihn erst gar nicht 
erst rein. :)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Müll rauswerfen und total optimieren:
>
> --combine
> -fwhole-program
>
>
> Peter

Ja, aber vergiss nicht zu sagen, dass dann alle .c Dateien in einem 
Compileraufruf kompiliert werden müssen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
>>ich erstelle ein Programm in C mit GCC und möchte jetzt gerne den
>>unbenutzten Code durch den GCC rauschmeißen lassen.
> Unbenutzten Code schmeißt man nicht raus, man schreibt ihn erst gar
> nicht erst rein. :)

:-)
Wenn man Code-Baugruppen nicht in Form einer Library benutzt, ist es 
unausweichlich
entweder Funktionen zu haben, die nie benutzt werden
oder den Code mit #ifdef zu spicken, so dass sich der Benutzer aussuchen 
kann, was davon mitcompiliert wird und was nicht.
oder sonst irgendeinen Compile/Linker spezifischen Hack gibt, mit dem 
man das Problem lösen kann.

Ein reiner C-Linker kann noch nicht aufgerufene Funktionen detektieren 
und rausschmeissen, weil es auf jeden Fall eine Referenz auf die 
Funktion irgendwo geben muss. Für C++ Kombi-Linker ist das allerdings 
schwieriger bis unmöglich (Stichwort: virtuelle Funktionen).

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OlliW schrieb:
>...
> PS: Ich gebe zu ein Windowsuser zu sein, Dinge wie Linkerskripte oder
> make-Files lösen bei mir keine Begeisterung aus. Ich benutze WinAvr +
> AVR-Studio. Beispiel C-Program ist einfach: Standard includes, zwei
> Funktionen definieren, im main nur eine davon aufrufen. Das .lst File
> zeigt Code für beide Funktionen an, und das .hex File ist auch grösser
> als wenn man die unbenutze Funktion per Hand auskommentiert.

Dann halt das AVR-Studio Projekt mit allen Dateien zusammenpacken und 
hier anhängen. Das von AVR-Studio erzeugte makefile drin lassen (per 
default im UVZ default, dann können auch nicht-MS-Windows nutzer 
"mitraten"). Zumindest mit neueren gcc aus neueren WinAVR keine Probleme 
mit function-sections/gc-section gehabt, auch in Kombination mit 
AVR-Studio.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit function-sections/gc-section funktioniert das jetzt. War auch schon 
mal in Beitrag "AVR-GCC Kompiliert nicht benutzte Funktionen mit ein" breit dargestellt, 
hab ich erst später gesehen. Problem war Version des gcc, ich war bei 
3.4 ;-(  , mit dem neuen gings.

>>--combine
>>-fwhole-program
Da muß man jedesmal alles compilieren ?! Das kann dauern.

>>ich erstelle ein Programm in C mit GCC und möchte jetzt gerne den
>>unbenutzten Code durch den GCC rauschmeißen lassen.
>Unbenutzten Code schmeißt man nicht rau, man schreibt ihn erst gar nicht
>erst rein. :)
Super Idee, wäre ich nicht drauf gekommen, es ist immer eine 
Bereicherung, wenn ein erfahrener Entwickler so helfen kann.


THX2ALL
Cheers
Detlef

Autor: OlliW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ha, jetzt habe ich extra ein Beispiel zusammengestellt und schon gibt es 
die Lösung... wenn das nur immer so ginge das alleine die Möglichkeit 
dass ein Beispiel gepostet wird ausreicht um zu einer Lösung zu 
kommen... ist ja fast quantenmechanisch... ne, echt SUPER, Danke Martin 
und Detlef!!

Und bei meinen Beispiel werden es statt 568 (alle Funktionen) und 216 
bytes (nur die benutzte Funktion) mit dieser Lösung am Ende sogar nur 96 
bytes (egal mit oder ohne unbenutze Funktionen)!

Olli

PS: eigentlich gehört soetwas doch in ein gcc-Tutorial mit und GANZ oben 
rein...

PSS: und warum macht der avr-gcc das jetzt nochmal nicht automatisch von 
selbst? ne, Scherz... echt cool :-)

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Und bei meinen Beispiel werden es statt 568 (alle Funktionen) und 216
>bytes (nur die benutzte Funktion) mit dieser Lösung am Ende sogar nur 96
>bytes (egal mit oder ohne unbenutze Funktionen)!

Ob das Programm jetzt aber noch das tut, was es soll?

Und auf die Gefahr hin, etwas zu wiederholen:

>Unbenutzten Code schmeißt man nicht rau, man schreibt ihn erst gar nicht
>erst rein. :)

Funktionssammlungen, bei denen man nicht genau weiß, was davon alles 
benutzt wird, packt man halt in eine lib. Wurde die richtig gebaut, holt 
sich der linker daraus nur das, was benötigt wird. Ganz automatisch, 
ohne zusätzliche Optionen.

Oliver

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:
> Funktionssammlungen, bei denen man nicht genau weiß, was davon alles
> benutzt wird, packt man halt in eine lib. Wurde die richtig gebaut, holt
> sich der linker daraus nur das, was benötigt wird. Ganz automatisch,
> ohne zusätzliche Optionen.

Da eine library aber auch nur eine Dateisammlung ist, hast Du genau
das selbe Problem. Der Compiler erzeugt ELF sections für Code und
Daten. Alle Funktionen (Code) einer compilation unit landen in der
selben ELF section.  Der Linker kann eine section nun einbinden oder
weglassen. Existiert auch nur eine Referenz auf eine einzige Funktion
in dieser section, dann muss diese komplett in das image übernommen
werden.

Um das zu vermeiden, kannst Du den Compiler anweisen, jede Funktion in
seine eigene ELF section zu legen (siehe weiter oben im
Thread). Nachteil: Einige Optimierungen können vom Compiler nicht mehr
durchgeführt werden. Außerdem vergrößert sich die Menge der
Verwaltungsdaten (section table) im ELF image möglicherweise
erheblich, was aber bei MCU Anwendungen ohne ELF loader nicht so eine
große Rolle spielt.

Gruß
Marcus
http://www.doulos.com/arm/

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Alle Funktionen (Code) einer compilation unit landen in der
>selben ELF section.

Richtig. Daher mein Zusatz:
>Wurde die richtig gebaut,...

Eine lib sollte man natürlich aus mehreren sinnvoll zusammengestellten 
compilation units zusammenbasteln.

Oliver

Autor: A. W. (uracolix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Eine lib sollte man natürlich aus mehreren sinnvoll zusammengestellten
> compilation units zusammenbasteln.

Beim Linken von strukturierten Libraries bin ich bisher auch
auf keinerlei Probleme "ala jetzt geht das Programm nicht mehr" 
gestossen.
D.h. alle Funktionen die sich bedingen in ein gemeinsames C-File packen,
wenn es zu unübersichtlich wird, dann die Funktionen vereinzeln. Das 
ganze als Library zusammenfassen und zum Main-Programm Linken. Das 
funktioniert soweit ich weiss auch beim IAR. Vorteil ist, es sind keine 
abenteuerlichen Compilerschalter im Spiel und man kann damit auch prima 
Default-Callback-Funktionen handhaben. Wenn der Nutzer sie definiert 
hat, dann wird das Object-File aus der Library gar nicht erst gelinkt.

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Oliver

Oliver schrieb:
> Richtig. Daher mein Zusatz:
>>Wurde die richtig gebaut,...

Peter schrieb:
> Ausnahme: Wenn man seine eigene Funktionssammlung als "Lib" übersetzt,
> pickt sich der Linker nur die wirklich benötigten Funktionen raus!

Es konnte beim Leser der Eindruck entstehen, dass der Linker eine 
(statische) Library grundsätzlich anders behandelt als einzelne Objekte.
Wir wissen, das das nicht der Fall ist. Ich hätte also eher Peter 
antworten sollen, als Dir.

Gruß
Marcus
http://www.doulos.com/arm/

Autor: maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Müll rauswerfen und total optimieren:
>
> --combine
> -fwhole-program

Simon K. schrieb:
> Ja, aber vergiss nicht zu sagen, dass dann alle .c Dateien in einem
> Compileraufruf kompiliert werden müssen.

Ich möchte das Thema hier noch einmal aufnehmen. Trotz "compile all" 
erhalte ich dutzende Fehlermeldungen undefined reference to function...

Hat jemand einen Tip woran das liegen kann. Ich nutze WinAVR-20080610 
und das AVR Studio (dort habe ich auch die Compileroptionen hinzugefügt)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
maxim schrieb:
> Hat jemand einen Tip woran das liegen kann.

Daran, dass du dich nicht an das hier hältst:
> alle .c Dateien in einem
> Compileraufruf kompiliert werden müssen.

Oder benutzt du etwa ein eigenes Makefile?

Autor: maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Daran, dass du dich nicht an das hier hältst:
>> alle .c Dateien in einem
>> Compileraufruf kompiliert werden müssen.

maxim schrieb:
> Trotz "compile all"
> erhalte ich dutzende Fehlermeldungen undefined reference to function...

Ich gehe davon aus, dass mit compile all diese getan wird. Wenn nicht, 
dann sagt mir bitte was ich sonst machen muss

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
maxim schrieb:

> Ich gehe davon aus, dass mit compile all diese getan wird.

Damit wird vielleicht alles übersetzt, aber nicht mit einem 
Compileraufruf, sondern mit mehreren separaten Aufrufen.

> Wenn nicht, dann sagt mir bitte was ich sonst machen muss

Eigenes Makefile verwenden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.