如何制作能够在VS2010和VS2013-preview上同样运行的F#项目?

7
新的 F# 项目带有:
  <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无法成功构建此项目文件,因此我甚至无法编写基于此项目文件的构建脚本。

我的解决方案:

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

我将v12.0替换为$(VisualStudioVersion),因为我的msbuild的VisualStudioVersion是11。但这会破坏与其他Visual Studio版本的兼容性。

我想我需要做类似的事情。

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

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

但这甚至看起来都不是一个好的解决方案。有没有更好的方法?
我也遇到了运行3.0 F#编译器fsc.exe和类似软件FAKE的问题:
“无法加载文件或程序集FSharp.Core,版本=4.3.0.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a'或其某个依赖项。”
那么如何在3.0 / msbuild和3.1及更高版本的VS2013-preview之间不破坏兼容性呢?

1
VS2013项目应该与VS2012向后兼容,但是VS2012项目需要一次性升级才能实现这一点。如果您已经将VS2012项目升级到VS2013,但之后无法在VS2012上构建它,请报告此问题,以便在VS2013 RTM中修复。 - Jack P.
关于VS2010呢?我没有VS2012来测试这个<Choose>在那里是否有效。 - cnd
我不知道。VS2013预览版公告没有提到VS2010,所以我认为这意味着你不会(轻松地)能够创建适用于所有三个版本的项目文件。 - Jack P.
2个回答

2
我猜Danny应该给出更具体的答案,如下:

更具体的答案是:

<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)" />

这应该适用于所有版本。

0
我会先创建两个版本的项目,然后比较这些项目文件。如果你构建一个包含两个文件的超集的项目文件,并使用适当的Condition属性,以便每个VS版本读取正确的部分,理论上它应该可以工作。

我只是希望这个建议能够奏效,但由于一些事情发生了变化,我现在无法确认它是否有效。VS2013已经发布,我没有安装2012版本,所以我甚至无法亲自验证这个问题。 - cnd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接