Closed isaacabraham closed 6 years ago
The only way I've managed to actually get VS to build is to upgrade to FSharp.Core 4.1.
@isaacabraham Can you add the project file for services?
Thanks Kev - it's here. I've removed the names of the .fs files in the main ItemGroup but otherwise this is it.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Name>Services</Name>
<AssemblyName>Services</AssemblyName>
<RootNamespace>Services</RootNamespace>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>e1197e5c-68e4-4117-a89b-c081d4f1f55f</ProjectGuid>
<OutputType>Library</OutputType>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>false</Optimize>
<Tailcalls>false</Tailcalls>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<DocumentationFile>bin\Debug\Services.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Choose>
<When Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\4.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\4.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<ItemGroup>
<None Include="Script.fsx" />
<None Include="paket.references" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Drawing" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Transactions" />
</ItemGroup>
<Import Project="..\..\.paket\paket.targets" />
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v2.0'">
<ItemGroup>
<Reference Include="FSharp.Core">
<HintPath>..\..\packages\FSharp.Core\lib\net20\FSharp.Core.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="FSharp.Core">
<HintPath>..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="System.Data">
<Paket>True</Paket>
</Reference>
<Reference Include="System.Xml">
<Paket>True</Paket>
</Reference>
<Reference Include="FSharp.Data.SqlClient">
<HintPath>..\..\packages\FSharp.Data.SqlClient\lib\net40\FSharp.Data.SqlClient.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="ImageProcessor">
<HintPath>..\..\packages\ImageProcessor\lib\net45\ImageProcessor.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.ApplicationInsights">
<HintPath>..\..\packages\Microsoft.ApplicationInsights\lib\net45\Microsoft.ApplicationInsights.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="System.Net.Http">
<Paket>True</Paket>
</Reference>
<Reference Include="System.Net.Http.Formatting">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.Azure.KeyVault.Core">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core\lib\net45\Microsoft.Azure.KeyVault.Core.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.Azure.Search">
<HintPath>..\..\packages\Microsoft.Azure.Search\lib\net45\Microsoft.Azure.Search.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.Data.Edm">
<HintPath>..\..\packages\Microsoft.Data.Edm\lib\net40\Microsoft.Data.Edm.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.Data.OData">
<HintPath>..\..\packages\Microsoft.Data.OData\lib\net40\Microsoft.Data.OData.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.Data.Services.Client">
<HintPath>..\..\packages\Microsoft.Data.Services.Client\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="System.Net">
<Paket>True</Paket>
</Reference>
<Reference Include="System.Net.Http.WebRequest">
<Paket>True</Paket>
</Reference>
<Reference Include="System.Runtime.Serialization">
<Paket>True</Paket>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime">
<HintPath>..\..\packages\Microsoft.Rest.ClientRuntime\lib\net45\Microsoft.Rest.ClientRuntime.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.Rest.ClientRuntime.Azure">
<HintPath>..\..\packages\Microsoft.Rest.ClientRuntime.Azure\lib\net45\Microsoft.Rest.ClientRuntime.Azure.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.Spatial">
<HintPath>..\..\packages\Microsoft.Spatial\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Microsoft.SqlServer.Types">
<HintPath>..\..\packages\Microsoft.SqlServer.Types\lib\net40\Microsoft.SqlServer.Types.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v2.0'">
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\packages\Newtonsoft.Json\lib\net20\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\packages\Newtonsoft.Json\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v2.0' Or $(TargetFrameworkVersion) == 'v4.5.2')">
<ItemGroup>
<Reference Include="NReco.PdfGenerator">
<HintPath>..\..\packages\NReco.PdfGenerator\lib\net20\NReco.PdfGenerator.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v2.0' Or $(TargetFrameworkVersion) == 'v4.5.2')">
<ItemGroup>
<Reference Include="SendGrid">
<HintPath>..\..\packages\Sendgrid\lib\SendGrid.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
<Reference Include="SendGridMail">
<HintPath>..\..\packages\Sendgrid\lib\SendGridMail.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="SendGrid.SmtpApi">
<HintPath>..\..\packages\SendGrid.SmtpApi\lib\net40\SendGrid.SmtpApi.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="System.Spatial">
<HintPath>..\..\packages\System.Spatial\lib\net40\System.Spatial.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
<ItemGroup>
<Reference Include="System.Xml.Linq">
<Paket>True</Paket>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage">
<HintPath>..\..\packages\WindowsAzure.Storage\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
</Project>
Just a small addendum - a full solution rebuild does still work in VS2015. But if you try a solution rebuild in VS2017 and then try to build the C# project (even from VS2015), it fails. It's as if the F# project is somehow being built linked against F#4.1 even though the referenced FSharp.Core is 4.0.
I think you are hitting https://github.com/Microsoft/visualfsharp/issues/2399 - do you reference a type-provider in your F# project?
Edit: It looks like you use FSharp.Data.SqlClient
? Afaik, the only way to fix this, as you noticed, is to upp the version of FSharp.Core...
@isaacabraham
open a vs command window, and run msbuild in the services directory. Scroll back through the output spew and find the compile options. it is similar to the below. Can you see if there is an -r: for fsharp.core.dll it should look similar to this:
-r:c:\kevinransom\ProjectScaffold\packages\FSharp.Core\lib\net40\FSharp.Core.dll
Please let me know if there is one. My intuition is that for the Services dll it is missing.
C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\fsc.exe -o:obj\Debug\Services.dll
-g
--debug:full
--noframework
--define:DEBUG
--define:TRACE
--doc:bin\Debug\Services.XML
--optimize-
--tailcalls-
-r:c:\kevinransom\ProjectScaffold\packages\FSharp.Core\lib\net40\FSharp.Core.dll
-r:C:\Program Files (x86)\Microsoft SQL Server\130\SDK\Assemblies\Microsoft.SqlServer.Types.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\mscorlib.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Core.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Data.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Net.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Net.Http.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Net.Http.WebRequest.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Numerics.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Runtime.Serialization.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Xml.dll
-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Xml.Linq.dll
--target:library
--warn:3
--warnaserror:76
--fullpaths
--flaterrors
--subsystemversion:6.00
--highentropyva+
Library.fs
C````
If there is an explicit reference to:
Then the issue is likely as @0x53A says the TypeProvider.
@KevinRansom Here's a snippet of output (taken from VS2017 command prompt): -
CoreCompile:
C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\fsc.exe -o:obj\Debug\Services.dll
-g
--debug:full
--noframework
--define:DEBUG
--define:TRACE
--doc:bin\Debug\Services.XML
--optimize-
--tailcalls-
-r:C:\Users\Isaac\Source\Repos\project\packages\FSharp.Core\lib\net40\FSharp.Core.dll
So it is there. I'm not sure if this means it's the same as #2399 or not though - your first comment suggest that that's not the case but your second implies it is :-)
Note that even in the VS2015 command prompt I see the -r
for FSharp.Core.
So the build and compiler are referencing the correct FSharp.Core.dll. So the likely culprit is using a type that references the latest FSharp.Core.dll. The most likely cause is a bug in the TypeProvider. It worked as you expected in earlier versions of the FSharp.Compiler because of a bug in the Compiler that has been fixed.
The fix is to correct the issue in the TP ...
Kevin
The provided types file for that TP looks quite old. Perhaps someone familiar with the TP should try and fix the FSharp.Core types that it returns to the compiler.
@isaacabraham
I think this is a by design … It is an instance of where imported references were not unifying upwards. We have to have this behavior for two reasons:
Someone needs to work with the SqlProvider maintainers to fix the issue in their type provider. I would try to take a look at it, but I kind of have a thousand other things to do right now. As I am sure does everyone else …
I do think there is, an F# compiler bug here too and that is we don’t issue an error message that the developer hasn’t referenced the unified version of the impacted assembly. However, that still wouldn't make this work.
There are tools in providedtypes.fs that enable a TP developer to pass back to the compiler the correct types for the references passed to the compiler. However, a lot of care is required and it is easy to get it wrong.
@dsyme thoughts?
@KevinRansom @isaacabraham I do believe the type provider may need to be updated to be a multi-targeting type provider, by making use of ProvidedTypesContext
here: https://github.com/fsprojects/FSharp.TypeProviders.StarterPack/blob/master/src/ProvidedTypesContext.fs
This is non-trivial and, given the fairly sophisticated nature of that type provider, it may expose further issues.
@dsyme @KevinRansom ok - thanks for explaining that :-) So what are the options going forward?
Someone updates the TP - sounds like a bit of effort but doable. I imagine only people that are using VS2017 / F#4.1 will be motivated to do this, but given the difficulty of working with TPs, this could be an issue for users of the TP.
Some change to allow the "old" behaviour? Or is that not possible / undesirable?
What is the impact of this issue vis-a-vis TPs in general - is it going to affect all of them? Just certain ones? Because of the spurious nature of this error I can see lots of people raising false positives about this.
I don't understand that much of this, but I do see similarities with an issue (or issues, it begins to look like) that I reported on Stackoverflow some time ago, and found a solution for. @isaacabraham, perhaps you can have a look at it and see if what I found can be of any help. Also, anybody, should I report that issue here?
Link to the issue on Stackoverflow: "Cannot resolve dependency to assembly FSharp.Core 4.4.1.0 when using VS 2017" http://stackoverflow.com/questions/42665926/cannot-resolve-dependency-to-assembly-fsharp-core-4-4-1-0-when-using-vs-2017
@BentTranberg Could be, but that looks more like a more run-of-the-mill binding redirects error to me.
@isaacabraham from my limited experience, this affects every type provider I have used, and will likely affect most others.
While I was trying to do my part by researching the behavior and providing more info for #2399, I found that I was able to create a provided property that returns an empty string or calls functions without any problems, but as soon as the property getter body uses anything specific to F#, even just the |>
operator, the compiled binary points to the newer FSharp.Core again.
This is just my assumption, but I doubt many type providers were written with the intent to completely avoid all F# features in the provided members, and as @dsyme pointed out here, the solution to this is not well-documented.
@amazingant. Yes if you pass back a type from the ambient FSharp.Core.dll which is super easy to do. Then the F# compiler is going to say ... oh I have a reference to FSharp.Core.dll version 4.4.1.0. Now all references to FSharp.Core in generated code will now use the higher version number and the referenced assembly will be to FSharp.Core version 4.4.1.0.
@KevinRansom as I mentioned, I was able to trigger this behavior by just using an F# operator within a provided property getter.
@dsyme is there a well-documented fix for this that could be applied to type providers for this? Or is it essentially "you must upgrade to FSharp.Core 4.1"?
@isaacabraham My understanding is that the fix is to make the relevant type provider be a cross-targeting type provider. https://github.com/fsprojects/FSharp.TypeProviders.StarterPack#the-providedtypes-api---cross-targeting-type-providers. That's why the bug is currently labelled as external.
Closing as this has a solution that is external to this repo
I have a solution that was created in VS2015 with two projects: -
Services
, which targets F#4.0.Both have a paket reference to
FSharp.Core
4.0.0.1
.The solution builds fine in VS2015, yet having installed VS2017 I now get the following error whenever I try to build the C# application in VS2017: -
Error CS1705 Assembly 'Services' with identity 'Services, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' uses 'FSharp.Core, Version=4.4.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' which has a higher version than referenced assembly 'FSharp.Core' with identity 'FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
.This is on a fresh VS2017 install with latest F# Nightly tools. The only way I can get it to build is through MSBuild directly in a FAKE script.