Visual Studio で作成した F# プロジェクトを Linux の xbuild でビルド


Linux/Mono 環境のビルドツールである XBuild は MSBuild といろいろ違って,単純に MSBuild でビルドできたプロジェクトが XBuild でビルドできるようになるとは限りません。 Visual Studio 2012 で作成した F# プロジェクト (.fsproj) もそのままではビルドできません。

ビルドが失敗する原因は, Import 要素の Condition で使われている Exists が働いてくれないために, Microsoft.FSharp.Targets が読み込まれないためです。そこで以前作成した NUnit プロジェクトファイルを修正するスクリプトを少し修正して, F# プロジェクトファイルを改変するスクリプトを作成します。

変更するのは editProject 関数のみです。

let editProject rawProjectXml =
   let project = XDocument.Parse rawProjectXml
   query {
      for import in project.Descendants (XName.Get ("Import", "http://schemas.microsoft.com/developer/msbuild/2003")) do
      let project = import.Attribute (XName.Get ("Project"))
      where (project.Value.EndsWith ("Microsoft.FSharp.Targets"))
      select (import.Attribute (XName.Get ("Condition")))
   }
   |> Seq.iter (fun attribute -> attribute.Remove ())
   project

プロジェクトファイル中に Import 要素は Microsoft.Common.props と Microsoft.FSharp.Targets の 2 つあります。 Microsoft.Common.props は Mono 環境では存在しないので無視して[A] Microsoft.FSharp.Targets の方のみ Condition 属性を取り除いてやります[B]

脚注

  1. Windows からコピーするという手段も考えられますが。 []
  2. プロジェクトファイル中の環境変数を展開できれば,実際にファイルが存在するかをチェックして属性値に bool 値を設定することもできるのでしょうが,方法がわからないので Condition を取り除く手段を選びました。そもそも Microsoft.FSharp.Targets が存在しないとビルドできないので,ここが false になっても困るのですが。 []