2013-07-12 10 views
5

utilizzando C++ottenere a tempo di compilazione di data e ora, senza macro

posso compilare il mio codice su un programma automatizzato e la necessità di utilizzare il tempo in cui il codice è stato compilato nel codice stesso. Attualmente sto solo usando i macro __DATE__, __TIME__ per ottenere la data e l'ora della compilazione. Tuttavia, questo fa sì che i binari cambino anche se non sono state apportate modifiche all'origine (le macro si gonfiano al momento della compilazione) che non è buono (non voglio che l'installazione pensi che il file binario sia cambiato se non ci sono state modifiche alla fonte).

È possibile ottenere il tempo di compilazione senza utilizzare alcun mezzo che causerebbe la modifica della sorgente?

Grazie

+0

Oltre a salvarlo in un file aggiuntivo che non fa parte della build, non penso sia possibile ... – Nbr44

+2

In tal caso, potresti voler costruire il tuo sistema di compilazione solo se ci sono delle modifiche. Ricompilare per motivi di ricompilazione quando non ci sono modifiche a nessuna fonte non ha molto senso. –

+2

(Nota: è necessario modificare il post e aggiungere i backtick attorno ai nomi delle macro: "' ... il \ '__DATE __ \', \ '__TIME __ \' macros ... '", perché attualmente appaiono in grassetto e senza i caratteri di sottolineatura) –

risposta

3

Lo standard __DATE__ e __TIME__ macro fanno ciò che si osserva, restituire una stringa dipendente dal tempo.

Dipende dal sistema (e forse dal compilatore) e in particolare dal sistema di generazione (ad esempio GNU make per esempio).

Una possibile idea potrebbe essere quella di collegare in un file timestamp separato, qualcosa di simile (in make sintassi)

timestamp.c: 
     date +'const char timestamp[]="%c";' > [email protected] 

program: $(OBJECTS) timestamp.c 
     $(LINKER.cc) $^ -o [email protected] $(LIBES) 
     rm -f timestamp.c 

Il timestamp.o sarebbe poi essere rigenerato e la tua program sarebbe ricollegato ad ogni make (in modo che il generato il programma cambierà davvero, ma la maggior parte del codice - con $(OBJECTS) rende variabile - rimarrà invariata).


In alternativa, è possibile ad es. accedere all'interno di alcuni database o file di log testuali al momento del collegamento, ad es.

program: $(OBJECTS) 
     $(LINKER.cc) $^ -o [email protected] $(LIBES) 
     date +'[email protected] built at %c' >> /var/log/build.log 

(si potrebbe utilizzare logger invece di date per ottenere che registrato nel syslog)

Poi il generato program non cambierà, ma avrete effettuato l'accesso da qualche parte un timestamp build. A proposito, è possibile registrare anche alcuni checksum (ad esempio $(shell md5sum program) nella sintassi make) del programma binario.

+0

Hmm, questo non farebbe ancora cambiare il file binario risultante da una build all'altra? Poiché anche il file timestamp.c cambierà e il file timestamp.0 verrà collegato al binario? –

+0

Ho bisogno di fare in modo che i binari finali non cambino a meno che non ci sia stato un effettivo cambiamento nella fonte. –

+0

@ user1322488 Prendi il suo primo frammento di makefile, ma poi modifica la riga timestamp.c aggiungendo una dipendenza. per esempio. 'timestamp.c: $ (OBJECTS)' Questo renderà rigenerare timestamp.c solo quando è più vecchio di qualsiasi oggetto. –

0

Se si utilizza il tempo di compilazione NEI binari, si avrà il cambio binario.

Ci sono diverse soluzioni, ma penso che il punto principale sia che se si ricostruiscono i binari su base regolare, questo dovrebbe essere fatto solo se ci sono effettivamente alcune modifiche (sia al sistema di compilazione che al codice sorgente). Quindi fai parte del tuo sistema di compilazione per verificare se ci sono cambiamenti, e non costruire nulla se non ci sono cambiamenti. Un modo semplice per farlo è quello di verificare quale sia la "versione più recente" nel sistema di controllo della versione per il codice sorgente. Se la versione più recente è uguale a quella utilizzata nella build precedente, non è necessario creare nulla. Questo ti farà risparmiare generando build identici (a parte il timestamp di costruzione) e risolverà il problema di storgin __DATE__ e __TIME__ nel file binario.

0

Non mi è chiaro cosa vuoi.Se si tratta dell'ora modificata del file , il suo caricamento dipenderà dal sistema e dal sistema di build : qualcosa come -D $(shell ls -l --time-style=long-iso $< | awk '{ print $7, $8 }') potrebbe essere utilizzato nell'invocazione del compilatore con GNU make sotto Linux, per esempio . Ma, naturalmente, significa che se un file di inclusione è stato modificato , ma non la fonte, l'ora e la data non riflettono lo stesso .