2013-07-12 18 views
5

użyciu C++coraz kompilacji datę i godzinę bez makr

skompilować mój kod na automatycznym harmonogramem i trzeba korzystać z czasu, w którym kod został skompilowany w samym kodzie. Obecnie używam tylko makr __DATE__, __TIME__, aby uzyskać datę i godzinę kompilacji. Jednak powoduje to zmianę plików binarnych, nawet jeśli nie wprowadzono żadnych zmian w źródle (makra będą nadmuchiwane w czasie kompilacji), co nie jest dobre (nie chcę, aby konfiguracja myślała, że ​​zmieniono kod binarny, jeśli nie było żadnych zmian do źródła).

Czy można uzyskać czas kompilacji bez użycia jakichkolwiek środków, które mogłyby spowodować zmianę źródła?

Dzięki

+0

Oprócz zapisania go w dodatkowym pliku, który nie jest częścią kompilacji, nie sądzę, że jest to możliwe ... – Nbr44

+2

W takim przypadku możesz chcieć, aby Twój system kompilacji był budowany tylko w przypadku jakichkolwiek zmian. Rekompilacja tylko dla dobra rekompilacji, gdy nie ma zmian w żadnym źródle, nie ma większego sensu. –

+2

(Uwaga: Powinieneś edytować swój post i dodawać kolejne odsyłacze do nazw makr: "' ... the \ '__DATE __ \', \ '__TIME __ \' macros ... '", ponieważ obecnie wyglądają pogrubione i bez podkreśleń) –

Odpowiedz

3

średnia __DATE__ i __TIME__ makr robić to, co można zaobserwować, zwrot zależny ciąg czasowy.

To zależy od systemu (i być może od kompilatora), a zwłaszcza od systemu kompilacji (na przykład GNU make).

Możliwym pomysłem mogłoby być ogniwem w oddzielnym pliku datownika, coś podobnego (w make składni)

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

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

timestamp.o byłyby następnie zregenerowany a program będzie relinked na każdym make (tak wygenerowany program rzeczywiście się zmieni, ale większość kodu - jako $(OBJECTS) make variable - pozostanie niezmieniona).


Alternatywnie możesz np. zaloguj się do pliku bazy danych lub pliku tekstowego w czasie połączenia, np.

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

(można użyć logger zamiast date aby ta zalogowany syslog)

Następnie generowany program nie zmieni, ale musisz zalogować gdzieś gromadzeniu znacznika czasu. BTW można zalogować również niektóre suma kontrolna (np. $(shell md5sum program) w make składni) swojego programu binarnego.

+0

Hmm, czy to nie spowodowałoby, że wynikowy plik binarny zmieni się z kompilacji na kompilację? Ponieważ plik timestamp.c również się zmieni, a plik timestamp.0 zostanie powiązany z plikiem binarnym? –

+0

Muszę sprawić, aby ostateczne pliki binarne nie uległy zmianie, chyba że nastąpiła rzeczywista zmiana źródła. –

+0

@ user1322488 Weź swój pierwszy fragment kodu Makefile, ale zmodyfikuj linię timestamp.c, dodając zależność. na przykład 'timestamp.c: $ (OBJECTS)' Spowoduje to, że tylko regeneruje timestamp.c gdy jest starszy niż którykolwiek z obiektów. –

0

Jeśli używasz czasu kompilacji W twoich plikach binarnych, to będziesz miał zmianę binarną.

Istnieje kilka rozwiązań, ale myślę, że najważniejsze jest to, że jeśli przebudujesz pliki binarne regularnie, powinno to być zrobione tylko wtedy, gdy faktycznie są jakieś zmiany (albo do systemu kompilacji, albo do kodu źródłowego). Zrób więc część systemu kompilacji, aby sprawdzić, czy są jakieś zmiany, i nie buduj niczego, jeśli nie ma żadnych zmian. Prostym sposobem na to jest sprawdzenie, jaka jest "najnowsza wersja" w systemie kontroli wersji dla kodu źródłowego. Jeśli najnowsza wersja jest taka sama jak w poprzedniej wersji, nic nie musi zostać zbudowane. Pozwoli to zaoszczędzić na generowaniu kompilacji, które są identyczne (poza znacznikiem czasu budowania) i rozwiąże problem binarnego storgin __DATE__ i .

0

Nie jest dla mnie jasne, czego chcesz.Jeśli jest to czas ostatniej modyfikacji pliku, jego pobranie będzie zależało od systemu i systemu budowania : coś podobnego do -D $(shell ls -l --time-style=long-iso $< | awk '{ print $7, $8 }') może być użyte w wywołaniu kompilacji z GNU make pod Linuksem, dla przykładu . Ale oczywiście oznacza to, że jeśli plik włączający został zmieniony , ale nie źródło, czas i data nie odzwierciedlałyby tego.

Powiązane problemy