はじめに
前々回、
ビルドが終わったらティロリサウンドを鳴らしてみるのもいいかもですね...いや迷惑。
なんて書きましたが、実際の所これをやるには問題がありますよね?
エラーが発生した時点で以後のビルドプロセスをキャンセルする事は可能ですが、エラーが発生した事を知る方法がないのです。ビルドエラーイベントなんてものはないのですから。
ビルドエラーを検出する
例えば大規模プロジェクトをビルドする際、終了時に何かを仕込むと便利です。
- サウンドを鳴らす
- メールを送信する
- LINE / Slack 等に通知する
ですが、ビルド終了イベント (Post-build events) でビルドが成功したか失敗したかを簡単に取得する方法はないようです。つまり、エラーが出てビルドプロセスが途中で止まった時に通知する方法はないという事になります。むしろエラーで止まってしまった時こそ早急に通知が欲しいのに...orz
<Delphi のインストールフォルダ>\bin にある CodeGear.xxx.Targets 1 をいじればどうにかなるのかもしれませんが、これに関する詳しいドキュメントは存在しません。
MSBuild
Delphi 2007 以降、ビルドには MSBuild が使われています。
一旦 IDE でビルドしたら、プロジェクトフォルダで RAD Studio コマンドプロンプト を開き msbuild とだけ叩けば、前回の構成でビルドされます 2。
新規ビルドでの最低限のコマンドラインオプションは次のようになります。
msbuild <プロジェクトファイル> -t:<ターゲット> -p:config=<ビルド構成>;platform=<プラットフォーム>
以下は Project1.dproj をビルドする例です。
msbuild Project1.dproj -t:build -p:config=Release;platform=Win32
See also:
- MSBuild (learn.microsoft.com)
- MSBuild コマンドラインリファレンス (learn.microsoft.com)
- MSBuildを使ってDelphi 10.1 Berlinのプロジェクトをビルドする (山本隆の開発日誌)
カスタムロガー
色々調べてみたら、MSBuild では -l (-logger) オプションでカスタムロガーを指定できるようです。
カスタムロガーを仕込めば MSBuild 終了時に成功・失敗を判断できそうです。
とはいえ、Targets ファイルにカスタムロガーを仕込む方法も判っていないので、現時点では MSBuid を手動実行する方向で進めて行きたいと思います。
カスタムロガーの作り方
うーん。カスタムロガーは .NET で作るのですか。しかも DLL (アセンブリ) として作る必要がある、と。
.NET
Delphi.NET (Delphi 8 系列) は廃止になっているし、もはや RAD Studio にも Delphi Prism (Oxygene) はバンドルされていませんし... 3
いや、素直に C# で書けばいいのですよ?Visual Studio Community Edition もあるのですから。
Visual Studio Community Edition を使える条件は次の通りです:
- 個人: 有償/無償問わず
- 中小企業: 最大 5 ユーザー
- 大企業・官公庁: PC 250 台未満 or 売上 100 万ドル未満
上記条件に一致しない場合でも、学習・学術研究・オープンソースへの寄与においては利用可能です。
でも、Pascal マニアとしては Pascal 系の言語でやってみたいのです!
PascalABC.NET でカスタムロガーを作る
ここは PascalABC.NET の力を借りようと思います。適当にインストールしておいてください。
PascalABC.NET の文法は Delphi Prism (Oxygene) よりも Delphi (.NET) 寄りとなっています。
PascalABC.NET のライセンスは LGPLv3 です。
1.プロジェクトの新規作成
PascalABC.NET を起動します。
[File | New Project] で新規プロジェクトダイアログを開き、Class Library を選択してプロジェクト名を MyLogger にします。
2.コードの記述
C# のコードを例にして Pascal に移植します。
Library MyLogger;
interface
uses
System, Microsoft.Build.Framework, Microsoft.Build.Utilities;
type
TMySimpleLogger = class(Logger)
public
constructor Create;
procedure Initialize(eventSource: IEventSource); override;
end;
implementation
constructor TMySimpleLogger.Create;
begin
inherited Create;
end;
procedure TMySimpleLogger.Initialize(eventSource: IEventSource);
begin
if eventSource = nil then
raise new ArgumentNullException('eventSource');
// プロジェクト終了イベント
eventSource.ProjectFinished +=
procedure(sender: Object; e: ProjectFinishedEventArgs) ->
begin
Console.Write('[Project Finished]: ');
if e.Succeeded then
Console.WriteLine('Success!') // ビルド成功
else
Console.WriteLine('Failed!'); // ビルド失敗
end;
end;
end.
今回、MSBuild の終了イベント (プロジェクト終了イベント) だけを検出できればいいので、短いコードになっています。
コードエディタにそのまま貼り付けてください。
4.参照の追加
左ペインの [Project Explorer] にある References ツリーを右クリックして [Add Reference] を選択します ([Project | Add Reference] でも OK)。
Microsoft.Build.Framework と Microsoft.Build.Utilities を追加します。
[Project Explorer] で次のような表示になれば OK です。
4.プロジェクトのビルド
[Program | Build] でビルドします。
ここまでの手順に間違いがなければ MyLogger.dll ができていると思います。
カスタムロガーを有効にして MSBuild を実行
プロジェクトフォルダに MyLogger.dll をコピーしておきます。
MSBuild の -l (-logger) オプションは次のような書式です。
-l:{[[名前空間.]ロガークラス名,]アセンブリファイル[;パラメータ]}
具体的には次のパラメータを渡します。
-l:MyLogger.TMySimpleLogger,MyLogger.dll
アセンブリファイル (*.dll) にロガークラスが一つだけの場合にはロガークラスの指定が不要なので、今回はもっと短く書けます。
-l:MyLogger.dll
カスタムロガーを組み込んだ msbuild のコマンドラインを 1 行で書くとこんな感じです。
msbuild Project1.dproj -t:build -p:config=Release;platform=Win32 -l:MyLogger.dll
わざとバグを混入させてビルドしてみました。
ちゃんとカスタムロガーが実行されています。
IDE で指定したビルドイベントとも共存できます。
おわりに
もっと簡単にビルド終了時の成功・失敗ステータスを取得する方法をご存じでしたらコメント欄までお願いします m(_ _)m
やっぱりビルドエラーイベントが欲しかったので QP に要望を出しておきました。
See also:
- MSBuild コマンドを使用したプロジェクトのビルド (DocWiki)
- Windows 8.x / 10 / 11 が Delphi 2007 の .targets ファイルを消すのでどうにかする (Qiita)
PascalABC.NET を使った感想
今回初めて PascalABC.NET を使ってみたのですが、なかなかいい感じですね。
Windows Forms アプリケーションも作れるので、.NET 系でちょっとした何かをやらなくてはいけなくなったら選択肢の一つに入れてもいいかもしれません。










