Forum: Compiler & IDEs Bester Weg zur Einbindung von Bibliotheken


von Thomas B. (escamoteur)


Lesenswert?

Hi,

ich verwende AVR-GCC zusammen mit AVR-Studio.

Viele Bibliotheken liegen im Quellcode zusammen mit einem make-file vor. 
Ich bin absolut kein Freund von Make-Files sondern arbeite lieber mit 
einer IDE.

Was ist der beste weg um eine externe Bibliothek die über ein Makefile 
gebaut wird in ein Projekt in AVR-Studio einzubinden?

Viele Grüße
Tom

von Karl H. (kbuchegg)


Lesenswert?

Thomas Burkhart schrieb:
> Hi,
>
> ich verwende AVR-GCC zusammen mit AVR-Studio.
>
> Viele Bibliotheken liegen im Quellcode zusammen mit einem make-file vor.
> Ich bin absolut kein Freund von Make-Files sondern arbeite lieber mit
> einer IDE.
>
> Was ist der beste weg um eine externe Bibliothek die über ein Makefile
> gebaut wird in ein Projekt in AVR-Studio einzubinden?

Indem man dem AVR Studio sagt, dass man externes Makefile hat :-)

Im Ernst. Ich weiß gar nicht, ob AVR-Studio das erstellen von 
Object-Libraries unterstützt. Zudem sind Object-Libraries gerade in der 
AVR Programmierung gar nicht so nützlich, wie auf einem Desktop System.
Das Problem: Wenn man die Library so gestalten möchte, dass 
Pinbelegungen frei wählbar sind, dann bläht das den Code ganz schön auf.

Wohlgemerkt: Object-Libraries, also vorcompilierte Bibliotheken.

von Thomas B. (escamoteur)


Lesenswert?

Ok, schon klar.

D.h. entweder alle Queldateien dem AVR-Studio-Projekt zufügen oder 
komplett auf Makefiles?

Oder kann ich AVR-Studio irgendwie sagen, dass zum Projekt noch ein 
externes Make-File dazugehört?

Gruß
Tom

von Karl H. (kbuchegg)


Lesenswert?

Thomas Burkhart schrieb:

> Oder kann ich AVR-Studio irgendwie sagen, dass zum Projekt noch ein
> externes Make-File dazugehört?

entweder - oder

entweder AVR-Studio generiert sich selbst ein Makefile oder es benutzt 
das von dir angegebene.

von Thomas B. (escamoteur)


Lesenswert?

Ok, habs verstanden, werde also einfach alles Sourcen Gnadenlos ins 
Projekt hängen und dem Linker den Job überlassen sich das notwendige 
rauszusuchen ;-)

Gruß
Tom

von Oliver (Gast)


Lesenswert?

>Ok, habs verstanden, werde also einfach alles Sourcen Gnadenlos ins
>Projekt hängen und dem Linker den Job überlassen sich das notwendige
>rauszusuchen ;-)

Das ist die einzige Möglichkeit. Auf Sourcecode-Level muß jedes File ins 
Projekt, egal, ob mit direktem makefile, oder nicht.
Allerdings sucht sich der Linker nicht alles notwendige raus, sondern 
linkt gnadenlos alles zusammen, und beschwert sich hinterher, falls was 
fehlt, oder doppelt vorhanden ist.

Oliver

von Peter D. (peda)


Lesenswert?

Thomas Burkhart schrieb:
> Ok, habs verstanden, werde also einfach alles Sourcen Gnadenlos ins
> Projekt hängen und dem Linker den Job überlassen sich das notwendige
> rauszusuchen ;-)

Der Linker wird Dir was husten, er linkt alle C-Files einschließlich 
nicht aufgerufenem Code.

Was ist so schlimm daran, nur die benötigten Sourcen ins Projekt 
aufzunehmen?


Peter

von Thomas B. (escamoteur)


Lesenswert?

Ähm, eigentlich sollte ein Linker selectiv arbeiten und nur den Code 
einlinken, der irgendwo auch aufgerufen wird, sonst ist der ziemlich 
fürn Arsch.

Gruß
Tom

von Karl H. (kbuchegg)


Lesenswert?

Thomas Burkhart schrieb:
> Ähm, eigentlich sollte ein Linker selectiv arbeiten und nur den Code
> einlinken, der irgendwo auch aufgerufen wird, sonst ist der ziemlich
> fürn Arsch.

Der Linker vom gcc macht das so, dass er die Funktionen eines 
Object-Files entweder alle oder gar keines dazulinkt. Man kann also 
durch die Granulierung in einzelne Object Files schon ein wenig steuern, 
was wegfallen kann. Bei Libraries ist es daher auch nicht ungewöhnlich, 
dass jede Funktion in einem eigenen Object-File residiert oder zumindest 
nur die Funktionen in einem Source Code File zusammengefasst werden, die 
auch gewöhnlich mitsammen benutzt werden.

Bei C kann der Linker noch rausfinden, welche Funktionen tatsächlich 
gebraucht werden (Achtung: aufgerufen zu werden ist zu wenig!) und 
welche nicht. Aber du vergisst, dass der Linker ein Universallinker ist, 
der auch mit C++ klarkommen muss. Und dort geht das nicht mehr.

von Peter D. (peda)


Lesenswert?

Man kann toten Code vom Compiler entfernen lassen:

--combine -fwhole-program


Peter

von Thomas B. (escamoteur)


Lesenswert?

Karl heinz Buchegger schrieb:
> Bei C kann der Linker noch rausfinden, welche Funktionen tatsächlich
> gebraucht werden (Achtung: aufgerufen zu werden ist zu wenig!) und
> welche nicht. Aber du vergisst, dass der Linker ein Universallinker ist,
> der auch mit C++ klarkommen muss. Und dort geht das nicht mehr.

Wieso soll er dass bei C++ nicht mehr können? Schließlich ist C++ early 
und nicht late binding.


Allerdings kann er gar nicht rausfinden, ob eine bestimmte Funktion 
eventuell nie gebraucht wird, wenn Sie irgendwo aufgerufen wird. Für so 
was müsste er ja das Programm simulieren. Er kann sich also nur daran 
halten was irgenwo aufgerufen werden kann.

Außerdem sprachen wir in der wzischenzeit ja nicht von Bibliotheken als 
object-File sondern, dass ich alle Quellen in das Projekt nehme. Ein 
selektiver Linker sollte damit schon klar kommen, das ist bei 
Compilern/Linker eigentlich schon seit Jahren standard.

Gruß
Tom

von Karl H. (kbuchegg)


Lesenswert?

Thomas Burkhart schrieb:
> Karl heinz Buchegger schrieb:
>> Bei C kann der Linker noch rausfinden, welche Funktionen tatsächlich
>> gebraucht werden (Achtung: aufgerufen zu werden ist zu wenig!) und
>> welche nicht. Aber du vergisst, dass der Linker ein Universallinker ist,
>> der auch mit C++ klarkommen muss. Und dort geht das nicht mehr.
>
> Wieso soll er dass bei C++ nicht mehr können? Schließlich ist C++ early
> und nicht late binding.

Ich sag nur: virtuelle Funktionen

Da gibt es im ganzen Programm keinen einzigen Aufruf der Funktion oder 
irgendeine sonstige Referenz darauf und trotzdem wird sie aufgerufen. 
Das ist nämlich 'late Binding' :-)

von Rolf Magnus (Gast)


Lesenswert?

> Da gibt es im ganzen Programm keinen einzigen Aufruf der Funktion oder
> irgendeine sonstige Referenz darauf und trotzdem wird sie aufgerufen.

Naja, eine Referenz drauf gibt's schon, sonst könnten sie ja nicht 
aufgerufen werden. Aber ich muß dir doch bestimmt nichts über vtables 
erzählen, oder? ;-)

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus schrieb:
>> Da gibt es im ganzen Programm keinen einzigen Aufruf der Funktion oder
>> irgendeine sonstige Referenz darauf und trotzdem wird sie aufgerufen.
>
> Naja, eine Referenz drauf gibt's schon, sonst könnten sie ja nicht
> aufgerufen werden. Aber ich muß dir doch bestimmt nichts über vtables
> erzählen, oder? ;-)

LOL
Soll ich da jetzt wirklich kontern?
LOL

von Thomas B. (escamoteur)


Lesenswert?

Karl heinz Buchegger schrieb:
> Ich sag nur: virtuelle Funktionen
>
> Da gibt es im ganzen Programm keinen einzigen Aufruf der Funktion oder
> irgendeine sonstige Referenz darauf und trotzdem wird sie aufgerufen.
> Das ist nämlich 'late Binding' :-)

Sorry, aber das ist immer noch kein Late Binding ala Small Talk, der 
Complier weiß definitiv welche Funktionen an welcher Stelle aufgerufen 
werden können. Sobald irgendwo eine Instanz einer Klasse angelgegt wird, 
und das ist ja voraussetzung dass eine virtuelle Funktion aufgerufen 
werden kann, muss der Linker natürlich deren Methoden berücksichtigen.

Im übrigen gibt es auch in c funktionszeiger, das wäre das gleiche 
Problem.


Auf jeden Fall kann ein Linker schon ziemlich gut entscheiden was 
gebraucht wird und was nicht.

Gruß
Tom

von Peter D. (peda)


Lesenswert?

Thomas Burkhart schrieb:
> Ein
> selektiver Linker sollte damit schon klar kommen, das ist bei
> Compilern/Linker eigentlich schon seit Jahren standard.

sollte, könnte ...

Probiers doch einfach mal aus, dann wirst Du schon sehen all den schönen 
toten Code darin.
Was compiliert, wird auch gelinkt, basta.


Peter

von Rolf Magnus (Gast)


Lesenswert?

> LOL
> Soll ich da jetzt wirklich kontern?
> LOL

Nein, lass mal. Das Problem ist mir durchaus klar.

Thomas Burkhart schrieb:

> der  Complier weiß definitiv welche Funktionen an welcher Stelle
> aufgerufen werden können.

Nein, weiß er nicht, da er ja nicht einmal die Klasse kennen muß, in der 
die Funktion definiert ist. Das ist eigentlich immer so beim Aufruf 
einer Funktion per Zeiger. Letztendlich ist es eigentlich sogar der 
Grund, warum man überhaupt Funktionszeiger braucht.

> Sobald irgendwo eine Instanz einer Klasse angelgegt wird, und das ist
> ja voraussetzung dass eine virtuelle Funktion aufgerufen werden kann,
> muss der Linker natürlich deren Methoden berücksichtigen.

Der wiederum weiß aber nichts von Klassen, oder was es bedeutet, wenn 
eine solche instanziiert wird. Er kann das nicht erkennen.

> Im übrigen gibt es auch in c funktionszeiger, das wäre das gleiche
> Problem.

Ja. Da kann das darüber erkannt werden, daß eben die Adresse der 
Funktion irgendwo benutzt wird. Für den Linker ist die Funktion nur ein 
"Symbol", und wenn dessen Adresse irgendwo angefordert wird, bedeutet 
das für ihn, daß dieses Symbol benötigt wird. In C++ werden virtuelle 
Funktionen normalerweise mit vtables gemacht. Das ist aber eine Tabelle 
aus Zeigern auf alle virtuellen Funktionen der Klasse. Das bedeutet 
aber, daß schon für die Initialisierung der vtable die Adressen 
sämtlicher virtueller Funktionen benötigt werden und der Linker sie 
somit ins Programm aufnehmen muß, auch wenn sie eigentlich nie 
aufgerufen werden.

von Thomas B. (escamoteur)


Lesenswert?

Rolf Magnus schrieb:
> In C++ werden virtuelle
> Funktionen normalerweise mit vtables gemacht. Das ist aber eine Tabelle
> aus Zeigern auf alle virtuellen Funktionen der Klasse. Das bedeutet
> aber, daß schon für die Initialisierung der vtable die Adressen
> sämtlicher virtueller Funktionen benötigt werden und der Linker sie
> somit ins Programm aufnehmen muß, auch wenn sie eigentlich nie
> aufgerufen werden.

Schon klar, aber das heiß doch, dass zumindest Klassen die nirgends 
verwendet werden nicht im Code laden müssen.

Gruß
Tom

von gastgast (Gast)


Lesenswert?

da muss ich jetzt nochmal verständnishalber nachfragen:

wenn ich einen großen code habe und daraus dann ein mini projekt mache 
welches nur einen bruchteil der funktionen braucht dann muss ich damit 
der benötigte falsh speicher auch mit schrumpft alle nicht benötigten 
funktionen löschen sonst werden die mit rein gelinkt und sind quasi 
toter code im flash?

danke!

von Karl H. (kbuchegg)


Lesenswert?

So gehts:

Im AVR-Studio: Project / Configuration Options.

Im Dialog dann auf Custom Options

Für den Compiler:

  In der linken Liste "[All Files]" auswählen
  Die Option  -ffunction-sections  eintragen und mit "Add" hinzufügen
  Die Option  -fdata-sections  eintragen und mit "Add" hinzufügen


Für den Linker:

  In der linken Liste "[Linker Options]" auswählen
  Die Option  -static   eintragen und mit "Add" hinzufügen
  Die Option  -Wl,-gc-sections   eintragen und mit "Add" hinzufügen


Alles neu compilieren und linken (F7 drücken) und unbenutzte Funktionen 
sind verschwunden.

von Peter D. (peda)


Lesenswert?

Karl heinz Buchegger schrieb:
> So gehts:

Ich habs noch nicht probiert, aber ich gehe mal davon aus, das es geht.

Ich frag mich dann immer wieder, wie die Leute bloß auf diese geheimen 
Schalter kommen.
Wenn ich die GCC Manuals lese, habe ich fast sofort den Eindruck, die 
sind auf chinesisch geschrieben.
Das ist quasi identisch, als wenn man versucht, Gesetzestexte zu lesen, 
die versteht auch niemand, selbst nachdem man sie 100-mal gelesen hat. 
Man kennt alle Wörter, aber versteht einfach deren Sinn nicht.

Gibts vielleicht irgendwo nen Link, wo all die geheimen AVR-GCC-Schalter 
so erläutert sind, daß man sie auch verstehen kann?

Also nicht, der Schalter macht das und das, sondern, Du willst das 
erreichen, dann setze die Schalter u,v,w,x,y,z.
Viele Schalter funktionieren ja nur dann, wenn man sie zusammen setzt.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter Dannegger schrieb:

> Ich frag mich dann immer wieder, wie die Leute bloß auf diese geheimen
> Schalter kommen.

Ich habe danach gegoogelt und probiert :-)

> Also nicht, der Schalter macht das und das, sondern, Du willst das
> erreichen, dann setze die Schalter u,v,w,x,y,z.
> Viele Schalter funktionieren ja nur dann, wenn man sie zusammen setzt.

Ja, das hat mich auch schon geärgert.

Was mich aber mehr ärgert ist, dass man solche Sachen dem AVR Studio 
nicht vorgeben kann. Beim letzten Poll für das nächste Studio hab ich 
mir so etwas wie Projekt Templates gewünscht. Diese Switches bei jedem 
neuen Projekt erneut händisch eintragen, ist nicht wirklich produktiv. 
Mal sehen ob daraus etwas wird.

Denn in einem muss ich allen Postern schon recht geben: Eigentlich hätte 
ich dieses Verhalten als Default erwartet.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.