2014-01-23 16 views
10

当我在Visual Studio中的一个新项目,它包含了fsproj文件中以下行:如何使用新的独立安装F#的时候使用F#CI服务器3.1.1

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

在CI服务器,因为FSharpTargetsPath仍然是空的,所以不会生成。 我们在CI服务器上使用新的standalone installer for F# 3.1.1,并且没有安装Visual Studio。 为了完成这项工作,我需要添加些什么?

回答

8

它看起来像我选择子句可能实际上是不正确的。如果没有安装Visual Studio,我会认为$(VisualStudioVersion)是空的。然而指向$(FSharpTargetPath)的地方是我期望独立目标文件驻留的地方。显然,换一个3.0的3.0换一个3.1。见下文。

<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> 
     <PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets')"> 
     <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath> 
     </PropertyGroup>   
    </Otherwise> 
    </Choose> 

免责声明:这是纯粹的猜测工作,因为我又不是在PC,我可以试试这个。

+0

谢谢!这对我来说是一个很大的帮助。我想在使用FAKE时使用3.0,使用VS 2012使用3.0,使用VS 2013使用3.1,并且我认为我已经使用这些指令进行了整理。 – lefthandedgoat

6

这是3.1.1安装程序中的一个错误。

摘要

这会影响只有干净的机器安装。在底部运行脚本,事情就会开始工作,无需对项目进行任何更改。

详细

由于VS 2013,F#项目模板包含Choose片断,你已经在你的问题中。设计如下:

  • VisualStudioVersion = 11.0初步检查是在VS 2012背compat的支持:无论你相信与否,新的VS 2013的F#项目将同时在VS 2012中打开罚款和2013年提供你瞄准F#3.0。在VS 2012中打开项目时(也就是版本11.0),将使用F#3.0构建目标文件。展望未来,我们不希望在您的项目文件中对版本号和路径进行硬编码,因此第二种情况代表了消耗构建目标的未来机制。这种情况指向每个VS版本的shim文件,其中除了导入“真实”构建目标文件外没有任何内容。对于VS 2013(又名12.0),$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets是3行,只需输入真实目标$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets。使用这种方法,当新的VS版本发布时,您的项目文件不需要使用新版本和路径进行更新。您的项目会自动找到与您使用的任何版本的VS匹配的填充文件,并且该填充文件将指向该VS版本中支持的相应“真实”目标。

这就是所有超级neato,除了3.1.1安装程序错误地将垫片文件放在“只检测VS时检测”桶中。因此,在干净的构建服务器上,尽管安装了“真实”目标文件)(它位于“始终部署”存储区中),但垫片不是,而且您将使用默认模板构建。:-(

解决方法

这是完全有效的编辑您的项目文件,以便它直接消耗的真正目标。这将工作,但我要说首选的解决方法是只需创建垫片自己的文件。

要创建缺少的垫片文件(实际上是2个文件,还有一个便携式的)自己,略低于从管理的PowerShell提示符下运行:

$shimDir = "${env:ProgramFiles(x86)}\MSBuild\Microsoft\VisualStudio\v12.0\FSharp" 
mkdir $shimDir | out-null 

$shimFormat = @' 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft{0}.FSharp.targets" /> 
</Project> 
'@ 

'','.Portable' |%{ ($shimFormat -f $_ -split '\n') | out-file "$shimDir\Microsoft$_.FSharp.targets" -encoding ascii } 
+1

感谢您的详细解答。 “首选解决方法”的问题是我没有真正访问CI服务器的权限。我所能做的只是希望管理员安装安装程序。 – forki23

+0

即使有这个修复,我在单声道上也有同样的问题https://travis-ci.org/fsharp/FAKE/builds/17504786 – forki23

1

我需要3.1在我的项目中,所以我删除了选择块,只需在顶部附近添加一个FSharpTargetsPath属性,请参阅SourceLink.fsproj。这是我们为0123KE等FAKE项目所做的更简单的版本。

<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>