MSBuild のインラインタスクを F# で書こう


MSBuild のプロジェクトファイルには直接コードを記述してインラインタスクを定義することができます。これを F# で書けるようにするのが今回のお題です。

インラインタスクは CodeDom の仕組みを利用しています。具体的には CodeDomProvider.CreateProvider を呼んで Code 要素の Language 属性の言語の CodeDomProvider のインスタンスを作成します。したがって F# の CodeDom プロバイダーが .NET Framework により認識される必要があり,これを達成すれば上記のように F# でインラインタスクが書けるようになります。

まずは F# の CodeDom プロバイダーの入手です。 F# の CodeDom プロバイダーはデフォルトでは提供されず, F# PowerPack に同梱されています。これをダウンロードしてインストールします。

インストーラーでインストールしても CodeDom プロバイダーを含むアセンブリーは GAC にインストールされないため, gacutil により手動でインストールする必要があります。

gacutil.exe /i "C:\Program Files (x86)\FSharpPowerPack-4.0.0.0\bin\FSharp.Compiler.CodeDom.dll"

さらに CodeDom で F# のプロバイダーが提供されていることを .NET Framework に教えてやる必要があります。 C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config の configuration 要素内に以下のような system.codedom 要素を追加してやります。

<system.codedom>
   <compilers>
      <compiler
         language="f#;fs;fsharp"
         extension=".fs"
         type="Microsoft.FSharp.Compiler.CodeDom.FSharpCodeProvider, FSharp.Compiler.CodeDom, Version=4.0.0.1, Culture=neutral, PublicKeyToken=f536804aa0eb945b"
         compilerOptions=""
         warningLevel="1" />
   </compilers>
</system.codedom>

type 属性に与える CodeDom プロバイダーの型はアセンブリー修飾名です。

以上で準備が完了です。以下のようなプロジェクトファイルをビルドできるはずです。

<?xml version="1.0" encoding="Shift_JIS" ?>
<Project DefaultTargets="Test" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <UsingTask TaskName="DoTest" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
      <Task>
         <Code Type="Fragment" Language="fs"><![CDATA[
printfn "%s" "こんにちは,世界!"
]]></Code>
      </Task>
   </UsingTask>
   <Target Name="Test">
      <DoTest />
   </Target>
</Project>

「こんにちは,世界!」と出力されれば成功です。