C++ Builderの出力mapを自動コピーして保存する

C++ Builderもリンク時にmapファイルを出力できる。
release版でアドレス違反が発生したときのメッセージをもとに、mapファイルで発生元の関数を推測できる。

ただし、そのためには準備がいる。
mapの出力設定はオプションのリンカ→出力→マップファイルの種類で「詳細なセグメントマップ」にする。
メイクあるいはビルド毎にmapファイルは上書きされ過去のmapファイルはなくなるので、最新版以外でトラブル発生に備えるならばmapの自動保存がされるように仕込んでおく必要がある。
自分がやっているのは、ビルドイベントとバッチファイルを組み合わせて、自動コピーする方法だ。
Gitなどを使っているのであれば、コミットすればmapもスナップショットが保存されるのかもしてない。そちらは自分で確認して欲しい。

まず、オプションのビルドイベントで、ビルド後のコマンドに以下を設定する。
設定するのは目的のターゲット(例えばWin32 release)のみでよいだろう。

chdir $(OUTPUTDIR)
map_copy.bat $(OUTPUTNAME)

mapファイルの保存先としてmapフォルダーを作成しておく(今回の例であればWin32\release\map)。
バッチファイル(map_copy.bat)はパスの通ったところに置く。
内容は以下の通り(2021-02-04修正)。

@echo off
set YYYY=%date:~0,4%
set MM=%date:~5,2%
set DD=%date:~8,2%
set H1=%time:~0,1%
set H2=%time:~1,1%
set NN=%time:~3,2%
if "%H1%" == " " set H1=0
copy %1.map map\%1_%YYYY%-%MM%-%DD%_%H1%%H2%-%NN%.map

これで例えばProject1のmapファイル(Project1.map)を2021-01-05 19:58に保存したとすれば、自動でmapフォルダーに名前(2021-01-05_19_58_Project1.map)をつけて保存してくれる。
この方法の場合、常にmapファイルのコピーが作成されるので、適当なタイミングで不要なmapファイルを削除した方が良いだろう。

2021-02-04 追記

時間が0~9時だとバッチファイルが正しく動作しない問題を修正した。
ifで%H1%に""をつけているのはそうしないと%H1%は空白に置き換えされてコマンドエラーを起こすため。比較対象の空白も""で囲む。
ついでに別解も示す。こちらの方がシンプルか。

@echo off
set mDate=%date:/=-%
set mTime=%time: =0%
set HH=%mTime:~0,2%
set MM=%mTime:~3,2%

copy %1.map map\%1_%mDate%_%HH%-%MM%.map

コマンドの詳細については、以下の記事を参考にした。
Windowsバッチまとめ - Qiita