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>
「こんにちは,世界!」と出力されれば成功です。