Skip to content

MS_BuildScript

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

ビルドスクリプト

概要

ビルドスクリプトでビルド自動化をすると、かなり生産性向上に寄与する。

ツール

下記ツールを使用してビルドを行うことが出来る。

コマンドライン

Visual Studio をコマンドラインで呼び出してビルドできる。

devenv /build release solution.sln 
  • devenv は Visual Studio の EXE

  • *.bat 化も容易、多くの要件にはこちらで対応可能。

補足(devenv を CI で使うべきではない理由): 手元の自動化には
手軽だが、ビルド サーバでは避けるのが定石である。

【devenv の問題】★
 ・【IDE 本体を起動する】
     → 重い。ライセンスが要る。GUI セッションを要求しうる
 ・【多重起動できない】
     → 並列ビルドに向かない
 ・ユーザー設定(.suo、ユーザー プロファイル)に影響される
     → 「私の環境では通る」の温床 ★
 ・戻り値・ログが扱いにくい

【CI での正しい選択】★
   ・.NET Framework  → 【MSBuild.exe】
   ・.NET Core 以降  → 【dotnet build】★
   ・Build Tools のみ導入すれば
     【VS 本体をインストールせずに済む】
       Visual Studio Build Tools(無償)
     → コンテナ イメージも提供されている

【devenv が今も要る場面】
   ・VS 固有のプロジェクト種別で
     MSBuild だけでは通らないもの
     (一部のセットアップ プロジェクト、
       古い C++ 系のカスタム ビルド)
   → その場合も【将来の負債】と認識しておく

ビルド・イベント

  • 「ビルド前のイベント」
  • 「ビルド後のイベント」

がある。

例えば、プロジェクト(プロジェクト・ファイル(*.csproj *.vbproj))に、
[ビルド後のイベント] を仕掛けて、プロジェクトのバイナリ出力を配置できる。

補足(ビルド イベントの落とし穴): 手軽な反面、壊れやすい

【① 失敗しても気付きにくい】★
   ・Pre/Post build event の
     終了コードが 0 以外ならビルドは失敗するが、
     エラー メッセージが【埋もれやすい】
   → 重要な処理はカスタム Target にして
     Message / Error タスクで明示する

【② パスに空白があると壊れる】
   → マクロは必ず引用符で囲む
      copy "$(TargetPath)" "$(SolutionDir)bin\"

【③ SDK スタイルでは Target の方が素直】★
   <Target Name="CopyOutput" AfterTargets="Build">
     <Copy SourceFiles="$(TargetPath)"
           DestinationFolder="$(SolutionDir)dist\" />
   </Target>
   → クロスプラットフォームで動く
   → 増分ビルド(Inputs/Outputs)を指定できる
   → cmd 依存の bat を書かずに済む

【④ 主なマクロ】
   $(TargetPath)    出力ファイルのフル パス
   $(TargetDir)     出力ディレクトリ
   $(ProjectDir)    プロジェクトのディレクトリ
   $(SolutionDir)   ソリューションのディレクトリ
                    ※ dotnet build 単体では
                      【空になることがある】★
   $(Configuration) Debug / Release

参考

MSBuild / NAnt

マイクロソフトのビルド環境であり、通常 Visual Studio と一緒に使われている。

  • nmake ツールの(機能的な意味での).NET 版

  • Visual Studio プロジェクトを IDE 無しでビルドできる。

NAnt

2012 年あたりで開発が停止している模様。

  • NAntを活用して開発時の作業を自動化する(1-4):CodeZine
    http://codezine.jp/article/detail/354

    • ビルドツールとは、アプリケーションの構築に必要なソースコードの
      コンパイルを容易にしたり、定型作業を自動化したりできるツールです。

    • NAnt の最大の魅力は呼び出せる機能の多さにあります。
      この機能のことを NAnt では「タスク」と呼んでいます。

補足(NAnt はその後どうなったか): 「2012 年あたりで停止」という
見立ては正しく、その後も再開していない

【NAnt の現況】★
   ・最終リリースは 0.92(2012年6月)
   ・以降、正式リリースなし
   ・.NET Core / .NET 5+ への対応もない
   → 【新規で選ぶ理由はない】

【何が代わりになったか】
   ・ビルド定義       → 【MSBuild】(.csproj そのもの)★
   ・タスクの豊富さ   → 【MSBuild タスク + NuGet】
       (MSBuild.Extension.Pack、
         MSBuildTasks 等のタスク集)
   ・CI との連携      → 【GitHub Actions / Azure Pipelines】★
       → 「ビルド以外の定型作業」は
         CI のステップとして書くようになった
   ・C# でビルドを書きたい
       → 【Cake】(C# Make)★
       → 【NUKE】(型付きのビルド定義)
       → いずれも「XML を書きたくない」層に支持がある

参考

移行メモ(正誤): 移行元では「例えばテスト・ツール「NAnt」の
呼び出しが標準機能だけで可能」となっていたが、
テスト・ツールは NAnt ではない(NAnt 自身の呼び出しでは意味が通らない)。
文脈から NUnit の誤記と判断し修正した
(NAnt には <nunit2> タスクが標準で用意されていた)。

その他

NuGet

  • .NET 向けのパッケージ管理システムで、
    ビルド時に、packages.config を見てパッケージを復元する。
..\nuget.exe restore "Frameworks\Infrastructure\AllComponent.sln"
  • PackageReference に切り替え後のビルドでは、NuGet リストアを
    nuget.exe ではなく、MSBuild /t:Restore で行うように変更されている。
MSBuild.exe /p:Configuration=Debug -v:d /t:Restore XXXXX.sln

移行メモ(表記): 移行元の「package.config」を、
実際のファイル名である「packages.config」に修正した。

補足(packages.configPackageReference: 原文が触れている
この移行は、今も現場で残っている作業である。

packages.config PackageReference
記述場所 別ファイル .csproj の中
依存の解決 フラットに全部書く 推移的依存を自動解決
配置先 ソリューション直下の packages/ グローバル キャッシュ~/.nuget/packages)★
復元 nuget restore msbuild /t:Restore / dotnet restore
対象 .NET Framework の旧形式 SDK スタイル / 現行
【PackageReference の利点】★
 ・リポジトリに packages/ を含めなくてよい
   → 【リポジトリが軽くなる】
 ・推移的依存が自動で解決される
   → 「A が B を要求している」を自分で書かなくてよい
 ・条件付き参照が書ける
     <PackageReference Include="X" Version="1.0"
                       Condition="'$(TargetFramework)'=='net48'" />
 ・【中央パッケージ管理】(Directory.Packages.props)★
   → 複数プロジェクトのバージョンを 1 箇所で揃える

【移行時の注意】
 ・VS の [packages.config を PackageReference に移行] で
   一括変換できるが、
   - content ファイルを配るパッケージ
   - install.ps1 に依存するパッケージ
   は【挙動が変わる】★
 ・[NU1605](MS_NuGetNU1605) 等の
   ダウングレード検出が厳しくなり、
   今まで通っていたビルドが落ちることがある

.NET Core では dotnetコマンド を使用する。

トラブルシュート

しかし、色々と問題が起きます。

MSBuild の該当節を参照。

NuGet の該当節を参照。

dotnetコマンド の該当節を参照。

参考

Open 棟梁は devenv や MSBuild を使用した
ビルド バッチ(*.bat)を提供して、
ビルドタスクの自動化を行っている。

https://github.com/OpenTouryoProject/OpenTouryo/tree/develop/root/programs/CS

補足(ビルド自動化の現在の到達点): 「ビルド スクリプトで自動化すると
生産性向上に寄与する」という主張は正しく、さらに先へ進んでいる

【段階】★
   ① 手作業でビルド
   ② 【bat / スクリプトで自動化】← 本ページの主題
   ③ 【CI で自動実行】(push のたびに回る)★
      → [CI](MS_CI) / [GitHub Actions](MS_GitHubActions)
   ④ 【CD まで自動化】(承認を挟んで配置)
      → [CI/CD パイプライン](MS_CICDPipeline)
   ⑤ 【IaC】(環境そのものもコード化)

【②で止まると起きること】
   ・「ビルドできるのは特定の PC だけ」
   ・スクリプトが【誰にも保守されない】
   ・手元と CI で結果が違う
   → ②を作るなら、
     【そのまま CI で回せる形】にしておくのが得策 ★
     (=ローカル環境固有のパスを埋め込まない、
       引数で環境を切り替える)

【再現性を上げる仕掛け】★
   ・global.json      … SDK のバージョンを固定する
   ・Directory.Build.props … 共通の MSBuild 設定
   ・Directory.Packages.props … パッケージ版の中央管理
   ・【ロック ファイル】(packages.lock.json)
     → 依存の版を固定し、
       「昨日は通ったのに今日落ちる」を防ぐ
   ・コンテナでビルドする
     → 環境差そのものを消す

Tags: 移行, テスト, デバッグ, デプロイ, CI, .NET開発

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally