mikrocontroller.net

Forum: Compiler & IDEs einbinden von __DATE__ __TIME__ in ein binary


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: H. R. (hacker_r)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
ich wurde gerne compile time und date in mein binary drin haben.

Dazu habe ich ein extra file: compile_time_date.c wo steht:

static const char  compileDate[12] = _DATE_;
static const char  compileTime[12] = _TIME_;

Nun wurde ich gerne den Compiler dazu bringen diese Datei jedes Mal neu 
zu compilieren, dass tut es aber nicht. Weil compile_time_date.c sich ja 
nicht geändert hat, auch wenn die Zeit sich geändert hat.

Gibt es da ein weg?
Danke

Autor: Teo D. (teoderix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: H. R. (hacker_r)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein clean ist in meine Anwendung keine option. Compile time = 2h.

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
H. R. schrieb:
> Gibt es da ein weg?

Mehrere.

Erstens kannst du natürlich deinem make sagen, dass das Target 
compile_time_date.o nicht nur von compile_time_date.c abhängt, sondern 
auch von einem fiktiven ("phony") target, welches stets zuvor gebaut 
werden muss.
all: foo.o

foo.o: foo.c dummy
        cc -O -c foo.c

dummy: 

.PHONY: dummy

Zweitens könntest du natürlich stattdessen auch die passenden Strings 
für Datum und Uhrzeit gleich irgendwie in der Shell ermitteln lassen und 
dann die zu compilierende Datei jedesmal neu bauen lassen. Hat den 
zusätzlichen Vorteil, dass du in der Wahl des Datums- und Zeitformats 
völlig frei bist.
all: foo.o

foo.o: foo.c

foo.c: dummy
        echo 'static const char tstamp[] = "'$$(date +'%Y-%m-%dT%H%M%S')'";' > foo.c

dummy:

.PHONY: dummy

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
H. R. schrieb:
> ich wurde gerne compile time und date in mein binary drin haben.

Bei so etwas sollte man vorsichtig sein. Dadurch unterscheiden sich zu 
einem späteren Zeitpunkt gebaute Binaries, auch wenn sie funktional 
identisch sind. Besonders hinterhältig ist es, wenn ein Binary aus 
vielen einzelnen Dateien besteht (z.B. ein Embedded Linux oder Android 
Image), die alle einen eigenen Timestamp haben, der aber auch noch 
unterschiedlich ist (da nicht alle Dateien in der selben Sekunde 
kompiliert werden). Da die Build-Reihenfolge nicht fix ist, lässt sich 
selbst durch Modifizieren der Systemzeit ein Build-Image nicht 100% 
reproduzieren.

Jörg W. schrieb:
> Hat den
> zusätzlichen Vorteil, dass du in der Wahl des Datums- und Zeitformats
> völlig frei bist.

Da muss man aber genau aufpassen, dass der String immer gleich lang 
ist (bei _DATE_ zum Glück der Fall), denn sonst kann z.B. je nach 
Monats/Tag-Namen oder führenden Nullen das Datum eine andere Länge 
haben, wodurch dann die Länge des Binary variieren kann, was ein binäres 
Vergleichen (z.B. mit vbindiff) stark erschwert, auch weil sich dann 
alle Adressen ändern.

Ähnlich tückisch ist das Einbinden von git-Revisions-Hashes: Wenn eine 
Codebasis mehrere Dateien produziert (z.B. Module aus dem 
Linux-Source-Code), ändern sich durch Commits alle erzeugten Dateien, 
inkl. Modulen, obwohl der Inhalt ggf. sonst komplett identisch ist.

Genau diese Probleme hatte ich mal - ein Embedded-Linux-Image, dessen 
zugrundeliegender Sourcecode/Konfiguration nicht mehr exakt erhalten 
war. Mit viel Fummelei konnte ich dann die Konfiguration reverse 
engineeren, aber das Image war dank zahlreicher Timestamps trotzdem 
unterschiedlich. Ich musste die Datums-Strings hartkodieren um 
feststellen zu können, ob ich jetzt die Konfiguration vollständig 
korrekt hatte...

Wenn also ein Datum gebraucht wird, sollte man dies wirklich nur an 
genau eine Stelle des Image packen. Dann kann man auch mehrere Binaries 
vergleichen und relativ leicht einen alten Build reproduzieren.

H. R. schrieb:
> Compile time = 2h.

Klingt nach einem kompletten Linux-System - dann vielleicht die 
Datums-Erzeugung in das Tool integrieren, welches das System-Image 
zusammenpackt (Partitionen+Bootloader). Man könnte das Datum vor den 
Bootloader packen o.ä.

Autor: Harry L. (mysth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein simples

touch <fname.c>

Bei dem anschließenden "make" wird nur diese eine C-Datei neu compiliert 
und anschließend das Projekt neu gelinkt.

: Bearbeitet durch User
Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> wodurch dann die Länge des Binary variieren kann, was ein binäres
> Vergleichen (z.B. mit vbindiff) stark erschwert

Naja, wenn man sowas vorhat, dann sollte man auf Kinkerlitzchen wie ein 
Compiledatum sinnvollerweise verzichten. Das bringt weniger Information 
als man zuerst glauben mag. Git revision könnte da schon mehr bringen.

Ansonsten bliebe der Weg, sich per Linkerscript darum zu kümmern, dass 
der so generierte String stets als allerletztes im Binary landet. Dann 
kann man den bindiff vom Anfang immer noch durchführen.

Übrigens gibt mein date-Kommando da oben den Timestamp im ISO8601-Format 
aus, sodass er wirklich immer gleich lang ist.

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Naja, wenn man sowas vorhat, dann sollte man auf Kinkerlitzchen wie ein
> Compiledatum sinnvollerweise verzichten.

Die Notwendigkeit für binäres Diff ergibt sich typischerweise nachdem 
man schon diverse Images erstellt hat; absichtlich Einplanen tut man das 
wohl kaum. Für den Fall dass es nötig werden könnte muss man sich aber 
vorher Gedanken machen.

Jörg W. schrieb:
> Ansonsten bliebe der Weg, sich per Linkerscript darum zu kümmern, dass
> der so generierte String stets als allerletztes im Binary landet. Dann
> kann man den bindiff vom Anfang immer noch durchführen.

Das geht auch, aber die genaue Position des Datums ist nicht so relevant 
wenn es immer gleich lang ist, und es auch nur genau eins davon gibt.

Idealerweise gibt es im Build-Prozess eine zentrale Stelle, an der das 
Build-Datum einmal erzeugt wird. Wenn man mehrere Timestamps hat, 
sollten die alle dieses Datum nehmen, welches dann auch überall gleich 
ist. Das kann man dann zu Testzwecken auch manuell auf ein (altes) Datum 
setzen. Leider unterstützt z.B. das Android-Build-System so etwas nicht; 
wenn man da 2x das gleiche Image kompilieren will, hat man riesige 
Unterschiede, weil an zig Stellen unterschiedliche Timestamps stehen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.