2014-06-18 164 views
14

我想使用cmake將VERSION設置爲發佈版本以防發佈版本,否則將其設置爲編譯時。使用cmake編譯日期和時間

當使用使發展構建,獲得編譯時通過

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

這可以通過C/C++源碼直線前進使用很容易。不幸的是,我還沒有發現如何使用cmake實現相同。

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

將VERSION設置爲cmake執行時間。在使用cmake時如何將VERSION設置爲編譯時(避免在沒有RELEASE標誌的情況下需要撥動__DATE____TIME__)?

+0

[這是一個有用的答案](http ://stackoverflow.com/questions/13419255/how-to-get-cmake-to-create-timestamp-file-after-an-actual-build-link-do-nothin)爲您的問題。您需要確保在主機構建環境中可以使用'date'等命令。使用'__DATE__'和'__TIME__'宏的通用解決方案也很容易,只需提供一個包含必要定義的頭文件,該文件在每個版本上生成(或至少被觸及)(作爲預生成操作) –

+2

說起來,一個版本號的目的是能夠*重現一個二進制文件用*編譯的確切源文件。因此,使用*彙編*的時間戳是一個非常非常糟糕的選擇。分配和維護正確的版本號,或者如果您不想這麼做,請使用版本控制軟件(SVN的分支/修訂版,GIT的哈希碼)中的某些內容。只是不使用編譯時間戳,它甚至比根本沒有版本更糟糕,因爲你可能有一個較新的源代碼編譯,這會讓包括你自己在內的每個人都感到困惑。 – DevSolar

回答

3

我第一次運行CMake的跨平臺解決方案在二進制目錄中創建timestamp.cmake文件,並定義運行生成文件的目標文件timestamp。文件timestamp.cmake使用STRING CMake命令形成一個ISO 8601時間戳字符串,並將其寫入文件timestamp.h,其中#define _TIMEZ_預處理程序指令(用一個前導下劃線定義;沒有定義,兩個前導下劃線定義不應由用戶定義)。

在您的主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) 

然後使用ADD_DEPENDENCIES CMake的命令,讓您的主要目標(可能是主要的可執行文件)依賴於timestamp目標。 CMake始終認爲它已經過時,所以每次主要目標重建時都會刷新它,根據要求刷新構建時間。

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

如果需要,可以使用此命令指定由空格分隔的多個附加依賴項。

然後,你可以#include "timestamp.h"(假設CMake的二進制dir是在包括路徑,這通常是如果沒有,那很簡單:INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR})),並使用_TIMEZ_每當你想有編譯時間戳ISO 8601格式(或者,實際上,無論你喜歡:你可以自己指定,see CMake documentation for STRING command usage)。

這可以通過直接(手工)創建文件timestamp.cmake並將其添加到您的代碼庫中來簡化,但我認爲它不夠乾淨。這是CMake的一個普遍缺點,你不能訪問CMake後端的時間戳字符串形成過程(在STRING CMake命令中使用的那個過程),不管它是什麼(例如,GNU make),所以必須使用單獨的CMake文件並在該階段調用它。如果您可以在「CMake命令模式」(cmake -E類型的調用)中調用CMake時間戳字符串形成過程,可以做得更簡單更乾淨,例如,如下所示:cmake -E date [format] [UTC],但可惜。我有filed a ticket in the CMake's Mantis bug tracker

您可以通過支持我的功能請求發佈一些評論來顯示您對此有多大的需求,從而幫助您實現這一目標。

+1

用前導下劃線*定義,然後*大寫字母實際上是不正確的。 (並不是說這太重要了。) – Praxeolitic

1

也許你可以在代碼中使用編譯器宏__DATE____TIME__而不是從cmake獲取它。值得一提的是,你將需要做清潔/使更新這些值(因爲GCC嵌入它,如果對象已編譯它不會再次編譯,所以沒有日期/時間變化)