使用F#3.1.1的新独立安装程序时,如何在CI服务器上使用F#

for*_*i23 11 msbuild f# f#-3.0

当我在Visual Studio中创建一个新项目时,它在fsproj文件中包含以下行:

  <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)" />
Run Code Online (Sandbox Code Playgroud)

在CI服务器上,由于FSharpTargetsPath仍为空,因此无法构建.我们在CI服务器上使用F#3.1.1的新独立安装程序,并且没有安装Visual Studio.我需要添加什么才能使其工作?

Col*_*ull 8

在我看来,choose子句可能实际上是不正确的.$(VisualStudioVersion)如果没有可视工作室安装,我会认为这将是空的.然而,$(FSharpTargetPath)这指向我期望独立目标文件驻留的位置.很明显,将3.1换成3.0.见下文.

  <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>
Run Code Online (Sandbox Code Playgroud)

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


lat*_*kin 7

这是3.1.1安装程序中的错误.

摘要

这仅影响清洁机器安装.在底部运行脚本,事情将开始工作,不需要对项目进行任何更改.

细节

从VS 2013开始,F#项目模板包含Choose您在问题中提供的代码段.设计如下:

  • 最初的检查VisualStudioVersion = 11.0是针对VS 2012的back-compat支持:不管你信不信,一个新的VS 2013 F#项目将在VS 2012和2013中正常开放,前提是你的目标是F#3.0.在VS 2012(aka版本11.0)中打开项目时,将使用F#3.0构建目标文件.

  • 展望未来,我们不希望在项目文件中使用硬编码版本号和路径,因此第二种情况代表了使用构建目标的未来机制.此案例指向每个VS版本的填充程序文件,该文件只包含"真实"构建目标文件的导入.对于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安装程序错误地将shim文件放入"检测到VS时仅部署"桶中.因此,一个干净的构建服务器上,虽然"真正的"目标文件安装(这是在"始终部署"桶),垫片是不是和你捣毁建立与默认模板.:-(

解决方法

编辑项目文件以便直接消耗真实目标是完全有效的.这会奏效.但我想说首选的解决方法是自己创建填充文件.

要自己创建丢失的填充程序文件(实际上是2个文件,也有一个可移植文件),只需从admin 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 }
Run Code Online (Sandbox Code Playgroud)