2023年1月8日日曜日

PlatformIOでビルド時にgitのコミット情報をcppのマクロとして定義


背景

cppのプログラムにその時点でのコミット情報を埋め込んで配信したかったので、platformioの設定を調べて実現しました。
備忘録を兼ねて方法を記事に残します。

使ったもの

  • プログラムを書き込むパソコン
    OSはUbuntu22.04のものを利用しました。
  • platformio
    pio --version 
    PlatformIO Core, version 6.1.6a4
  • Arduinoとして動かせる開発ボード + USBケーブル
    今回はESP32をArduinoとして動かして動作確認しました。

extra scriptを利用してコミット情報のマクロを定義

platformioは処理前後の挙動をextra scriptで設定可能なので、それでコミット情報をビルド時のフラグとして追加すれば、コミット情報を含むマクロをプログラムに埋め込みます。

ここで紹介する処理では、下記のようにSTR_INFO_GITという名前のマクロでコミットの日時と編集中か否かを設定します。gitの情報が得られない場合はno-infoと出します。

STR_INFO_GIT=YYYY-MM-DD-hh-mm-ss+zzzz-[no-diff|editing]
例1: 2023-01-07-22:49:16+0900-modified
例2: 2023-01-07-23:05:18+0900-no-diff
例3: no-info

platformio.iniにextra_scriptを追加します。
platformio.ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
extra_script = ./extra.py

extra_scriptでSTR_INFO_GITを作成して割り当てます。
platformioのv6からAppendを呼ぶ対象がenvからprojenvに変わったようなので注意が必要です。
自分が検索したときはenvに対してAppendを呼んでいる例が多く見つかりましたが、それでは動かず時間を取られました。
extra.py
Import("env", "projenv")
import os
import subprocess

try:
cmd = "git log -1 --pretty=%cd --date=format:%Y-%m-%d-%H:%M:%S%z"
str_info_git = subprocess.check_output(cmd.split()).strip().decode('utf-8')
cmd = 'git diff --name-only'
str_diff_files = subprocess.check_output(cmd.split()).strip()
if str_diff_files == b'':
str_info_git = str_info_git + '-no-diff'
else:
str_info_git = str_info_git + '-modified'
print(str_info_git)
projenv.AppendUnique(CPPDEFINES=[("STR_INFO_GIT", env.StringifyMacro(str_info_git))])
except Exception as e:
print("cannot assign str")
print(e)

STR_INFO_GITをシリアル出力するプログラムです。
STR_INFO_GITが定義されていない場合はno-infoを割り当てます。
main.cpp
#include <Arduino.h>

#ifndef STR_INFO_GIT
#define STR_INFO_GIT "no-info"
#endif

void setup() {
Serial.begin(115200);
Serial.println("start");
}

void loop() {
Serial.print("STR_INFO_GIT: ");
Serial.println(STR_INFO_GIT);
Serial.println(millis());
delay(1000);
}

上記のプログラムを書き込んでログを確認すると、下記のようにコミット情報を確認できます。
STR_INFO_GIT: 2023-01-07-23:05:18+0900-modified
7038
STR_INFO_GIT: 2023-01-07-23:05:18+0900-modified
8038

終わり

ビルド時にコミット情報からマクロを定義してプログラムに組み込めました。
今までは気づいた時に手動で更新していて肝心な時に差異が分からないことがありましたが、今回の自動組み込み方式ならそういう不都合な場面を無くせるので嬉しいです。

参考

作成したプログラムをまとめたリポジトリです
practice-esp32-pio-add-git-info

extra scriptに関するplatformio公式の説明です
Pre & Post Actions - PlatformIO
extraScript - PlatformIO

envではなくprojenvの利用が必要と分かったissueです
Post Build scripts are being run before the build started
using extra_scripts is not working as expected (global scope)

今回は利用しませんでしたがgitのcommitのhash情報を取得するコマンド情報です
「git rev-parse HEAD」や「git rev-parse --short HEAD」でhash値を取得できます
Get the current git hash in a Python script

最新のコミットの日時を取得するコマンドを把握したページです
git log -1 --pretty=%cd --date=format:%Y-%m-%d-%H:%M:%S%z
How do I get last commit date from git repository?

gitで差分が発生しているファイルの一覧表示コマンドを把握したページです
git diff --name-only
Getting a list of the changed files

0 件のコメント :