特集

MSBuild完全攻略(後編)

ビルド・エンジン「MSBuild」を思いのままに操る技

デジタルアドバンテージ 一色 政彦
2006/05/13

Page1 Page2 Page3

 前編では、MSBuildとは何かについて、またその実行方法について解説した。MSBuildは自由度の高いツールなので、ビルドに付随するさまざまな独自タスクを自動化できる。

 しかし、本当に思いどおりに使いこなすには、MSBuildファイルの内容についての深い理解が必要だ。そこで後編となる今回は、MSBuildファイルの内容の読み方と書き方を示し、さらにはより高度なMSBuildファイルを作成する方法を紹介しよう。

 なお本稿ではVisual Studio 2005 Professional Edition(以降、VS 2005)を利用している。

4. MSBuildファイルの徹底理解

 まずはVS 2005で生成されたプロジェクト・ファイル(=MSBuildファイル)の内容を見てみよう。ここで使用するサンプル・アプリケーションは前回と同じコンソール・アプリケーションである。

 VS 2005を使っている場合は、プロジェクト・ファイルをIDEから直接、編集できる(使っていない場合は、プロジェクト・ファイルをテキスト・エディタなどで開けばよい)。

 具体的には次の画面の手順を参考にしてほしい*2

*2 ただし、VS 2005の各Express Editionでは、Visual C++ 2005を除いて、下の画面で説明している「プロジェクトのアンロード」と「プロジェクト・ファイルの編集」の機能が搭載されていない(なお「IntelliSense機能」はすべてのEditionで利用可能だ)。
 
VS 2005 IDEのXMLエディタでプロジェクト・ファイルを開く手順
VS 2005 IDEで現在開いているプロジェクトのMSBuildファイルを、XMLエディタで表示したところ。
  編集したいプロジェクトを[ソリューション エクスプローラ]で右クリックしてコンテキスト・メニューを開き、そこから[プロジェクトのアンロード]を選択する。これにより、プロジェクト・ファイルが編集可能な状態になる。ちなみに、アンロードしたプロジェクトを元に戻すには、同じコンテキスト・メニューから[プロジェクトの再読み込み]を選択すればよい。
  続けて、再度コンテキスト・メニューから[編集 <プロジェクト・ファイル名>](本稿の例では「編集 ConsoleApplication1.cspoj」)を選択する。これにより、プロジェクト・ファイルがXMLエディタ上で開かれる。
  VS 2005ではMSBuildファイルに対するIntelliSenseが提供されているので、テキスト・エディタで編集するよりも便利だ。

 VS 2005が生成するプロジェクト・ファイルの記述内容は少し長いので、ここでそのすべてをまとめて説明するのは難しい。従って、以降ではこのプロジェクト・ファイルとほぼ同じ内容のMSBuildファイルを作成する手順を通して、MSBuildファイルの読み方、書き方について説明していくことにしよう。

VS 2005による独自のMSBuildファイルの編集

 最初に「ConsoleApplication1.myproj」という名前の独自のMSBuildファイルを新規作成しよう。VS 2005がない場合はテキスト・エディタで編集するしかないが、ある場合はIntelliSenseが使えるのでVS 2005を活用した方がよい。

 次の画面は、独自のMSBuildファイル(本稿の例では「.myproj」という拡張子を持つファイル)をVS 2005のXMLエディタに関連付けて*3、次回以降で簡単に編集できるようにするための前準備を行う方法を示している。

*3 ただしこの機能は、Express Editionの中では、Visual C++ 2005 Express Editionにしか搭載されていない。従ってそれ以外のExpress Editionを使う場合には毎回手動でXMLエディタを選択してファイルを選択する必要がある(つまり次の画面で示すの手順を毎回行う必要がある)。
 
VS 2005で独自のMSBuildファイルを編集するための前準備
最初に独自のMSBuildファイル(本稿の例では「*.myproj」)に対するXMLエディタの関連付けを行う。これにより、次回以降そのMSBuildファイルをVS 2005のIDEで普通に開こうとすると、自動的にXMLエディタで開かれるようになる。なおここではいったんプロジェクトにMSBuildファイルを追加する方法を示しているが、IDEのメニュー・バーから[ファイル]−[開く]−[ファイル]を選択して[ファイルを開く]ダイアログを表示し、そこの[開く]ボタンの右端にある[▼]メニューから[ファイルを開くアプリケーションの選択]を選択して以降の処理を行ってもよい。
  VS 2005のプロジェクトに対して、「ConsoleApplication1.myproj」という独自のMSBuildファイルを追加する(上記の説明に従ってプロジェクトをアンロードした場合は、あらかじめプロジェクトの再読み込みを実行すること)。具体的には、[ソリューション エクスプローラ]のプロジェクト・フォルダを右クリックして開くコンテキスト・メニューから[追加]−[新しい項目]を選択して[新しい項目の追加]ダイアログを開き、そこから「XML ファイル」のテンプレートを選択して「ConsoleApplication1.myproj」というファイル名を入力し、最後に[追加]ボタンをクリックする。
  新規に追加した「ConsoleApplication1.myproj」ファイルを右クリックし、開かれたコンテキスト・メニューから[ファイルを開くアプリケーションの選択]をクリックする。これにより、[ファイルを開くアプリケーションの選択]ダイアログが表示される。
  [ファイルを開くアプリケーションの選択]ダイアログで[このファイルを開くのに使用するプログラムを選択してださい]リストの中から「XML エディタ」を選択し、[既定値として設定]ボタンをクリックする。これにより、以後、「.myproj」という拡張子を持つファイルはXMLエディタで開かれるようになる。
  後は[OK]ボタンをクリックして実際にMSBuildファイルを開くだけだが、文字コードが「UTF-8」ではない可能性がある場合は、「エンコード付き XML エディタ」をダブルクリックし、そこで表示される[エンコード]ダイアログから「Unicode (UTF-8 シグネチャ (BOM) 付き) − コードページ 65001」を選択して開くとよい。なおを実行して新規XMLファイルを作成した場合、文字コードは「UTF-8」のはずなのでこの作業は不要だ。

MSBuildファイルのルート要素 ― <Project>タグ

 上記の方法で独自のMSBuildファイルを新規作成すると、ファイル内に

「<?xml version="1.0" encoding="utf-8" ?>」

というXML宣言が記述されているが、MSBuildファイルではこれは不要なので消してよい(もちろん消さなくても問題なく動作する)。そして、次のテキストを追加してほしい。これにより、IntelliSenseを使ったMSBuild関連タグの挿入が可能になる。

<Project
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

</Project>
MSBuildファイルに最低限必要な<Project>タグの記述

 ここで記述した<Project>タグはMSBuildファイル(=プロジェクト・ファイル)のルート要素で、前回でも度々登場したVS 2005プロジェクトと同じ概念である。すなわち、モジュール(=ビルドにより出力するプログラム・ファイル)ごとに1つの<Project>タグが必要で、いうまでもないがMSBuildファイル1つにつき、<Project>タグは1つしか記述できない。

【コラム】MSBuildによるマルチ・モジュール・アセンブリの開発

 ここで、アセンブリではなくモジュールと記述しているのは、.NET Frameworkでは複数のモジュール(=ファイル)で1つのアセンブリを構成することが可能なので、必ずしも「1プロジェクト=1アセンブリ」とは限らないからだ。このようなアセンブリは、「マルチ・モジュール・アセンブリ」と呼ばれ、複数言語(例えば、C#とVisual Basic:以降VB)で作成したモジュールを1つのアセンブリとして扱いたい場合などに使われる。

インサイド .NET Framework [改訂版] ― マルチ・モジュール・アセンブリの作成
 マルチ・モジュール・アセンブリのモジュール(拡張子は「.netmodule」)を作成するには、MSBuildファイルのOutPutプロパティに「Module」を設定すればよい。だが、依然としてVS 2005のIDEのビルド機能では、このようなマルチ・モジュール・アセンブリの生成に対応していない(※MSBuild自体は対応しているのだが……)。しかも、プロジェクト・ファイルを手動で編集して「Module」という値を指定したとしても、VS 2005のIDEがこれをエラーとしてはじいてしまう。

 このため、実際にこのようなモジュールを作成するには、VS 2005とは別のMSBuildファイルを作成するか、MSBuildをコマンドラインから呼び出す際にOutPutプロパティの上書き設定を行う必要があるのだ(コマンドラインからプロパティを設定する方法は前回説明した)。

 さらに、そこで生成したモジュールをアセンブリ・ファイルに追加するための指定も必要となる。具体的には、C#やVBのコンパイルを行うタスクである<Csc>タグ(=Cscタスク)や<Vbc>タグ(=Vbcタスク)を独自に追加して、そのAddModules属性にそのモジュールを指定する。例えば、次のような内容のMSBuildファイルが必要になるわけだ(このMSBuildファイルを含むプロジェクト全体は説明欄のリンクからダウンロードできる)。


……前略……
<Target Name="ModuleCompilation">
  <MakeDir Directories= "$(OutputPath)"/>
  <Csc Sources="ConsoleApplication1.cs" TargetType="Exe"
       AddModules="$(OutputPath)\MyModule.netmodule"
       OutputAssembly="$(OutputPath)\ConsoleApplication1.exe" />
</Target>
……後略……
マルチ・モジュール・アセンブリを生成するMSBuildファイルの内容(抜粋)
このコードでは、まずMakeDirタスクによって出力フォルダ(この例では「$(OutputPath)」)を作成して、次にCscタスクによってモジュール・ファイルを組み込んで最終的に「ConsoleApplication1.exe」というアセンブリ・ファイルを生成している。

処理プロセスの定義 ― <Target>タグ

 MSBuildファイルでルート要素の次に重要なのが「ターゲット(Target)」である。ターゲットについては前回でも解説したが、「処理プロセスの1単位」を意味し、例えば「ビルド」や「コンパイル」などの各処理プロセス1つ1つがターゲットとなる。

 VS 2005のプロジェクトの基本的なターゲット(=ビルド処理プロセス)としては、「ビルド(Build)」「リビルド(Rebuild)」「クリーン(Clean)」「発行(Publish)」などが考えられる。例えばこのうちビルドに関するターゲットを独自に定義するなら、次のように記述すればよい。

<Project
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Build">
    ……タスクの記述……
  </Target>
</Project>
Buildターゲットの定義方法
ルート要素の<Project>タグの中に<Target>タグを記述する。なおターゲットはプロジェクト内にいくつ記述してもよい。

 <Target>タグのName属性にターゲット名(この例では「Build」)を指定して、ターゲットを定義する。なおここで「……タスクの記述……」と記述している個所には、処理プロセスを構成する具体的な処理作業(例えば「ディレクトリの作成」「コンパイラの呼び出し」など)を記述する。この細かな処理作業は「タスク(Task)」と呼ばれ、「処理作業の最小単位」を意味する。つまり1つのターゲット(=処理プロセス)は、一連のタスク(=処理作業)を実行する手順(=プロセス)によって構成されるわけである。このタスクの定義方法について詳しくは後述する。

 上記ではBuildターゲットを定義する例を示したが、実はビルドに必要な標準的なターゲットは、.NET Framework 2.0のランタイムがインストールされている場所(基本的には「C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727」)の「Microsoft.CSharp.targets」というファイル(C#の場合。VBの場合は「Microsoft.VisualBasic.targets」)にあらかじめ定義されているので*4、これをMSBuildファイル内にインポートして利用すれば、実際には独自に定義する必要はない。

*4 厳密には「Microsoft.CSharp.targets」や「Microsoft.VisualBasic.targets」がインポートしている「Microsoft.Common.targets」に標準的なターゲットが実装されている。

 Microsoft.CSharp.targetsファイルを実際にMSBuildファイルへインポートするには、<Import>タグを使えばよい。次のコードではそれを実際に行っている例だ。

<Project
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import
    Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

</Project>
MSBuild予約済みターゲットのインポート方法
<Import>タグにより、Microsoft.CSharp.targetsファイルをインポートする。

 この例では、<Import>タグのProject属性にMicrosoft.CSharp.targetsファイルへのパスを指定している。このファイルが格納されている.NET Framework 2.0ラインタイムのインストール・フォルダへのパスは、「MSBuildBinPath」という予約済みプロパティから取得できる。なお上記のコードを見れば分かるように、プロパティのデータには

「$(<プロパティ名>)」

という構文でアクセスできる(この例では「$(MSBuildBinPath)」という式によりMSBuildBinPathプロパティのデータにアクセスしているが、これにより筆者の環境では「C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727」というパス名が取得できる)。

 以上のインポートの記述によりMSBuildファイル内でBuildターゲットが利用できるようになったので、MSBuildを実行したときにデフォルトでこのターゲットが実行されるようにしておこう。これには<Project>タグのDefaultTargets属性にターゲット名として「Build」を指定すればよい。具体的には次のようなコードになる。

<Project
  DefaultTargets="Build"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
デフォルト・ターゲットの指定
<Project>タグのDefaultTargets属性にターゲット名として「Build」を指定する。
 

 INDEX
  MSBuild完全攻略
  .NETビルド・エンジン「MSBuild」使いこなし術(前編)
    1.「MSBuild」および「MSBuildファイル」とは?
    2.コマンドラインからMSBuildを使いこなす!
 
  ビルド・エンジン「MSBuild」を思いのままに操る技(後編)
  3.MSBuildファイルの基本要素を理解する
    4. プロジェクト項目、プロパティ、条件分岐の記述
    5. カスタム・タスクでMSBuildを思いのままに操る!


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間