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:
1 | LDFLAGS = -T"STM32F407VGTx_FLASH.ld" -Xlinker --gc-sections --specs=nano.specs -Wl,-Map=$(MAP)
|
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:
1 | LDFLAGS = -T"STM32F407VGTx_FLASH.ld"
|
2 | LDFLAGS += --gc-sections
|
3 | LDFLAGS += -Map=$(MAP)
|
4 | LDFLAGS += -L"/usr/arm-none-eabi/lib/armv7e-m/fpu"
|
5 | LDFLAGS += -L"/usr/lib/gcc/arm-none-eabi/7.3.0/armv7e-m/fpu"
|
6 | LDFLAGS += /usr/lib/gcc/arm-none-eabi/7.3.0/armv7e-m/fpu/crti.o
|
7 | LDFLAGS += /usr/lib/gcc/arm-none-eabi/7.3.0/armv7e-m/fpu/crtn.o
|
8 | LDLIBS += --start-group -lgcc -lc_nano -lm -lstdc++_nano --end-group
|
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: plugin needed to handle lto object
|
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?