WINAVR: eigene Librarys einbinden, nur mit verwendeten funktionen?

Gast #1000335
Lesenswert?

Hallo all,

wie kann man in winavr selbst geschrieben .a librarys einbinden, so das 
nur die aufgerufenen Funktionen im code verwendet werden ?
bei mir wird immer die gesamte Library im code verwendet,
was zu sinnloser programm-flash-verschwendung führt .
Bemerkt habe ich die ganze Sache, indem ich unbenutze Funktionen in der 
Library ausdokumentiert habe, wodurch der Programmcode kleiner geworden 
ist.
Ich dachte eigentlich das der Compiler selber merkt welchen Funktionen 
in der Library nicht verwendet werden und diese dann auch nicht in den 
Programmcode einbindet.
Vielleicht irgendeine Option im makefile ????

Danke im Vorraus,
Micha
Moderator Persönliche Seite #1000361
Lesenswert?

grooves wrote:

> wie kann man in winavr selbst geschrieben .a librarys einbinden, so das
> nur die aufgerufenen Funktionen im code verwendet werden ?

Eine Funktion pro Quelldatei schreiben.  Aus allen Objektdateien dann
eine Bibliothek bauen.  Der Linker hat keine Kennung darüber, was
genau eine ,,Funktion'' sei (welche globalen Daten gehören denn dann
zu dieser Funktion?), er arbeitet auf der Basis globaler Symbole und
von Objektmodulen.  Wenn ein Symbol eines Moduls einer Bibliothek
dazu beiträgt, ein zu diesem Zeitpunkt global undefiniertes Symbol
aufzulösen, dann wird der entsprechende Objektmodul aus der
Bibliothek eingefügt.  Ob der aus einer oder 50 Funktionen oder auch
gar keiner (nur globale Symbole im Datensegment betroffen) besteht,
interessiert ihn dabei nicht.
Gast #1000380
Lesenswert?

Danke für die schnellen Antworten,

ich verstehe, der Linker braucht einfach pro Funktion eine .o 
Objektdatei,
um diese ggf. der "Nichtbenutzung" auch weglassen zu können.
Gibt es denn evtl. ne elegante Lösung, aus einer gesamten .c Datei mit 
vielen Funktionen, pro Funktion eine .o Datei zu erzeugen,
wäre sehr komfortabel als pro Funktion eine .c Datei haben zu müssen.

Danke und Grüße,
Micha
Moderator Persönliche Seite #1000388
Lesenswert?

Ich weiß zwar nicht, was daran ,komfortabel' ist (außer du benutzt
ein krückiges Filesystem mit viel ,,Verschnitt'', FAT vielleicht),
aber außer x-mal compilieren mit #ifdef fällt mir nichts dergleichen
ein.  (Das macht die libgcc.a übrigens so.)

Übrigens ist die Aussage ,bei Nichtbenutzung weglassen' einfach mal
komplett falsch herum: es wird ,bei Benutzung genommen' und bei
Nichtbenutzung einfach ignoriert.
Gast #1000402
Lesenswert?

na gut, komfortabel find ich es einfach wenn ich nur "EINE" source-datei 
habe, wo z.B. alle meine util-funktionen drin sind,
die dann auch zu "EINER" util-lib führen,
hat jetzt weniger mit n Filesystem zu tun, sondern nur, aus meine Sicht,
... wie ordne und organisiere ich meine Sourcen.
das mit den #ifdef in der libgcc.a muß ich mir mal anschauen, vielleicht 
ist das ja das was mir vorschwebt.
Ansonsten kann ich auch damit leben, pro Funktion ein source-file zu 
haben,
ist ja noch recht übersichtlich an Funktionen was ich da geschrieben 
habe, :-)))

Also, nochmals Danke,
und Grüße,
Micha
#1001865
Lesenswert?

Eine Möglichkeit gibt es noch:

Mit der Compileroption -ffunction-sections und der Linker Option 
--gc-sections kannst Du Compiler/Linker beibringen, nur die Funktionen 
zu laden die auch verwendet werden - sogar ohne eine Library ganz normal 
beim Linken.

Keine Ahnung ob das auch Nachteile hat - würde mich auch mal 
interessieren.

Gruß, Marcus
Gast #1001909
Lesenswert?

Um auf die Sourcedatei zurueckzukommen, ich hatte ein aehnliches Problem 
zum Dateisplitten seinerzeit mit Kommentarmarken und einem Script 
geloest. Das C-File war in etwa so formatiert:
1
/*+Common:*/
2
#include <...>
3
/*+File: foo.c */
4
void foo()
5
{}
6
/*+File: bar.c */
7
void bar()
8
{}
9
/*+End:*/

Du musst deinem Projekt dann aber das passende Splitter-Script, dass im 
Makefile gerufen wird, mit beilegen. Am besten ist es das Script in 
einer HighLevel Scriptsprache wie Python oder Perl zu schreiben und sich 
nicht auf einen Tool-Zoo aus bash, csplit, gawk, sed, ... einzulassen.

Ciao, Axel
#1002283
Lesenswert?

Jörg Wunsch wrote:
> Naja, nicht ganz.  Der Linker lädt erst einmal alles, schmeißt
> danach aber alles wieder weg, was global nicht gegenseitig
> referenziert ist.

Hallo Jörg,
wie auch immer, auf jeden Fall ist es weg :-)

Hat das Verfahren eigentlich irgendwelche echten Nachteile (mal 
abgesehen von einem Haufen Sections) ?

Gruß, Marcus
Moderator Persönliche Seite #1002293
Lesenswert?

Marcus Müller wrote:

> Hat das Verfahren eigentlich irgendwelche echten Nachteile (mal
> abgesehen von einem Haufen Sections) ?

Ja, man muss mit Spezialfällen vorsichtig sein.  Eine Initialisierungs-
funktion in .init3 wird ja beispielsweise nie irgendwoher referenziert,
folglich wird sie der Linker rauskicken, wenn du sie nicht auch noch
als "used" markierst.

Einen wesentlichen Nachteil sehe ich, dass diese Funktionalität zu
schlampiger Programmierung verleiten kann: solange all das, was ich
hingeschrieben habe, auch im fertigen Code landet, werde ich darauf
achten, dass nur das noch da steht, was auch benutzt wird.  Wenn ich
mich drauf verlasse, dass der Linker ,,schon irgendwie aufräumt'',
dann kann sich da schnell Müll ansammeln, von dem man in zwei Jahren
erst umständlich recherchieren muss um festzustellen, dass diese
Funktion ja bereits seit der vorvorhergehenden Version gar nicht mehr
genutzt worden war.  (Das trifft natürlich auf den hier vorgestellten
Fall der Bibliotheken so nicht zu.)

Meines Wissens ist die entsprechende Funktionalität insbesondere im
Hinblick auf C++ in die Toolchain gewandert.  Dort gibt es
Konstellationen, bei denen die logische Überschattung bestimmter
Codeteile (bspw. Konstruktoren) für den Compiler nicht ersichtlich
ist, er deshalb den Code zweimal generiert.  Erst der Linker kann
dann feststellen, dass auch auf globalem Niveau einer von beiden
gar nicht benutzt wird.  Anders als oben hat in diesem Falle aber
der Programmierer gar keine Chance, die Doppelgenerierung zu
vermeiden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren