Es scheint ein Problem mit Wrapperfunktionen und der LTO zu geben: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88643 Kennt hier jemand einen Workaround? Mit Bugzilla kenne ich mit nicht aus, wann könnte sowas gefixt werden? Der Fehler ist für 9.0 gemeldet, aktuell gibt es 9.2.1, da sehe ich das Problem immer noch.
Johannes S. schrieb: > Kennt hier jemand einen Workaround? Steht doch da drin : nimm clang. Damit gehts. Oliver
der Compiler ist vorgegeben und nicht so einfach auszutauschen (Mbed), da stehen Aufwand und Nutzen in keinem guten Verhältnis.
Genau wegen solchen Problemen verwende ich generell kein LTO. In manchen Situationen könnte man ansonsten das weak attribut verwenden. foo.h:
1 | int cook(void); |
bar.c:
1 | #include "foo.h" |
2 | __attribute__((weak)) int cook(void){ return -1; } |
foo.c:
1 | #include "foo.h" |
2 | // Strong symbol, überschreibt das weak symbol cook
|
3 | int cook(void){ return 0; } |
main.c:
1 | #include "foo.h" |
2 | int main(){ |
3 | if (cook () == -1) |
4 | __builtin_abort (); |
5 | }
|
Johannes S. schrieb: > der Compiler ist vorgegeben und nicht so einfach auszutauschen (Mbed), > da stehen Aufwand und Nutzen in keinem guten Verhältnis. Je nun, wer hat denn dann gcc 9 für euer Projekt freigegeben? Wobei gcc 8.3.1 das Problem auch schon hat. Oliver
das ist nicht mein Project, Mbed ist ARM. Die unterstüzen schon drei toolchains: ARMCC, GCC und IAR. Als OS geht das sehr in die Tiefe und schon für die drei Compiler sind viele Fallunterscheidungen nötig. LTO funktioniert da schon, nur mit den neuen wrappern nicht zusammen. An anderen Stellen wurden da schon Workarounds gebaut, für das printf/vsnprintf hat das aber noch nicht geklappt. Auch mit WEAK gibts die gleiche Mecker. https://github.com/ARMmbed/mbed-os/issues/12542 Mbed5 ist massig gewachsen, mit bare-metal und LTO passt es jetzt wieder in kleine Controller. Dazu gibt es jetzt noch ein skalierbares printf, nur alles zusammen geht (noch) nicht.
Johannes S. schrieb: > Auch mit WEAK gibts die gleiche Mecker. Bei mir hat's funktioniert, aber mit dem älteren gcc 5.4.0 (der wrap bug war bei dem auch da). Hast du es mit dem Beispielcode oben probiert?
Ansonsten, eventuell kannst du es mit einem Macro ersetzen?
1 | void foo_a(int x); |
2 | void foo_b(int x); |
3 | |
4 | #ifndef ALT_FOO
|
5 | #define foo(...) foo_a(__VA_ARGS__)
|
6 | #else
|
7 | #define foo(...) foo_ ## ALT_FOO(__VA_ARGS__)
|
8 | #endif
|
1 | gcc -DALT_FOO=b |
sieht irgendwie kompliziert aus, es soll ja eine Funktion aus der c-lib überschrieben werden. Die ist nicht weak definiert und nachträglich geht das auch nicht, dafür wird ja das __wrap_printf anstelle von printf gelinkt. z.B: https://github.com/ARMmbed/mbed-os/blob/c2c6d251fd6d6d7f5f8d5a920b3ad6ce4df0f8ba/platform/source/minimal-printf/mbed_printf_wrapper.c#L33-L41
Johannes S. schrieb: > es soll ja eine Funktion aus der c-lib > überschrieben werden. Ach so. Eventuell kann man da mit der #include_next extension was machen: stdio.h
1 | #ifndef MYSTDIO_H
|
2 | #define MYSTDIO_H
|
3 | |
4 | #define printf(...) my_printf(__VA_ARGS__)
|
5 | #define puts(...) my_puts(__VA_ARGS__)
|
6 | // ...
|
7 | |
8 | #include_next "stdio.h"
|
9 | |
10 | #endif
|
Wenn man den include path so einrichtet, dass die eigene stdio.h zuerst gefunden wird, müsste das dann eigentlich alles auf die eigene umleiten. Es sei denn, diese sind bereits macros, dann müsste man die dann nach dem #include_next undefinen.
DPA schrieb: > Ach so. Eventuell kann man da mit der #include_next extension was > machen: Danke für deine Ideen und Tipps. Mit der include Reihenfolge wird es auch schwierig, die wird vom Buildsystem zusammengesucht. Könnte man beeinflussen, ist aber sehr aufwändig. Das printf und die Varianten werden ja auch von anderen units benutzt, das ist das grössere Problem. Durch die Wrapper beim Linken erwischt man automatisch alle units die diese Funktionen benutzen und lenkt alle auf die wrapper um. Wenn in dem ganzen Programm auch nur einer die org stdio benutzt hätte man den Code beider Funktionen und genau das will man mit der Option ja nicht. Der ARMC6 benutzt clang, mal sehen ob ich das damit testen kann. Den habe ich aber nur in der Form vom MbedStudio, und da ist vieles fix vorkonfiguriert und der lässt sich nicht aus der cmd starten. Beim gcc gibt es die Linkeroption -fuse-ld=lld um clang als Linker zu benutzen, das hat auch nicht geklappt. Clang habe ich installiert und im Suchpfad, lld kann ich starten. Braucht man da eine Crosscompiler Version für ARM? Dann habe ich noch die -u Option zum 'undefine Symbol' probiert. So wird z.B. auch main undefined und so der Linker gezwungen die zu suchen. Klappt mit -u printf aber auch nicht. Wenn es nicht geht dann auf den nächsten gcc warten :) Das LTO scheint sehr komplex zu sein, da hatte ich vorher auch schon viel mit rumprobiert und viele Fehler bekommen. Edit: mit -u klappt es doch, es wurde __wrap_vsnprintf angemeckert und ich hatte die falsche Funktion angegeben. Irgendwann sollte man Pause machen... Mit "-u main -u printf -u vsnprintf" linkt es, jetzt müsste ich mal die Codegrössen vergleichen. ok, es compiliert, aber der Code mit -lto ist grösser, das printf ist da noch aus lib_a_nano drin. Also vertragen sich wrap und lto nicht wirklich.
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.