2014-06-18 21 views
14

Chcę użyć cmake, aby ustawić wersję VERSION na wersję wydania w przypadku kompilacji wydania i na czas kompilacji w przeciwnym razie.Skompiluj datę i godzinę przy użyciu cmake

Przy użyciu powodują rozwój buduje, uzyskując czas kompilacji było łatwo poprzez

-DVERSION=`date +%Y-%m-%d_%H:%M` 

, które mogą być wykorzystywane proste kodem C/C++ źródłowego. Niestety nie dowiedziałem się, jak można to osiągnąć, używając cmake.

string(TIMESTAMP VERSION "%Y-%m-%d %H:%M") 
add_definitions(-DVERSION="${VERSION}") 

ustawia WERSJĘ na czas wykonania polecenia cmake. Jak ustawić VERSION na czas kompilacji podczas używania cmake (aby uniknąć skrzypienia z __DATE__ i __TIME__ pod nieobecność flagi RELEASE)?

+0

[Oto przydatna odpowiedź] (http : //stackoverflow.com/questions/13419255/how-to-get-cmake-to-create-timestamp-file-after-an-actual-build-link-do-nothin) dla twojego problemu. Musisz upewnić się, że masz jakieś polecenie, takie jak "date" dostępne w środowisku kompilacji hosta. Ogólne rozwiązanie wykorzystujące makra "__DATE__" i "__TIME__" byłoby również łatwe, po prostu dostarczając plik nagłówkowy zawierający niezbędne definicje, które są generowane (lub przynajmniej dotykane) w każdej kompilacji (jako działanie pre-build). –

+2

Ogólnie mówiąc, celem numeru wersji jest umożliwienie * odtworzenia dokładnych plików źródłowych, z których zbudowano plik binarny *. W związku z tym użycie znacznika czasu * kompilacji * jest bardzo, bardzo złym wyborem. Przypisuj i zachowuj odpowiednie numery wersji lub jeśli nie możesz tego zrobić, użyj czegoś z oprogramowania do kontroli wersji (oddział/wersja dla SVN, kod Hash dla GIT). Po prostu nie używaj sygnatury czasowej kompilacji, jest nawet gorsza niż brak jakiejkolwiek wersji, ponieważ możesz mieć nowszą kompilację starszych źródeł, co może być mylące dla wszystkich, włącznie z Tobą. – DevSolar

Odpowiedz

3

Moje wieloplatformowe rozwiązanie przy pierwszym uruchomieniu CMake tworzy plik timestamp.cmake w katalogu binarnym i definiuje obiekt docelowy timestamp, który uruchamia wygenerowany plik. Plik timestamp.cmake tworzy ciąg znacznika czasu ISO 8601 przy użyciu polecenia CMake STRING i zapisuje je w pliku timestamp.h z przedłożoną wstępnie instrukcją preprocesora #define _TIMEZ_ (definiowane za pomocą jednego znaku podkreślenia wiodącego są prawidłowe, definicje z dwoma wiodącymi podkreśleniami nie powinny być definiowane przez użytkownika).

Dołącz następujące informacje do głównego pliku CMake.

# build time in UTC ISO 8601 
FILE (WRITE ${CMAKE_BINARY_DIR}/timestamp.cmake "STRING(TIMESTAMP TIMEZ UTC)\n") 
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(WRITE timestamp.h \"#ifndef TIMESTAMP_H\\n\")\n") 
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define TIMESTAMP_H\\n\\n\")\n") 
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define _TIMEZ_ \\\"\${TIMEZ}\\\"\\n\\n\")\n") 
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#endif // TIMESTAMP_H\\n\")\n") 
ADD_CUSTOM_TARGET (
    timestamp 
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/timestamp.cmake 
    ADD_DEPENDENCIES ${CMAKE_BINARY_DIR}/timestamp.cmake) 

Następnie użyj komendy ADD_DEPENDENCIES CUpewnij aby Twój główny cel (prawdopodobnie główny plik wykonywalny) zależny od celu timestamp. Jest zawsze uważany za nieaktualny przez CMake, więc jest odświeżany za każdym razem, gdy główny cel odbudowuje się, odświeżając czas kompilacji, zgodnie z żądaniem.

ADD_DEPENDENCIES (${CMAKE_BINARY_DIR}/${BINARY_NAME} timestamp) 

Można podać wiele dodatkowych zależności rozdzielonych przez białe spacje za pomocą tego polecenia, jeśli trzeba.

Następnie można po prostu #include "timestamp.h" (zakładając, że CUpewnij binarny dir jest w to ścieżka, która zazwyczaj jest, jeśli nie, to proste. INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR})) i używać _TIMEZ_ gdy chcesz mieć stempel czas budowy w ISO 8601 format (lub, w rzeczywistości, cokolwiek chcesz: możesz to określić samodzielnie, see CMake documentation for STRING command usage).

Mogło to być uproszczone bezpośrednio (ręcznie), tworząc plik timestamp.cmake i dodając go do repozytorium kodu, ale uważam, że nie jest wystarczająco czysty. Jest to ogólną wadą programu CMake, z którego nie można uzyskać dostępu do procedury formowania ciągów znaków czasowych (tej używanej w poleceniu CMake) na etapie, na którym znajduje się backend CMake'a, cokolwiek to jest (na przykład: GNU make), więc trzeba użyć osobny plik CMake i wywołaj go na tym etapie. Mogłoby to zostać zrobione o wiele prostsze i czystsze, gdyby można było wywołać procedurę formowania ciągu znacznika czasu CMake w "trybie komend CMake" (typ inwokacji typu cmake -E), na przykład: cmake -E date [format] [UTC], ale niestety. Mam filed a ticket in the CMake's Mantis bug tracker.

Możesz pomóc, aby tak się stało, wspierając moją prośbę o dodanie pewnych komentarzy pokazujących, jak bardzo tego potrzebujesz.

+1

Definiuje z wiodącym podkreśleniem *, a następnie * duża litera nie jest w porządku. (Nie to jest zbyt ważne.) – Praxeolitic

1

Może możesz użyć makr kompilatora __DATE__w swoim kodzie zamiast odbierać go z cmake. Warto nadmienić, że musisz dokonać czyszczenia/make, aby zaktualizować te wartości (ponieważ GCC je osadza, jeśli obiekt jest już skompilowany, nie będzie się on kompilować ponownie, więc nie ma zmiany daty/czasu)

Powiązane problemy