How to make F# projects which will work same on VS2010 / VS2013-preview?

815 views Asked by At

New F# projects comes with

  <Choose>
    <When Condition="'$(VisualStudioVersion)' == '11.0'">
      <PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
        <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
      </PropertyGroup>
    </When>
    <Otherwise>
      <PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
        <FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
      </PropertyGroup>
    </Otherwise>
  </Choose>
  <Import Project="$(FSharpTargetsPath)" />

msbuild just fails with it so I even can't write an build script based on this project file.

My solution:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0\FSharp\Microsoft.FSharp.Targets" />

I set v12.0 instead of $(VisualStudioVersion) because VisualStudioVersion is 11 for my msbuild. So but this breaks compatibility with other Visual Studio versions.

I guess I need to make something alike

<FSharpTargetsPath Condition="'$(VisualStudioVersion)' == '11.0'">$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>

and

<FSharpTargetsPath Condition="'$(VisualStudioVersion)' == '12.0'">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>

But that even doesn't look alike good solution. Is there proper way?

Also I have problems with running 3.0 F# compiler fsc.exe and software alike FAKE :

Could not load file or assembly FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies

So how to not break compatibility between 3.0 / msbuild and 3.1 and newer VS2013-preview stuff ?

2

There are 2 answers

0
knocte On BEST ANSWER

The more specific answer that I guess Danny should have given is:

<PropertyGroup Condition="'$(FSharpTargetsPath)' == '' OR (!(Exists('$(FSharpTargetsPath)')))">
  <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(FSharpTargetsPath)' == '' OR (!(Exists('$(FSharpTargetsPath)')))">
  <FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(FSharpTargetsPath)' == '' OR (!(Exists('$(FSharpTargetsPath)')))">
  <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\4.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(FSharpTargetsPath)' == '' OR (!(Exists('$(FSharpTargetsPath)')))">
  <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(FSharpTargetsPath)' == '' OR (!(Exists('$(FSharpTargetsPath)')))">
  <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<Import Project="$(FSharpTargetsPath)" />

This should work with all versions.

1
Danny Tuppeny On

I would start by creating projects in both versions and diffing the project files. If you build a project file that contains the superset of both files, with appropriate Condition attributes so that each version of VS reads the correct parts, in theory it should work.

Related Questions in F#

Related Questions in F#-3.1