mikrocontroller.net

Forum: Compiler & IDEs Linker dynamisch?


Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
mal ne Frage zum Linker.
Kann der gnu c linker (speziell beim avr gcc) eigentlich nur statisch
linken, also immer nur komplette object files oder holt der sich aus
den files nur die funktionen raus die im programm wirklich angesprungen
werden?
 also ich hab zb na math lib mit den funktionen x() y() und z(), das
Programm braucht aber nur z(). Wird dann aus der lib "math" nur z()
dazugelinkt oder alles?

JarJar

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo JarJar,

das kannst Du leicht ausprobieren - lass ihn doch mal irgendwas
dazulinken, was Du garnicht verwendest.

Meine Erfahrung ist, dass alles was man zum Linken angibt auch
dazugelinkt wird (zumindest bei selbstgeschriebenen Projektteilen). Im
Klartext, wenn ich meine LCD-Lib mitlinke und keine einzige Funktion
verwende, dann kommt im ObjectCode auch die ganze LCD-Lib vor.
Theoretisch kann der Linker herausfinden, was man wirklich braucht und
was nicht - in wie fern der Linker bnei avrgcc das macht - keine
Ahnung.

Wenn jemand Hinweise hat, wie man den Linker dazu erzieht nicht
verwendete Funktionalität beim Linken wegzulassen - als her damit. Ich
würde mich schon dafür interessieren. Das nur am Rande. Ich habe dazu
noch nicht viel recherchiert - als bitte keine RTFMs - sagt einfach,
ob's geht oder nicht und schreibt das, was Ihr gerade dazu im Kopf
habt....

MfG, Daniel.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Begriffsdefinition ist etwas problematisch. Als dynamisches Linken
bezeichnet man es, wenn Bibliotheken zur Laufzeit des Programms ad-hoc
nachgeladen werden. Bei Microcontrollern eher unüblich.

Zudem ist es grad andersrum als von dir skizziert. Beim dynamischen
Linken wird prinzipbedingt stets die komplette Biblilothek geladen.
Beim statischen Linken hingegen nur der minimal notwendige Teil ins
Programm direkt eingebunden. Was genau diesen Teil ausmacht hängt von
der verwendeten Darstellung der Funkionen im Objektfile ab (neuere vor
allem im C++-Umfeld entstandene Link-Techniken) und mitunter auch
davon, wie fein der Autor der Library die einzelnen Funktionen in
einzelne Objektfiles aufgedröselt hat (ältere Link-Techniken,
Assembler-Quelltext).

Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, ok. Wie nennt man das dann wenn der Linker in der Lage ist nur den
benötigten Code aus ner Lib zum endgültigen Programm zu linken und kann
der AVR GCC das? Bei "größeren" Compilern hab ich das schon gesehen.

JarJar

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das nennt man Linken. Oder statisches Linken. Und es wird seit anno
Tobak so gemacht. Ich hab's eigentlich fast nie anders gesehen.

Blöd ist lediglich, wenn der Autor der Lib zu faul war, die einzelnen
Funktionen in seinem Quelltext in einzelne Files aufzudröseln, sondern
der Einfachheit halber alle in ein einziges File schmiss. Dann hat
mancher Linker wenig Chancen und schnappt sich alles en bloc.

Hast Du einen konkreten Anlass für deine Frage? Ich hab das Gefühl Du
rennst offene Türen ein.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo A.K.

nach Deinen Ausführungen würde man für jede einzelne Funktion eine
eigene Datei benötigen. Das kann so nicht sein - ist ja für den Linker
auch nicht wirklich ein Problem.

Tatsächlich habe ich beim Erstellen von Programmen bemerkt, dass auch
wenn eine Lib nur eine Funktion enthält und diese nicht im Programm
verwendet wird, der Code sich trotzdem um das Maß dieser Funktion
vergrößert (beim Programmerstellen für den µC). Weißt Du (oder jemand
anders) nun, ob und wenn wie man den Linker dazu bringen kann, nur die
Teile dazuzulinken, die auch wirklich verwendet werden ?

MfG, Daniel

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man benötigt für jede Optionale Funktion ein eigenes objectfile, das
Später in eine Library eingefügt wird!
Beispiele wie 'free' und 'malloc' können dabei wieder in einem
objectfile stecken, da sie eh voneinander abhängig sind.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab ich noch nicht erlebt. Was ich indes öfter erlebt habe, ist die
Frage warum zum Teufel der Linker auf die hirnrissige Idee kommt grad
die exotische Funktion einzubinden, die ich garantiert nirgends
verwendet habe. Naja. wie üblich stellt sich dann heraus, recht hat er
doch. Um ein paar Ecken herum beispielsweise. Oder im Startup-Code.
Oder...

"nach Deinen Ausführungen würde man für jede einzelne Funktion eine
eigene Datei benötigen. Das kann so nicht sein"

Weil nicht sein kann was nicht sein darf? Grad so arbeiten
traditionelle Linker. Bei denen ist das Objektfile eine unteilbare
Einheit. Wie schon gesagt, erst im Umfeld von C++ und Templates hat
sich das gezwungenermassen geändert. Was nicht unbedingt heisst, dass
GCC/AVR das so macht, nur das es da technisch sicherlich möglich ist
(keine Ahnung ob oder ob nicht, ich hab mir das noch nicht angesehen).

Guck dir Quelltexte von Standard-C-Libraries an (string.h, math.h und
sowas). Üblicherweise für jeden Kleinscheiss ein eigenes File. Warum
wohl?

"ist ja für den Linker auch nicht wirklich ein Problem."

Ach? Wie soll der Linker die Funktionen auseinander halten, wenn sie
ihm im Objektfile als geschlossener Block präsentiert werden? Keine
Chance. Erst wenn die Compiler/Assembler jede Funktion als
eigenständige Einheit im Objektfile unterbringen (muss das Obj-Format
freilich erst mal abkönnen), dann geht das.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NB: Ein Freund und ich hatten anno 68000 mal ein eigenes System
entwickelt, mit Betriebssystem, C-Compiler, Assembler, Linker usw. Der
Compiler stammte von der Uni, der Rest war Eigenbau. Jedenfalls hatte
mich just diese Eigenheit von Libraries genauso gestört, weshalb das
Objektfile-Format denn auch identisch dem Library-Format war, und
Compiler/Assembler bis zu 32 unabhängige Module in einem Quelltext
unterbringen konnten. Uns war's einfach zu blöd, wegen jedes einzelnen
5-Zeilers eigens den damals ja von Floppy-Disk gestarteten Compiler
anwerfen zu müssen. Diesen Trick (obj=lib) habe ich freilich noch
nirgends wiedergefunden, wenngleich ich es bis heute für sinnvoll
halte.

Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum wird eigentlich so ne Diskussion draus? Ein simples "Ja" oder
"Nein" hätte gereicht.

d.h. also wenn ich ne brauchbare und kleine Library von Funktionen
erstellen will muß ich alles in möglichst kleine Blocks unterteilen und
in einzelnen Object Files speichern.

Mal ein Beispiel: Ich schreibe eine Lib für ein Display, da gibts die
Funktionen "Init", "Write", "Clear", "Cursor_Pos" und noch
einige mehr. All diese Funktionen müsste ich in einzelnen Files
abspeichern und der Programmierer müsste manuell bestimmen welche der
Funkitonen er in seinem Programm hat? Das ist doch so ineffizient und
unkomfortabel wie nur was

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso denn bitte Manuell?

Das macht ja gerade der Linker für den Programmierer, nicht der
Programmierer selbst! Ganz weit hergeholt muss natürlich doch wieder
der Programmierer entscheiden, was reinkommt und was nicht, aber das
macht er ganz unterbewusst, indem er eine Funktion entweder benutzt,
oder eben nicht ;-)

Ist Deine Library gut organisiert, und der Programmierer verwendet eine
darin enthaltene Funktion nicht (weil er sie nicht braucht), dann kommt
sie auch später nicht mit in das ELF...

Ich hätte ja schon längst ein Beispiel gebracht, aber dazu fehlt mir
grad die Zeit...

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast wohl nicht ganz verstanden, wie der Linker arbeitet.

    "All diese Funktionen müsste ich in einzelnen Files
    abspeichern ..."

Ja, es ist korrekt, daß jede einzelne Funktion in ein eigenes Source-
und also Objektfile gehört.

Diese werden vom Librarymanager zu einer Library verwurschtelt.

   "und der Programmierer müsste manuell bestimmen
   welche der Funkitonen er in seinem Programm hat?"

Und nein, der Benutzer der Library muss sich nicht darum kümmern,
welche Objektdateien er aus der Library verwendet - das nämlich macht
der Linker. Der bestimmt zunächst alle nicht aufgelösten Symbole
(beispielsweise aufgerufene Funktionen, bei denen die Implementierung
fehlt) und durchsucht dann alle ihm übergebenen Objektdateien und
Libraries nach diesen. Wird so ein Symbol in einer Library gefunden,
wird die dieses enthaltene Objektdatei aus der Library zum Projekt
dazugelinkt.

Fertig. Funktioniert wunderbar, ist komfortabel und effizient und seit
Jahrzehnten so erprobt.

Es gibt allerdings Linker, die -aufgrund eines deutlich komplexeren
Objektdateiformates- in der Lage sind, auf Funktionsebene zu linken,
das heißt, aus einer Objektdatei nur die verwendeten Teile zu
extrahieren. Ein frühes Beispiel dafür war der in Borlands Turbo Pascal
integrierte Linker.

Natürlich zwingt Dich niemand dazu, auch wirklich alle Funktionen
Deiner Library in eigenständigen Source- und also Objektdateien zu
organisieren; das bleibt frei Deiner Lust und Laune überlassen. Gutes
Librarydesign sieht so eine Arbeitsweise aber vor.
Ich sehe auch überhaupt kein Problem darin; es erfordert vom
Libraryentwickler nur ein kleines bisschen Selbstdisziplin (sinnvolle
Namensvergabe von Source- und Headerfiles, etwas Nachdenken über
#include-Strategien), ist danach aber so selbstverständlich wie das
Atmen.

Selbst wenn nicht eine Library entwickelt wird, lohnt es sich, mit
modularen Codeblöcken zu arbeiten. Das steigert unter anderem die
Chancen der -Achtung, jetzt kommt ein "buzzword"- Code-Reuse.
Beim Arbeiten im Editor ist ein 100 Zeilen langes Sourcefile mit
ausschlaggebenden Namen auch übersichtlicher als ein 4000 Zeilen langes
...

Autor: OldBug (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
...und jetzt hab ichs doch gemacht...

Siehe Anhang, entpacken mit 'tar -xvjf linkertest.tar.bz2' im
Verzeichnis Deines Vertrauens.

Lib erstellen mit:

 * avr-gcc -c -Os -ggdb -o foo.o foo.c
 * avr-gcc -c -Os -ggdb -o bar.o bar.c
 * avr-ar -qcs libfoobar.a foo.o bar.o

Inhalte anzeigen:

 * avr-nm -s libfoobar.a

...für alle Die das mal nachvollziehen wollen.

Dann noch 'make clean all' und ins .map-File schauen und nach
'foo.o', welches enthalten ist, und 'bar.o' welches nicht enthalten
ist, suchen!

Viel Spaß!

Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, wunderbar, danke für die Erklärung.
Leider ist das ganze für mich noch nicht ganz so selbstverständlich wie
das Atmen, aber ich würde gerne wissen wie das geht. Gibts es das
irgendwo nachzulesen? Ich hab zwar diverse Bücher, meist aber mehr zu
C++ und alles für den PC und zu dem Thema schweigen sich alle aus.
Vielleicht kann sich ja jemand erbarmen und das Thema hier in dem
großen Tutorial anzugehen (wenn's nicht schon drinsteht und ich dösel
das blos noch nicht gesehen hab).
Die Sprache C ist für mich das kleinere Problem, hab ich auch früher
schon programmiert. Allerdings noch zu Borland C 3.1 Zeiten unter DOS.
Da hab ich mich um sowas nicht gekümmert. Viel schwieriger ist für mich
das ganze "Drumrum" wie makefiles und Linker usw

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, naja, vielleicht liest Du mal die Beiträge?

>Dateianhang: linkertest.tar.bz2 (12.4kB, 0 Downloads)

Das war doch jetzt nicht wirklich für die Katz', oder?

 :-)

Autor: R2D2 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
GCC kann mittlerweile selber entscheiden welche Funktionen verwendet
werden und welche nicht.
CPFLAGS += -ffunction-sections
LDFLAGS += -ffunction-sections -Wl,--gc-sections
-Wl,-uInterruptVectors
ich hoff das war alles was nötig is. Wenn nicht schau ich nochmal nach.
Funktioniert zumindest beim MSP430 problemlos.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Selbst wenn das mit WinAVR geht, dann muss freilich die Library so
übersetzt werden, nicht bloss das eigene Programm.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Außerdem muss man sich dann wieder mit Krücken wie dem genannten
-Wl,-uInterruptVectors behelfen, um all die Symbole, die drin
bleiben sollen, zu benennen.  Auf jeden Fall heißen die
Interruptvektoren bei avr-libc erst einmal anders, außerdem braucht
man ähnliche Krücken, um eigene init-Funktionen (in .init3 oder
so) nicht rauskicken zu lassen.

Ich finde die Methode insgesamt alles andere als elegant.  Sie
fördert meines Erachtens lediglich die Faulheit des Programmierers,
sich um seine Codestruktur noch weniger Gedanken zu machen.  Mögen
Compiler und Linker dann das Chaos doch richten...

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg:
Vielleicht hast Du damit ja gerade den Stein der Erkenntnis gefunden,
warum Programme von Microsoft oft so ... sind, wie sie sind.

Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hm, naja, vielleicht liest Du mal die Beiträge?
Den hast du grad gepostet als ich selbst geschrieben hab. Hab ich erst
hinterher gesehen. Eine Beschreibung im Wiki wäre trotzdem nicht
schlecht, wäre dann etwas langlebiger und nützlich für die
Allgemeinheit.
Aber ich werd mir das Beispiel heute oder morgen mal vornehmen

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...Bitteschön, ersten Absatz beachten ;)

  http://www.mikrocontroller.net/articles/Libraries

Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super, klasse. Das ist endlich mal was womit man was anfangen kann!!!
Ich danke recht herzlich

Schönes Wochenende
JarJar

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.