FSharp.Compiler.Service uses latest TargetFramework when compiling scripts rather than environment.
See original GitHub issueNot sure if this is a bug or a feature request.
I am using FSharp.Compiler.Service to compile user created F# scripts. Up until today, the code was working as expected however after I updated to .NET 7 the script compilation succeeds but attempting to load/reflect into the script fails with:
Could not load file or assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
After some investigation what seems to be happening is when FSharpChecker.Compile
is given an fsx file, it implicitly creates an fsproj file with the TargetFramework=net7.0
(based on the latest SDK installed?). The rest of my solution is targeting net6.0
so it can’t find the correct version of System.Runtime
.
Repro steps
A concise repro is not simple. The key parameters are described below.
let checker = FSharpChecker.Create()
// https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/compiler-options
let compilerArgs (scriptPath:string) (dllPath) =
[|
"-a"; scriptPath
$"-o:%s{dllPath}"
"--targetprofile:netcore"
"--target:library"
"--debug:full"
$"--compilertool:%s{Assembly.GetExecutingAssembly().DirectoryName}"
|]
let tryCompile scriptPath dllPath =
async {
let compilerArgs = compilerArgs scriptPath loadCtx.DllFullName
let! errors, retCode = checker.Compile(compilerArgs)
// omitted a bunch of code that handles copying of reference assemblies
let assembly = // ... code loads the dll into its own AssemblyLoadContext
let types = assembly.GetTypes() // calling this method throws the exception
As an attempted workaround I placed a global.json into the runtime directory:
{
"sdk": {
"version": "6.0.0",
"rollForward": "latestMinor"
}
}
Then with some scripts I get a compiler error. To cause this behaviour the script must have some dependencies to trigger the creation of a .fsproj on disk. #r "nuget: FSharp.Data, 5.0.2"
seems to be sufficient for this. Simple scripts produce the same System.Runtime exception from above.
C:\Path\To\main.fsx (2,1)-(2,31) parse error C:\Program Files\dotnet\sdk\6.0.306\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.TargetFrameworkInference.targets(144,5): error NETSDK1045: The current .NET SDK does not support targeting .NET 7.0. Either target .NET 6.0 or lower, or use a version of the .NET SDK that supports .NET 7.0. [C:\Path\To\bin\Projects\31412--0815da43-918d-4e85-baef-19d36d3e76bf\Project.fsproj]
Expected behavior
My initially expected behavior is that selecting a particular version of FSharp.Compiler.Service
(I tried with 41.0.6 and 41.0.7) corresponding to FSharp.Core
6.0.6 and 6.0.7 would set the TargetFramework=net6.0
and FSharp.Compiler.Service
42.7.1 would set the TargetFramework=net7.0
.
I would have also expected the compiler to consider the presence of global.json and set the TargetFramework based on that.
I searched extensively to see if there was some way to instruct FSharpChecker
on what TargetFramework to use e.g. with compiler args. Possibly there could be an overload to Compile
or new method added to FSharpChecker
which provides some direct control over the implicitly generated fsproj file.
Known workarounds
None tested. Expect that uninstalling the latest .NET so that only .NET 6 SDKs were present on the system would succeed. My update to .NET 7 happened as part of automatic updates to Visual Studio.
Related information
Provide any related information (optional):
- Operating system: Windows 10
dotnet --list-sdks
5.0.104 [C:\Program Files\dotnet\sdk] 6.0.111 [C:\Program Files\dotnet\sdk] 6.0.202 [C:\Program Files\dotnet\sdk] 6.0.203 [C:\Program Files\dotnet\sdk] 6.0.306 [C:\Program Files\dotnet\sdk] 7.0.100 [C:\Program Files\dotnet\sdk]- Editing Tools: Visual Studio 17.4.0
Issue Analytics
- State:
- Created 10 months ago
- Reactions:1
- Comments:11 (7 by maintainers)
Top GitHub Comments
Yes, this is definitely an issue.
The behavior generating default references does not do what is expected. I did a bunch of cleanup around that code a month or two ago, I may have broken something. Although it may also have been broken a lot longer than that.
Here is a complete straightforward repro: FCS_14289_Repro.zip
It produces this output:
System.Runtime should be 6.0.0.0 because of the presence of the global.json file with this specification:
@KevinRansom There seems to be a workaround to this issue, using a solution posted here: https://github.com/dotnet/fsharp/issues/14250