dotnet / dotnet/fsharp

FSharp.Compiler.Service uses latest TargetFramework when compiling scripts rather than environment.

Open
#14,289 11 comments 1 reaction 0 assignees View on GitHub
Bug Impact-Medium
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 22h
Merged PRs (30d)
144

Description

Not 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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.