-
Notifications
You must be signed in to change notification settings - Fork 318
fix https://github.com/fsharp/FSharp.Compiler.Service/issues/721 #675
Conversation
I don't really know what the right thing to do here is. The TargetFrameworkVersion is the target for which we are generating code, and is independent of whether you want to run the F# compiler using .NET Core or .NET Framework. The way you run the compiler is just orthogonal, though 99% of the time TargetFrameworkVersion is a fine guess. I suppose it just depends whether you have .NET Core or .NET Framework available on your machine. I don't know how to determine that. This is why Roslyn ended up with two packages, just pushing the problem up another level. The world keeps being bifurcated. It's very difficult to stop but we need to try @enricosada Do you have any ideas here? I like the idea of a unified package but I don't see any good guidance on working out which is the preferred compiler toolchain |
@dsyme is right, one thing is target fw, other is current runtime of msbuild. we discussed a bit that in dotnet/netcorecli-fsc#75 for another stuff. you should check |
About choose toolchain (use fsc full, fsc netcore, fsc full on mono) in same fsproj. Atm if you run with Idea is instead of use orrible properties like <AvaiabileFscTool Include="$(MSBuildThisFileDirectory)netcoreapp1.0/fsc.dll">
<Runtime>netcoreapp1.0</Runtime>
<RuntimeType>Core</RuntimeType> <!-- so i know if i need to prefix `dotnet` -->
</AvaiabileFscTool>
<AvaiabileFscTool Include="$(MSBuildThisFileDirectory)/net45/fsc.exe">
<Runtime>netcoreapp1.0</Runtime>
<RuntimeType>Full</RuntimeType> <!-- no prefix, or `mono` if not windows -->
</AvaiabileFscTool> in the fsproj, user can choose to add that's the idea for So on Obv a good |
so that it automatically overrides the in-box F# compiler
</PropertyGroup> | ||
|
||
<Choose> | ||
<When Condition="('$(MSBuildRuntimeType)' != '') AND ('$(MSBuildRuntimeType)' != 'Full')"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use check " `$(MSBuildRuntimeType)' == 'Core' "
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh that's great to know, thanks @enricosada !
@dsyme obv the part about |
<!-- specific netcoreapp1.0 fsc --> | ||
<FscTaskAssemblyPath_netcoreapp1_0>$(MSBuildThisFileDirectory)netcoreapp1.0/FSharp.Build.dll</FscTaskAssemblyPath_netcoreapp1_0> | ||
<FscToolFullPath_netcoreapp1_0>$(MSBuildThisFileDirectory)netcoreapp1.0/fsc.dll</FscToolFullPath_netcoreapp1_0> | ||
<FscToolPath_netcoreapp1_0>$(MSBuildThisFileDirectory)netcoreapp1.0</FscToolPath_netcoreapp1_0> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove that FscToolPath_netcoreapp1_0
, i know is a good refactor, but i added FscToolFullPath_netcoreapp1_0
because i had no other way to save paths at the time.
i prefer if you can duplicate the paths in following properies, instead of pollute msbuild with unused properties. these should be labelled also as private with _
prefix because is something who will change. but no need to change that now, another pr will do with final design
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed FscToolPath
and prefix the other two with _
. Should I also remove the other two instead?
Ah, I didn't realise at the start that the distinction is for fsc runtime, not code generation target. Now things make a bit more sense. I am currently rerunning the VS Setup so that I can also test this with net core. |
@0x53A like that seems ok. should work for your use case, i think the old target doesnt use @dsyme i need to try this PR locally before merge. |
@enricosada Thank you for your help! One other issue is the While our nuget also includes the Microsoft.FSharp.Targets, it isn't really possible to overwrite it due to the way the defaul fsproj is structured: When installing the nuget, the props file is included at the top, but the current fsproj include it like this: <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)" /> So without manually modifying the fsproj, there is no way to override the .targets from this nuget. This is an issue for example if there is a new compiler parameter. |
Roslyn bifurcated afaik because they bundle the csc inside two different stuff (dotnetcli and VS), so was easier just use two packages :D |
I don't think there's any way to fix it - the user just has to edit the project file by hand, don't they? However I would love if someone would go fix this stuff at the root core of the problem - i.e. the templates that are included in the Visual F# Tools - and just make sure that the targets path is at least defined by a variable (or some other fundamental fix). The fact that so many F# project files unavoidably rely on a machine-path installed set of F# targets is really storing up trouble for the long term |
@dsyme The easiest way would be to only set the path inside the fsproj if it is not already set. Do you have a hook inside VS where such a transformation could be applied on opening the project? |
For example simply changing to this:
so as not to override an existing |
@dsyme i dont think is possibile to fix that with old fsprj, the whole sdk was using hardcoded paths or relative to sdk/extensions dir. Is risky, for what? you cannot change old templates.. Yes you can change the the new fsproj fix that. there is no need anymore to worry about. |
@enricosada so I should NOT try to set the targets file in this nuget? Then I will revert 0c70c11 |
That's fine once we update the Visual Studio .NET Framework templates to use the new .fsproj. (However Microsoft might not do that for .NET Framework tempaltes because they may want to maintain VS2017 --> VS2015 compat, so projects created with VS2017 can be edited by teams using VS2015 as long as they don't use F# 4.1 features - I'm not sure).
Yes, agreed, though editing the templates to check if FSharpTargetsPath is already set seems harmless |
This reverts commit 0c70c11.
@0x53A I think setting |
Ah yes, chaning VS2017 old fsproj templates, yes :D |
@enricosada Do you agree it is OK to set this? Even if it is ignored/overridden? Seems ok to me |
Yes, sry, i checked. i remembered things incorrectly |
@enricosada Ah I see. But regardless should't the setting of FSharpTargetsPath be conditional on the .NET Framework build/compile toolchain, i.e. only set it when when this is false?
Do we expect to be able to process existing F# projects with the .NET Core build toolchain? |
Wouldn't setting FSharpTargetsPath be conditional on the TargetFramework, not on the MSBuildRuntimeType? |
no, becasue new fsproj can build all frameworks, you cannot rely on TargetFramework, example `net451. Let me see if i can find a msbuild property about new sdk vs old |
Yes that's what we need. |
Ah yeah... So we have: old SDK vs new SDK |
yes.
that's the usual (full/pcl), but now there is also netstandard1.6, or netcoreapp1.0 for example
yes, because exists |
So, i have better memory than expected. And yes, i use But checking new sdk 1.0.1, i see no more that, just targets for new code. i think they just abandoned the idea maybe. I chcked dotnet/sdk but i lost atm :D @dsyme @0x53A maybe we should do that in another PR? @dsplaisted @eerhardt there is a way to know if the target is execute in new sdk (with |
@enricosada So you're saying we should not set |
Isn't the targets file coupled to the actual version of fsc used? |
This reverts commit 951cd29.
is tied more to fsc task used and sdk used. fsc args are stable, and retro compatible afaik.
that's better, or give me some time to test, i dont want to break things 😄 |
Well, as long as the SDK is also on nuget, it doesn't really matter if the targets file is in the sdk nuget or in the FSharp.Compiler.Tools nuget, since you can just update both. =) The current problem is that it uses the targets from the installed visual studio. |
I have created a new issue for FSharpTargetsPath: #676 |
@0x53A Could you please also add notes in the README.md about how to add the FSharp.Compiler.Tools to an existing project as part of this PR, mentioning the FSharpTargetsPath issue? Thanks! |
I have added a note to fsharp/fsharp about the issue with the targets file, and also added a quick note that the package exists (e.g. for use on a buildserver) to visualfsharp. |
Officially there isn't a way yet. See dotnet/sdk#534 Unofficially, there are ways to accomplish this. One way (again not officially supported) is how the targets in .NET Standard are doing it: https://github.com/dotnet/standard/blob/master/Microsoft.Packaging.Tools/tasks/targets/Microsoft.Packaging.Tools.targets#L11-L12 |
No the one in this repo - they are additive - they haven't yet been merged (some of the last remaining changes) |
thx for info @eerhardt ! |
ref fsharp/fsharp-compiler-docs#721