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
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.
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
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.
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
>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
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
Ä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
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.
Man kann toten Code vom Compiler entfernen lassen: --combine -fwhole-program Peter
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
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' :-)
> 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? ;-)
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
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
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
> 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.
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
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!
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.