Как использовать F # на сервере CI при использовании нового автономного установщика для F # 3.1.1
Когда я создаю новый проект в 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)" />
На сервере CI это не создается, поскольку FSharpTargetsPath все еще пуст.
Мы используем новый автономный установщик для F # 3.1.1 на сервере CI и не устанавливаем там Visual Studio.
Что я должен добавить, чтобы сделать эту работу?
Ответы
Ответ 1
Мне кажется, что предложение select может быть неверным. Я бы подумал, что $(VisualStudioVersion)
будет пустым ", если не было установки визуальной студии. Однако $(FSharpTargetPath)
, который указывает на то, где я ожидаю, что файл автономных целей будет находиться. Очевидно, замена 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>
Отказ от ответственности: это чистая работа, поскольку я не на ПК, где я могу попробовать это.
Ответ 2
Это ошибка в установщике для 3.1.1.
Резюме
Это влияет только на установку чистой машины. Запустите script внизу, и все начнет работать, никаких изменений, необходимых для вашего проекта.
Подробнее
Начиная с VS 2013, шаблоны проектов F # содержат фрагмент Choose
, как вы указали в своем вопросе. Конструкция выглядит следующим образом:
-
Первоначальная проверка для VisualStudioVersion = 11.0
предназначена для поддержки back-compat с VS 2012: верьте или нет, новый проект VS 2013 F # откроется отлично как в VS 2012, так и в 2013 году, если вы настроите F # 3.0. Файл целей построения F # 3.0 используется, когда проект открыт в VS 2012 (aka version 11.0).
-
Идем дальше, мы не хотим быть в числе номеров и путей версии hardcoding в вашем файле проекта, поэтому второй случай представляет собой будущий механизм для потребления целей сборки. Этот случай указывает на файл shim для VS-версии, который не содержит ничего, кроме импорта файла "real" build target. Для 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 файла на самом деле, также и переносимый), просто запустите его из подсказки 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 }
Ответ 3
Мне требуется 3.1 в моих проектах, поэтому я удаляю этот блок выбора и просто добавляю свойство FSharpTargetsPath в верхней части страницы, см. SourceLink.fsproj. Это более простая версия того, что мы сделали для проектов FAKE, таких как FakeLib.fsproj.
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>