OSに標準付属のMSBuildツールでプロジェクトをビルドするには?

連載目次

対象:Windows Vista以降
ただし、Windows XPはWindows Updateで対応


 Windowsには標準でC#とVisual Basic(.NET Framework用のもの。「VB.NET」と呼ばれることもある。以降「VB」)のコンパイラーが含まれているが、それだけでなく「MSBuild」というビルドツールも入っている(以降、ツール名として「MSBuild」、実行ファイル名として「MSBuild.exe」と表記する)。コンパイラーだけではVisual Studioのプロジェクトをビルドできないが、MSBuildを使えばプロジェクトをビルドできるのである。本稿では、コンパイラーとビルドツールの違いを説明し、Visual StudioのプロジェクトをMSBuildでビルドする方法を解説する。

コンパイラーだけではできないこと

 C#/VBのコンパイラーがあれば、原理的にはどんな.NET Frameworkのプログラムでも作成できるはずである。MSDNの「コンパイラ オプションの一覧」(C#VB)を見ると、EXEファイルだけでなくDLLファイルを作ることや(「/target」オプション)、出力ファイルにリソースを埋め込むこと(「/resource」オプションなど)なども可能だと分かる。

 しかし、C#/VBのコンパイラーにはできないこともある。代表的なものは、ソースコードの自動生成だ。例えば、WPFではXAMLファイルからC#/VBのコードが自動生成されることはご存じだろう*1。ソースコードやリソースファイルなどを自動生成することは、コンパイラーの役目ではないのである。

 例えばWPFの場合、次の図のような流れでアプリが構築される。

WPFビルドパイプラインの図WPFビルドパイプラインの図
これはMSDN「WPF アプリケーション (WPF) のビルド」に掲載されている図である。
Visual StudioでWPFアプリをビルドするときには、これだけの処理が行われているのだ。その中でコンパイラーが行う処理は、「アセンブリを作成/生成する」と書かれた2カ所だけである。
この手順に必要な情報はプロジェクトファイルに記述されており、それに基づいてMSBuildがそれぞれの処理を呼び出していくのだ。

 上の図で分かることは、C#/VBコンパイラーによる処理(=アセンブリを作成/生成)の他に、コード/リソース/マニフェストといったものを自動生成していることだ。このような処理は(コンパイルも含めて)「ビルドタスク」と呼ばれている。そして、このビルドタスクの一つにコンパイルがあるのだ。

 ビルドタスクを処理するプログラムは、C#/VBコンパイラーが置かれているフォルダー*2(またはその配下のフォルダー)にDLLの形で収められている*3。コンパイラーのようにコマンドラインから実行することはできない。

 このようなビルドタスクの流れを統率し、それぞれのビルドタスクを処理するDLLファイル/EXEファイルを呼び出すのが、MSBuildの役割である。コンパイラーとビルドツールの特徴をまとめると次のようになる。

  • コンパイラー(C#用はcsc.exe/VB用はvbc.exe):C#/VBのソースコードだけをコンパイルする
  • ビルドツール(MSBuild.exe):自身ではコンパイルしない。コンパイラーや、その他のツール(XAMLコードからC#/VBのソースコードを自動生成するツールなど)を呼び出す

プロジェクトファイル

 では、MSBuildにビルドタスクを処理させるにはどうするのだろうか? プロジェクトファイルを読み込ませるのである。

 プロジェクトファイルは、ビルドタスクに必要となる情報を記述したものだ。具体的には「.csproj」ファイル(C#用)/「.vbproj」ファイル(VB用)である。Visual StudioでC#/VBを使った開発をしている人にはおなじみの「.csproj」/「.vbproj」ファイルは、MSBuildに対する「指示書」だったのだ。

 少々長くなるが、ごく簡単なWPFのプログラムをビルドするプロジェクトファイルの例を示そう。

 まず、ソースファイルを用意する。次から示す二つのファイルを、「メモ帳」などのテキストエディターで作成する。

<Application x:Class="App"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  StartupUri="MainWindow.xaml">
</Application>

App.xaml(XAML)
「メモ帳」などのテキストエディターで作成し、「App.xaml」というファイル名で保存する。


<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title=".NET TIPS #1107" Height="350" Width="525">
  <Grid>
    <TextBlock Text="Hello, MSBuild!" FontSize="48"
               HorizontalAlignment="Center" VerticalAlignment="Center" />
  </Grid>
</Window>

MainWindow.xaml(XAML)
画面中央に「Hello, MSBuild!」と表示するだけのUIである。
「メモ帳」などのテキストエディターで作成し、「MainWindow.xaml」というファイル名で保存する。


 それでは、上の2ファイルからWPFプログラムをビルドするプロジェクトファイルを作ろう。上のソースコードはXAMLだけでC#のコードもVBのコードも含まれてないが、MSBuildにはC#かVBのいずれかのソースコードを自動生成させるため、プロジェクトファイルはC#用とVB用とで書き分ける。次のコードのようになる。

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>


    <AssemblyName>AppByMSBuild</AssemblyName>
    <Platform>AnyCPU</Platform>
    <OutputType>WinExe</OutputType>
    <OutputPath>.¥bin¥Release</OutputPath>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  </PropertyGroup>

  <ItemGroup>


    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>

    <Page Include="MainWindow.xaml">


      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>

    <Reference Include="PresentationCore" />


    <Reference Include="PresentationFramework" />
    <Reference Include="WindowsBase" />
    <Reference Include="System" />
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
  </ItemGroup>

  <Import Project="$(MSBuildToolsPath)¥Microsoft.CSharp.targets" />


</Project>

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>


    <AssemblyName>AppByMSBuild</AssemblyName>
    <Platform>AnyCPU</Platform>
    <OutputType>WinExe</OutputType>
    <OutputPath>.¥bin¥Release</OutputPath>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  </PropertyGroup>

  <ItemGroup>


    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>

    <Page Include="MainWindow.xaml">


      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>

    <Reference Include="PresentationCore" />


    <Reference Include="PresentationFramework" />
    <Reference Include="WindowsBase" />
    <Reference Include="System" />
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
  </ItemGroup>

  <Import Project="$(MSBuildToolsPath)¥Microsoft.VisualBasic.targets" />


</Project>

AppByMSBuild.csproj/.vbproj(XML、上:C#用、下:VB用)
「メモ帳」などのテキストエディターで作成し、「AppByMSBuild.csproj/.vbproj」というファイル名で保存する。
C#とVBでは基本的に同じである(太字にした2カ所のみ異なる)。
なお、<TargetFrameworkVersion>要素に「v4.5」と指定してあって、Windows 8.x用になっている(Windows 7などでも.NET Framework 4.5がインストールされていればビルドできるはずだが、未確認)。


 プロジェクトファイルを置いたフォルダーでMSBuildを実行すれば、プログラムがビルドされる(次のコードと画像)。

> C:¥Windows¥Microsoft.NET¥Framework¥v4.0.30319¥MSBuild


コマンドプロンプトからMSBuildを起動するコマンド
パスの部分は、それぞれの環境に応じて変更してほしい(前回を参照)。
これはC#とVBで同じである(行頭の「>」はプロンプトなので、入力の必要はない)。
なお、プロジェクトファイルが同じフォルダーに複数ある場合は、この行の後ろにスペースを空けてプロジェクトファイル名を指定する。

コマンドプロンプトからビルドして実行する(Windows 8.1 Update 1)コマンドプロンプトからビルドして実行する(Windows 8.1 Update 1)
スタートボタンを右クリックして出てきたコンテキストメニューから[コマンド プロンプト]を選ぶと、コマンドプロンプトが開く。あるいは、スタートボタンを右クリックして出てきたコンテキストメニューから[ファイル名を指定して実行]を選び、表示されたダイアログに「cmd」と入力して[Enter]キーを押してもよい。
コマンドプロンプトでカレントディレクトリをソースコードの置いてある場所に移して、上のコマンドを入力し、[Enter]キーを押す(コマンドプロンプトの使い方については「これだけは覚えておきたいWindowsのコマンドプロンプトの使い方」を参照)。何もエラーが出ずにビルドに成功したら、プロジェクトファイルで指定したフォルダー(このフォルダーの下の「bin¥Release」フォルダー)に実行ファイルが生成されている(画像では警告が出ているが問題ない)。生成された実行ファイルをエクスプローラー上でダブルクリックすれば、この画像のようなウィンドウが表示されるはずである。

 さて、長々とプロジェクトファイルをご覧に入れたのは、「こんなものを手で書けるのか?」と感じてもらうためである。上に載せたプロジェクトファイルは、ごくごく小規模なものである。実際のプロジェクトファイルはこれより何倍も大きなサイズになるのだ(Visual Studioで作成したプロジェクトファイルの内容を確認してみてほしい)。また、プロジェクトファイルの書き方は、MSDNの「MSBuild リファレンス」に記載されているが、とても複雑なものである*4。手書きでゼロから書き起こすのはちょっと無理だと筆者は思っている。

 では、プロジェクトファイルを使ってMSBuildでビルドするのは無駄かというと、そんなことはない。MSBuildは無人で実行できるのだ(Visual Studioでも可能ではあるが、MSBuildを直接起動する方が速いだろう)。しかも、Visual Studioをインストールしなくてよいのである。ビルド専用のサーバーを構築するといったときに重宝するだろう。

 プロジェクトファイルは、Visual Studioで作成する。作成できたプロジェクトファイルを使って、ビルドサーバーではMSBuildを使う。そういった使い分けが有効だと思う。

MSBuildでプロジェクトをビルドするには?

 プロジェクトファイルのあるフォルダーでMSBuildを実行すればよい。

 上記のプロジェクトファイルの解説ですでに述べたが、プロジェクトファイルのあるフォルダーでMSBuildを起動するだけである。MSBuildは、そのフォルダー内でプロジェクトファイルを探し出して、自動的に実行してくれる。なお、同じフォルダー内に複数のプロジェクトファイルが存在する場合は、MSBuildに対する引数としてプロジェクトファイル名を指定する。

 MSBuildはOSに標準で含まれているので、Visual StudioをインストールしていなくてもC#/VBのプロジェクトからプログラムをビルドできる*5。ということは、例えば公開されているサンプルプロジェクトを、Visual Studioがインストールされていない環境でビルドできるのである。

*5 以下のような場合にはビルドできないこともあるのでご注意願いたい。

  • OSによってインストールされている.NET Frameworkのバージョンが異なる。プロジェクトファイルが要求するバージョンの.NET Frameworkがインストールされていないときは、ビルドできない。例えばWindows 8.xには.NET Framework3.5が入っていないので、.NET Framework3.5を必要とするプロジェクトはビルドできない(別途.NET Framework3.5をインストールすれば可能だ)。
  • プロジェクトファイルが、標準ではOSに含まれていないライブラリなどを指定していることがある。そのようなライブラリなどは、別途インストールしないとビルドできない。例えば筆者は、先日GitHubで公開されたMSBuildのソースコードを、Visual StudioをインストールしていないWindows 8.1 Update 1の環境でビルドしようと試みたが、「Microsoft.Build.Tasks.v12.0.dll」ファイルが存在しないというエラーが出て失敗した。このファイルはVisual Studio 2013をインストールすると入るものである(MSBuildのソースコードに含まれる「README.md」ファイルによれば、ビルドするにはVisual Studio 2015が必要だとされている)。

 実際に試してみよう。Windows 8.1 Update 1でビルドできるように、.NET Framework 4.0以降のWPFプロジェクトを探してみる(Windows 8.xに.NET Framework 3.5は入っていないため)。条件に合っていれば何でもよいのだが、ここでは「Simple Calculator」を使わせていただこう。

 サンプルをダウンロードするとZIPファイルになっているので、その中からプロジェクト一式を適当なフォルダーにコピーする。あとは、コマンドプロンプトでカレントディレクトリをプロジェクトファイルのあるフォルダーに移して、MSBuildを実行するだけである(次の画像)。

サンプルプロジェクトをコマンドプロンプトからビルドして実行する(Windows 8.1 Update 1)サンプルプロジェクトをコマンドプロンプトからビルドして実行する(Windows 8.1 Update 1)
スタートボタンを右クリックして出てきたコンテキストメニューから[コマンド プロンプト]を選ぶと、コマンドプロンプトが開く。あるいは、スタートボタンを右クリックして出てきたコンテキストメニューから[ファイル名を指定して実行]を選び、表示されたダイアログに「cmd」と入力して[Enter]キーを押してもよい。
コマンドプロンプトでカレントディレクトリをプロジェクトの置いてある場所に移して、次のコマンドを入力し、[Enter]キーを押す(コマンドプロンプトの使い方については「これだけは覚えておきたいWindowsのコマンドプロンプトの使い方」を参照)。

C:¥Windows¥Microsoft.NET¥Framework¥v4.0.30319¥MSBuild

パスの部分は、それぞれの環境に応じて変更してほしい。前回を参照のこと。


何もエラーが出ずにビルドに成功したら、プロジェクトファイルで指定されているフォルダー(この例ではプロジェクトのフォルダーの下の「bin¥Debug」フォルダー)に実行ファイルが生成されている。生成された実行ファイルをエクスプローラー上でダブルクリックすれば、この画像のようなウィンドウが表示されるはずである。
なお、この例ではビルド時に警告が出るが(画像で黄色い文字の部分)、無視してよい。

まとめ

 WindowsにはMSBuildというビルドツールが標準で含まれている。C#/VBのプロジェクトをコマンド一つでビルドできるのである。

 MSBuildを動かすためにはプロジェクトファイルが必要だ。ただし、プロジェクトファイルの書き方は難しいので、ゼロから手書きするのはあまり現実的とは言い難い。プロジェクトファイルは、Visual Studioで作成するか、そうやって作成したものを少し書き換える程度にしておくのがよいだろう。

 MSBuildを使えば、Visual Studioがインストールされていない環境でも、C#/VBのプロジェクトをビルドできる。そのような環境でサンプルコードを試してみたいとか、ビルド専用サーバーを構築したいといった用途に重宝するだろう。

.NET TIPS

Copyright© 1999-2015 Digital Advantage Corp. All Rights Reserved.