Cmakeを使用して、リリースビルドの場合はVERSIONをリリースバージョンに設定し、それ以外の場合はコンパイル時間に設定します。
Makeを開発ビルドに使用する場合、コンパイル時間の取得は簡単でした。
-DVERSION=`date +%Y-%m-%d_%H:%M`
これは、c/c ++ソースコードで直接使用できます。残念ながら、私はcmakeを使用して同じことがどのように達成できるかを知りませんでした。
string(TIMESTAMP VERSION "%Y-%m-%d %H:%M")
add_definitions(-DVERSION="${VERSION}")
cmakeが実行された時刻にVERSIONを設定します。 cmakeを使用するときに、VERSIONをコンパイル時間に設定するにはどうすればよいですか(RELEASEフラグがない場合に__DATE__
と__TIME__
をいじる必要がないようにするため)。
CMakeの比較的最近のバージョン(> = 2.8.11)の場合:
string(TIMESTAMP {output variable} [{format string}] [UTC])
( http://www.cmake.org/cmake/help/v3.0/command/string.html を参照してください)。例えば:
string(TIMESTAMP TODAY "%Y%m%d")
CMakeの最初の実行時の私のクロスプラットフォームソリューションは、バイナリディレクトリにファイル_timestamp.cmake
_を作成し、生成されたファイルを実行するターゲットtimestamp
を定義します。ファイル_timestamp.cmake
_は、STRING
CMakeコマンドを使用してISO 8601タイムスタンプ文字列を形成し、_timestamp.h
_プリプロセッサディレクティブを前に付けてファイル_#define _TIMEZ_
_に書き込みます(1つのアンダースコアで定義して問題ありません;定義2つの先行アンダースコアはユーザー定義ではありません)。
メインの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形式のビルドタイムスタンプが必要です(または、実際には、好きなように指定できます STRING
コマンドの使用法については、CMakeのドキュメントを参照してください )。
_timestamp.cmake
_ファイルを直接(手動で)作成してコードリポジトリに追加することで、これを簡単にすることができますが、十分にクリーンではないと考えました。 CMakeの一般的な欠点は、CMakeのバックエンドがある段階で、タイムスタンプ文字列形成手順(STRING
CMakeコマンドで使用される手順)にアクセスできないことです(たとえば、GNU make)が実行されるので、別のCMakeファイルを使用してその段階で呼び出す必要があります。これは、「CMakeコマンドモード」でCMakeタイムスタンプ文字列形成プロシージャを呼び出すことができれば、はるかに簡単でクリーンになります(_cmake -E
_呼び出しのタイプ)たとえば、次のようになります:_cmake -E date [format] [UTC]
_ですが、悲しいかな CMakeのMantisバグトラッカーにチケットを提出しました 。
あなたはそれがどれだけ必要かを示すいくつかのコメントを投稿する私の機能要求をサポートすることによってそれが起こるのを助けることができます。
コンパイラマクロ__DATE__
__TIME__
cmakeから取得するのではなく、コード内で。これらの値を更新するにはクリーンアップ/メイクを行う必要があることを言及する価値があります(GCCが埋め込んでいるため、オブジェクトが既にコンパイルされている場合、再度コンパイルされないため、日付/時刻は変更されません)。
私は次の解決策に終わります:
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
add_custom_target(
"linktimestamp"
ALL
COMMAND date +'%Y-%m-%d %H:%M:%S' > "linktimestamp.txt"
COMMAND objcopy --input binary --output elf64-x86-64 --binary-architecture i386:x86-64 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA "linktimestamp.txt" "linktimestamp.o"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "link timestamp: ${LINK_TIMESTAMP}"
)
else()
add_custom_target(
"linktimestamp"
ALL
COMMAND date +'%Y-%m-%d %H:%M:%S' > "linktimestamp.txt"
COMMAND objcopy --input binary --output elf32-i386 --binary-architecture i386 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA "linktimestamp.txt" "linktimestamp.o"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "link timestamp: ${LINK_TIMESTAMP}"
)
endif()
#add_dependencies(${PROJECT_NAME} "linktimestamp")
target_link_libraries(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/linktimestamp.o")
バイナリターゲット${PROJECT_NAME}
更新されたセクションと毎回リンクされます。
Qtこのタイムスタンプを取得するコード:
extern char _binary_linktimestamp_txt_start[];
//extern char _binary_linktimestamp_txt_end[];
extern char _binary_linktimestamp_txt_size[];
const auto text = QByteArray::fromRawData(_binary_linktimestamp_txt_start, reinterpret_cast< std::intptr_t >(_binary_linktimestamp_txt_size));
qDebug() << QDateTime::fromString(QString::fromUtf8(text), "yyyy-MM-dd HH:mm:ss\n"));
私はしばらく前に同じ問題にぶつかり、解決策として this repo と書きました。それをCMakeサブディレクトリとして追加するだけで、build_date_str
にプログラムのリンク時間が含まれます。
Stackoverflowの前にgithubがオフラインになる場合、このソリューションのアイデアは次のとおりです。
BUILD_TIME
を使用してstring(TIMESTAMP ...
CMake変数を作成します。BUILD_TIME
を記録する小さなライブラリをコンパイルして、プログラムからグローバル変数(印刷できるものなど)に入れます。cmake -U BUILD_TIME
を使用してCMakeキャッシュから変数を削除するカスタムターゲットに依存させる。つまり、プロジェクトをビルドするたびに、依存関係がチェックされ、CMakeキャッシュがクリアされ、このタイムスタンプライブラリに対してCMakeが再実行されます。このソリューションの欠点は、CIシステムがある場合、CMakeステップに渡すパラメーターはすべて、ビルドステップにも渡すことを覚えておく必要があることです。