I have a VS 2010 mixed-language solution that's primarily C#, but contains a windows service written in F#. I've had this building with xbuild in the in a parallel environment, but since upgrading to the packaged version of mono 2.10.5 from badgerports I've been unable to get it working.
The error I typically encounter is:
/home/alex/git/Solution/FSProject/FSProject.fsproj: error : Target named 'Build' not found in the project.
What puzzles me is that looking at the project file, it doesn't appear that ANY targets are defined. I'm far from an expert on MSBuild, but this seems a bit strange to me. That being said, it did work previously.
Has anyone run into (and hopefully found the solution for) similar issues? If possible I'd like to be able to build the solution with xbuild and from Visual Studio.
Environment is mint 11 (not sure if this is based on ubuntu maverick or natty) running mono 2.10.5 from badgerports. fsharp was installed from latest source to the default prefix.
edit
I've been able to get a little closer thanks to Brian's pointer (I did have to hard-code a path, xbuild seems to have trouble resolving things like "$(MSBuildExtensionsPath32)..\FSharp\1.0\Microsoft.FSharp.Targets"). FSC is actually getting called now, though it's complaining that it's unable to resolve the reference to FSharp.Core.
I found this page F# and XBuild (Debian) helpful in getting this far.
There's no need for hackery anymore if you use this:
- Mono 3.0.0 or newer. (My change was merged here.)
- FSharp tag 3.0.26 (or newer) on github (My change was merged here.).
So it turns out that the parallel environment was actually making things easier on me. Mono installs at /usr, while F# installs at /usr/local, so I needed to set up symlinks to enable FSharp targets and Common targets to see each other. This is detailed here: F# and XBuild (Debian)
Once this was set up, I was still having trouble. After adding some debug messages I found that xbuild was not resolving the path to F# targets correctly. Project file was trying to import like this:
<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
and xbuild was having trouble resolving the relative path. So I just changed it to this:
<Import Project="$(TargetsPath)" Condition="$(TargetsPath) != ''" />
<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="$(TargetsPath) == '' And !Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="$(TargetsPath) == '' And Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
which allows me to passin the path to FSharp.targets on the command line.
There are still a few problems (it's failing with a complaint about ItemGroups not being registered, I know this is a weakness in xbuild but it seems to be a false alarm - the project does in fact get built and run successfully). Hope this helps someone else.