Mahlzeit! Der gcc¹ kann ja --date-- und --time-- entsprechend der Environment Variable SOURCE_DATE_EPOCH setzen. So weit so gut, solange ein Programm aus den Quellen komplett neu gebaut wird. Mit Makefile und mehreren *.c funktioniert das nur zufällig, weil die Datei mit diesen Variablen selten geändert und übersetzt wird. Dann funktioniert auch die Empfehlung² nicht, eine RTC erstmalig zu stellen. Außerdem sieht man in dem Beitrag, wie mega umständlich das ist. Und evt. ist nicht klar, ob man UTC oder localtime bekommt. Mit CFLAGS += SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) entfällt der Umstand, man bekommt die UNIX-Sekunden direkt als Konstante. Aber trotzdem muss die entsprechende Quelldatei jedes Mal übersetzt werden. So geht's also auch nicht. Wie kann man so eine Konstante per Makefile dem Linker übergeben? Oder wie macht "man" das? 2) Beitrag "Re: Datum und Uhrzeit auf Mikrocontroller" 1) https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html
:
Bearbeitet durch User
Bauform B. schrieb: > Wie kann man so eine Konstante per Makefile dem Linker übergeben? Pack sie in ein C-Sourcefile, und sorge dafür, daß das bei jedem make-Aufruf neu übersetzt wird.
1 | version.o: version.c |
2 | |
3 | version.o: .FORCE |
4 | |
5 | .FORCE: |
(siehe https://stackoverflow.com/questions/7643838/how-to-force-make-to-always-rebuild-a-file)
Danke, das ist auch ein netter Trick. Aber für diesen Zweck ist das alles ein Krampf. Wenn SOURCE_DATE_EPOCH nicht definiert ist, setzt der gcc (vorschriftsmäßig) die aktuelle Uhrzeit ein, noch dazu die lokale. Dazu kommt der Umweg über mühsame Dekodierung von mühsam erzeugtem Text. Diese beiden Präprozessor-Konstanten sind für etwas anderes gedacht. Es ist toll, dass der gcc auch Leute unterstützt, die diese Konstanten brauchen. Aber eigentlich will man doch nur eine einzige Zahl. Mein Problem für heute war: -Wl,-defsym=SOURCE_DATE_EPOCH=$(UTC) benutze ich für die Cortex-M und früher ging es auch auf dem PC. AMD mit ihrem 64-Bit Befehlssatz ist schuld, dass auf dem PC per Default PIC erzeugt wird. Deshalb geht -defsym nicht mehr ganz so einfach. Jetzt schreibe ich sinngemäß:
1 | SDE := $(shell stat -L -c %Y $(PROJECT)/src/*/*.c | sort | tail -1) |
2 | -Wl,-defsym=S_D_E_BASE=0 \ |
3 | -Wl,-defsym=S_D_E=$(SDE) |
4 | |
5 | extern char S_D_E_BASE, S_D_E; |
6 | time_t source_date_epoch = (time_t)(&S_D_E - &S_D_E_BASE); |
OK, es gibt keinen Schönheitspreis, aber es ist doch völlig legal? Gibt es irgend welche Einwände?
Bauform B. schrieb: > Und evt. ist nicht klar, ob > man UTC oder localtime bekommt. Warum verwendest Du nicht date?
1 | date +%d.%m.%Y_%H:%M |
Und muß es der Linker sein? In solchen Fallen erstelle ich mir per Skript eine passende Quelltextdatei.
Rick schrieb: > Warum verwendest Du nicht date?date +%d.%m.%Y_%H:%M Wenn schon, dann date +%s. Dein Format muss ich ja auch wieder mühsam auseinander fieseln. Aber hier geht es eben nicht um die aktuelle Zeit, sondern um die Zeit der letzten Änderung der Quellen. Der entscheidende Unterschied: man kann das Programm später neu bauen und bekommt Bit für Bit das gleiche Binary. https://reproducible-builds.org > Und muß es der Linker sein? In solchen Fallen erstelle ich mir per > Skript eine passende Quelltextdatei. Ja, mit Haralds FORCE-Trick geht das auch. Aber auch in dem Fall würde ich nicht den Umweg über die offiziellen Macros gehen, sondern über ein define mit date +%s (in Wirklichkeit: stat -c %Y). Ja, time_t als Differenz von 2 Adressen zu übergeben, ist sicher überraschend. Aber die Lösung mit define und FORCE finde ich auch nicht elegant. Ich hatte mich so an -Wl,-defsym gewöhnt und nur wegen PIC geht das nicht mehr so einfach. Ich warte noch auf Alternativ-Vorschläge ;)
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.