LoginSignup
4
3

More than 3 years have passed since last update.

CMakeでgitのコミットハッシュをコードに埋め込む

Last updated at Posted at 2021-02-24

S/Wだとそんなことはまずないが、H/Wだと今動いているコードが何か知りたいので、コードの一部にgitのコミット番号を埋め込みたい、みたいなことが起こる (らしい。) その時に引っかかったことがあるので残しておく。結論から言うとTARGETを使うadd_custom_commandを使うのが一番いい気がする。なおCMakeに関してはほとんどわかっていないのでご容赦を...

gitのコミットハッシュを取得する

gitのコミットハッシュ自体は下で取得できる(長いやつ)

$ git log --pretty=format:%H -1
# 又は
$ git rev-parse HEAD

短いやつ

$ git log --pretty=format:%h -1
# 又は
$ git rev-parse --short HEAD

CMakeの処理3段階

  1. Configure ファイルの依存関係をさらう
  2. Generate さらった依存関係を元にビルド用ファイルを作成
  3. Build ビルドを実行
    の主に3段階ある。よく
-- Configuring done
-- Generating done
-- Build files have been written to: /hogehoge

みたいな表示を見る。

CMakeでコマンド実行

CMakeでコマンドを実行する方法は主に2通りある。 execute_processadd_custom_commandの2つ。2つと書いたが、add_custom_commandには使い方が2通りあって、頭にOUTPUTを持ってくるかTARGETを持ってくるかで処理が全く違う。OUTPUTを持ってきた場合はビルド用のファイル生成でTARGETを使うのはビルド時にコマンド実行(ビルドイベント)をする用途になる。
cf. add_custom_command - CMake
このうち、上のビルド時に実行されるのはadd_custom_commandTARGETのみ。他は configure or generate で実行される。

Gitハッシュ埋め込み

execute_processadd_custom_commandの使い方についてはCMakeの公式リファレンスにしっかり載ってるのでそちらに譲る。
cf. execute_process - CMake
1つ目の方法としてexecute_processでハッシュ値を取得、configure_fileで埋め込み、という手がある。WORKING_DIRECTORYはgit ~を実行するディレクトリを指定するので、git submodule内部のハッシュ値が欲しい場合はそのディレクトリを指定してあげればいい。

CMakeLists.txt
execute_process(COMMAND git rev-parse --short HEAD 
  OUTPUT_VARIABLE git_rev
  OUTPUT_STRIP_TRAILING_WHITESPACE
  WORKING_DIRECTORY ${WORKING_DIRECTORY})
configure_file ("hogehoge.tmp" "hogehoge.h")

hogehoge.tmpの中に@git_rev@みたいな文字列を用意しておけば、そこが勝手にgitのハッシュに置き換わってhogehoge.hを出力してくれる。
別の方法としてadd_custom_commandOUTPUTを使う場合。こちらは公式リファレンスにもあるが役目がGenerating Filesなのでビルド前にファイル生成を行うのが主目的。そのファイルがCMakeLists.txtでビルドに使用されるとわかっている時、適当に文字列をハッシュに書きかえる.batなり.shなりを用意してあげればconfigure & generate中にそのコマンドが実行されてくれる。

CMakeLists.txt
add_custom_command(OUTPUT hogehoge.h
  COMMAND hogehoge.bat
  WORKING_DIRECTORY ${WORKING_DIRECTORY})

ただ上の2つの問題点は上でも書いたようにビルド直前では実行されないことだ。一度フォルダを開いてconfigure & generateが済まされた場合、hogehoge.hに何らかの変更が加えられてもその変更を超えてgitのハッシュの反映をなされない。そういう場合でも変わらず埋め込みたい場合はadd_custom_commandTARGETを使用する。こちらの役割はBuild Eventsである。

CMakeLists.txt
add_custom_command(TARGET ${PROJECT_NAME}
  PRE_BUILD
  COMMAND hogehoge.bat
  WORKING_DIRECTORY ${WORKING_DIRECTORY})

これはビルドが実行される場合、つまりプログラムが走る場合常に直前に実行されるので他の改変の影響を受けない。のでそうして欲しい場合はadd_custom_commandTARGETを使用しよう。ここではビルド直前に反映されて欲しいのでPRE_BUILDとしているが、PRE_LINK, POST_BUILDなどで実行するタイミングを指定できる。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3