Einen schönen guten Abend
Ich entschuldige mich für den kryptischen Titel, jedoch quälen mich ein
paar Fragen rund um Make zu denen man so gut wie keine Infos im Netz
findet. Hintergrund ist, dass ich habe vor kurzem angefangen eigene
Makefiles zu erstellen um einerseits meine Builds besser unter Kontrolle
zu haben und andererseits um Clang als Compiler für ARM auszuprobieren.
Als Tools installiert ist bei mir aktuell:
- arm-none-eabi-gcc 7.3.0
- arm-none-eabi-newlib 3.0.0-1
- make 4.2.1.
1.) Anstatt arm-none-eabi-ld direkt aufzurufen wird ja gern gcc/g++
verwendet, dem man via -Xlinker oder -Wl auch Linker Flags mitgeben
kann. Aus Komfortgründen werden dann auch gerne Spec-Files übergeben,
die sich vor allem um so Dinge wie das Linken der notwendigen
Bibliotheken kümmern. Ein Teil des Makefiles könnte also etwa so
aussehen:
Leider kann ich das Spec-File "nano.specs" nicht entziffern. Laut Doku
(https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html) stehen in dem File
mehrere sogenannte "*[spec_name]:" Tokens. Welche von diesen Rules oder
wie man das nennt wird aber dann genutzt? (Datei im Anhang, falls es
sich wer direkt ansehen will)
2.) Um gcc/g++ aus dem Link-Prozess zu entfernen hab ich angefangen den
Linker direkt aufzurufen. Die entsprechenden Flags hab ich dabei
folgendermaßen gesetzt:
Das funktioniert prinzipiell einmal soweit ich sagen kann.
Interessanterweise ist das entstehende Binary aber 5kB kleiner als jenes
wenn ich gcc/g++ zum Linken nutze obwohl die Optimierungseinstellungen
sonst vollkommen ident waren. Ich werde mir morgen diesbezüglich noch
Map und Listing ansehen... aber irgendwas kommt mir hier komisch vor.
Erneut wäre es wohl einfacher wenn man wüsste, was "nano.specs" im
obrigen Linkvorgang wirklich tut.
3.) Sobald ich LTO aufdrehe funktioniert der direkte Aufruf des Linkers
nicht mehr, der Aufruf via gcc/g++ aber schon. Beim Linken via ld selbst
bekomm ich eine Fehlermeldung:
1
...
2
cfft_q15.c.o:pluginneededtohandleltoobject
Von jenem "plugin" hab ich schon einmal gehört, aber meines Wissens nach
sollte das mit meiner GCC und Linker Version schon lange obsolet sein.
Weiß jemand wie dieser Fehler sonst entstehen kann? Was geschieht in
Variante 1 dass LTO dort beim Linken nicht fehlschlägt?
4.) Verwendet man keinen eigenen Startup-Code, sondern jenen der
Toolchain, dann sind 4x Objektdatein von Interesse:
- crti.o
- crtn.o
- crtbegin.o
- crtend.o
Laut GCC Doku enthalten die letzten Beiden (begin/end) den .init und
.fini Array Teil für C++ Ctor/Dtor. Komischerweise kann ich ohne beide
Datein problemlos Linken und Klassen anlegen wie ich lustig bin. Wie
gibts das?
Vincent H. schrieb:
Alle Fragen kann ich dir auch nicht beantworten …
> 2.) Um gcc/g++ aus dem Link-Prozess zu entfernen
Warum zum Geier™ willst du den denn eigentlich entfernen?
gcc bzw. g++ sind die Compiler-Treiber, ein Frontend, welches einfach
für den jeweiligen Zweck die richtigen Tools mit den richtigen
Optionen aufruft *). Du compilierst doch auch nicht, indem du explizit
cpp, cc1 und as aufrufst, warum willst du dann unbedingt den Linker
manuell anwerfen?
*) OK, klappt beim ARM leider nicht so gut wie beim Compilieren eines
Programms direkt für den Host oder auch bspw. beim AVR-GCC. Da fehlt
ein wenig Koordination der diversen Rundrum-Dateien wie eben crt,
library, includes etc. Hätte wohl ARM als zentrale interessierte
Institution in die Hand nehmen müssen und beim GCC koordinieren, die
einzelnen Hersteller der diversen ARMs kümmern sich um sowas nicht, da
dort jeder nur seine IDE im Blick hat und dort dann den ganzen Salat
in die IDE stopft, statt den Compiler „rund“ zu machen.
> 3.) Sobald ich LTO aufdrehe funktioniert der direkte Aufruf des Linkers> nicht mehr, der Aufruf via gcc/g++ aber schon. Beim Linken via ld selbst> bekomm ich eine Fehlermeldung:
Völlisch logisch.
LTO braucht einen Compiler, denn es will Code erneut compilieren
können.
ps: Um nachzuvollziehen, was der Compilertreiber denn genau als
Backends aufruft und mit welchen Optionen, füge dem Aufruf einfach ein
„-v“ hinzu.
Wieso genau ich für meine Fragen jetzt ein negative Bewertung bekommen
hab versteh ich zwar nicht, aber ich hab einige Antworten die für den
ein oder anderen vielleicht interessant sein könnten.
Ad 1.)
Die Verbose Ausgabe von dem was passiert wenn man "nano.specs" dem
Linker übergibt ist wirklich grausam.
Damit sollte sich wirklich niemand auseinander setzen müssen.
Schrecklich.
Ad 2.)
Der Größenunterschied kam daher, weil ich aus versehen printf mit
Floating Point Unterstützung mitcompiliert hab. Ja, die kostet
tatsächlich 5kB...
Clang kommt mittlerweile übrigens auch mit Linker, nur leider findet man
wenn man Richtung "Clang Cortex M" googled zu viele alte Einträge in
denen eben noch manuell via dem GNU Linker gearbeitet wird. Kann nun
auch einwandfrei mit Clang compilieren.
Vincent H. schrieb:> Damit sollte sich wirklich niemand auseinander setzen müssen.> Schrecklich.
Vieles davon kommt aber auch von diesem nano-Kram. Ich mag den nicht
besonders und würde die nano-Bibliothek nur nutzen, wenn es platzmäßig
wirklich nicht anders geht.
> Kann nun> auch einwandfrei mit Clang compilieren.
Falls es dafür noch irgendwelcher besonderer Optionen bedarf, wäre es
natürlich nett, wenn du das hier im Thread noch mit vermerkst, damit
andere ggf. davon profitieren können, wenn sie das über eine
Suchmaschine
finden.
wenn bei 1MB flash noch die nano lib nötig ist und man sich kein fp bei
printf gönnenn kann muss das ja ein riesen Programm sein... Man sollte
auch Bedenken das es für die Sparsamkeit Einschränkungen gibt, zB ist
die nano lib nicht thread safe. Für einen Cortex-M0 benutze ich die
auch, aber der hat nur 16 kB flash.
Mit -lto stehe ich aber auch auf Kriegsfuss, wenn ich das aktiviere wird
der generierte Code oft grösser als ohne.
Johannes S. schrieb:> wenn bei 1MB flash noch die nano lib nötig ist und man sich kein fp bei> printf gönnenn kann muss das ja ein riesen Programm sein... Man sollte> auch Bedenken das es für die Sparsamkeit Einschränkungen gibt, zB ist> die nano lib nicht thread safe. Für einen Cortex-M0 benutze ich die> auch, aber der hat nur 16 kB flash.> Mit -lto stehe ich aber auch auf Kriegsfuss, wenn ich das aktiviere wird> der generierte Code oft grösser als ohne.
Der STM32F4 war nur ein Beispiel... Ich muss erstmal lernen vernünftig
mit Make umzugehn bevor ich mich da auf ein echtes Projekt einschießen
kann.
-flto ist für mich als C++ Template Süchtler ein Must-Have.
Bei Zeiten post ich eventuell mal das ganze Makefile und ein
Testprojekt. Vor allem was modernes C++ im Embedded Bereich angeht gibts
kaum Vergleiche zw. GCC und Clang.
Vincent H. schrieb:> Johannes S. schrieb:>> wenn bei 1MB flash noch die nano lib nötig ist und man sich kein fp bei>> printf gönnenn kann muss das ja ein riesen Programm sein... Man sollte>> auch Bedenken das es für die Sparsamkeit Einschränkungen gibt, zB ist>> die nano lib nicht thread safe. Für einen Cortex-M0 benutze ich die>> auch, aber der hat nur 16 kB flash.>> Mit -lto stehe ich aber auch auf Kriegsfuss, wenn ich das aktiviere wird>> der generierte Code oft grösser als ohne.>> Der STM32F4 war nur ein Beispiel... Ich muss erstmal lernen vernünftig> mit Make umzugehn bevor ich mich da auf ein echtes Projekt einschießen> kann.>> -flto ist für mich als C++ Template Süchtler ein Must-Have.
Warum? Schreib doch header-only, dann brauchst Du das doch gar nicht.
Vincent H. schrieb:> -flto ist für mich als C++ Template Süchtler ein Must-Have.
Dann würde ich aber an deiner Stelle in der Tat auf nanolib und
Gefummel mit nicht-FP-printf verzichten. Das Zeug macht's nicht
gerade übersichtlicher.