【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

Windows上のXamarin StudioでF#プロジェクトをビルド

Windows上のXamarin StudioでF#プロジェクトをビルドしようとすると、最近のバージョンでは失敗します。

Xamarin Studio F# Language Binding 結果
4.0.12 3.2.15 OK
4.0.13 3.2.15 ビルドに失敗しました。. MSBuild operation failed
4.0.13 3.2.19 ビルドに失敗しました。. MSBuild operation failed

本体とアドインの組み合わせから推測すると、どうやら本体側の仕様変更が影響しているようです。

【追記】この件に関して、既にgithubのプロジェクトIssueが上がっていました。

4.0.12ではXamarin Studioからfscを直接呼んでビルドしていましたが、4.0.13ではmsbuildを使うように変更されたようです。

Xamarin Studioでは詳しいエラーメッセージが出て来ないので直接msbuildを呼んでみます。

> msbuild
(中略)
MSB4019: インポートされたプロジェクト
"C:\Program Files (x86)\Microsoft F#\v4.0\Microsoft.FSharp.Targets"
が見つかりませんでした。
<Import> 宣言のパスが正しいかどうか、
およびファイルがディスクに存在しているかどうかを確認してください。

確かにこのパスにはファイルが存在しません。

このプロジェクトをVisual Studioで読み込むと修正してくれました。複数の候補を条件指定しています。

修正前
  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" />
修正後
  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets'))" />
  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (!Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets'))" />

この部分を手動で修正することで Xamarin Studio 4.0.13 + F# Language Binding 3.2.19 でもビルドできるようになりました。