mikrocontroller.net

Forum: Compiler & IDEs WINAVR: eigene Librarys einbinden, nur mit verwendeten funktionen?


Autor: grooves (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst die Funktionen sinnvoll in einzelne Sourcedateien unterbringen 
und dann erst die daraus erstellten Objektdateien zur Library 
zusammenfassen. Der Linker kann dann aus der Library die unbenutzten 
Objektdateien weglassen. EineStückelung innerhalb einer Objetdatei ist 
nicht möglich.

Autor: grooves (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: grooves (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marcus Müller (marcus67)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, nicht ganz.  Der Linker lädt erst einmal alles, schmeißt
danach aber alles wieder weg, was global nicht gegenseitig
referenziert ist.

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
/*+Common:*/
#include <...>
/*+File: foo.c */
void foo()
{}
/*+File: bar.c */
void bar()
{}
/*+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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Viel einfacher ist es doch mit Präprozessor, aber das steht hier ja auch 
schon als Vorschlag.

Autor: Marcus Müller (marcus67)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

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.