From 3c0782510708cc8d2dfc34c0f9f7824548152305 Mon Sep 17 00:00:00 2001 From: Pierre Chalamet Date: Tue, 10 Nov 2026 19:52:33 +0100 Subject: [PATCH] chore: upgrade FScript to .NET 11 --- .build/checks.sh | 2 +- .github/scripts/test-vscode-debugger.sh | 4 ++-- .github/scripts/verify-release-cli.sh | 2 +- CHANGELOG.md | 1 + Directory.Build.props | 4 +++- Makefile | 2 +- WORKSPACE | 2 +- .../FScript.DotNet.Comparison/CompareArtifacts.fsx | 4 ++-- benchmarks/FScript.DotNet.Comparison/README.md | 4 ++-- .../FScript.Evaluation.Benchmarks.fsproj | 2 +- .../FScript.Inference.Benchmarks.fsproj | 2 +- docs/architecture/native-aot-size.md | 2 +- docs/guides/compilation.md | 2 +- docs/guides/compile-to-csharp.md | 4 ++-- docs/guides/compile-to-dotnet.md | 14 +++++++------- docs/guides/compiler-cli.md | 6 +++--- docs/specs/dotnet-backends.md | 4 ++-- samples/ffi/README.md | 4 ++-- samples/ffi/Tests/GraphicsTests.fs | 6 +++--- samples/ffi/fscript.toml | 2 +- samples/task-sharing/fscript.toml | 2 +- src/FScript.Backend.CSharp/CSharpBackend.fs | 6 +++--- .../FScript.Backend.CSharp.fsproj | 2 +- src/FScript.Backend.DotNet/DotNetBackend.fs | 2 +- src/FScript.Backend.DotNet/DotNetDeadCaptures.fs | 2 +- src/FScript.Backend.DotNet/DotNetPackaging.fs | 10 +++++----- .../DotNetSourceOptimization.fs | 6 +++--- .../FScript.Backend.DotNet.fsproj | 2 +- .../FScript.CSharpInterop.fsproj | 2 +- src/FScript.Compiler/ClrBindings.fs | 4 ++-- src/FScript.Compiler/FScript.Compiler.fsproj | 2 +- .../FScript.DebugAdapter.csproj | 2 +- .../FScript.Interpreter.Lir.fsproj | 2 +- .../FScript.LanguageServer.csproj | 2 +- src/FScript.Runtime/FScript.Runtime.fsproj | 4 ++-- src/FScript/CompileOptions.fs | 2 +- src/FScript/FScript.fsproj | 2 +- src/FScript/Program.fs | 7 +++---- .../FScript.Backend.DotNet.Tests.fsproj | 2 +- .../FScript.Cli.Tests.Fixtures.Conflict.fsproj | 2 +- .../FScript.Cli.Tests.Fixtures.Consumer.fsproj | 2 +- .../FScript.Cli.Tests.Fixtures.Invalid.fsproj | 2 +- .../FScript.Cli.Tests.Fixtures.Valid.fsproj | 2 +- .../NuGetFixture.fs | 2 +- tests/FScript.Cli.Tests/CliTests.fs | 4 ++-- tests/FScript.Cli.Tests/FScript.Cli.Tests.fsproj | 2 +- tests/FScript.Compiler.Tests/CseTests.fs | 2 +- .../FScript.Compiler.Tests.fsproj | 2 +- .../FScript.Conformance.Tests.fsproj | 2 +- tests/FScript.DebugAdapter.Tests/AdapterTests.js | 2 +- .../FScript.Interpreter.Lir.Tests.fsproj | 2 +- .../FScript.Language.Tests.fsproj | 2 +- .../FScript.LanguageServer.Tests.csproj | 2 +- tests/FScript.LanguageServer.Tests/LspClient.cs | 2 +- .../FScript.Runtime.Tests.fsproj | 2 +- .../FScript.Runtime.Tests/NuGetEnvironmentTests.fs | 8 ++++---- tests/FScript.VscodeDebug.Tests/index.js | 2 +- vscode-fscript/README.md | 4 ++-- vscode-fscript/extension.js | 2 +- website/docs/compiler/compilation.md | 2 +- website/docs/compiler/compile-to-csharp.md | 4 ++-- website/docs/compiler/compile-to-dotnet.md | 14 +++++++------- website/docs/examples/ffi-graphics.md | 6 +++--- website/docs/reference/cli-reference.md | 2 +- 64 files changed, 108 insertions(+), 106 deletions(-) diff --git a/.build/checks.sh b/.build/checks.sh index fac520aa..8283b271 100644 --- a/.build/checks.sh +++ b/.build/checks.sh @@ -2,7 +2,7 @@ set -euo pipefail cd "$(dirname "$0")/.." configuration="${FSCRIPT_BUILD_CONFIG:-Release}" -cli=(dotnet "src/FScript/bin/$configuration/net10.0/fscript.dll") +cli=(dotnet "src/FScript/bin/$configuration/net11.0/fscript.dll") run_node_tests() { local report=$1 shift diff --git a/.github/scripts/test-vscode-debugger.sh b/.github/scripts/test-vscode-debugger.sh index de493385..8df66172 100755 --- a/.github/scripts/test-vscode-debugger.sh +++ b/.github/scripts/test-vscode-debugger.sh @@ -23,11 +23,11 @@ let calculate value = answer * 2 calculate 41 SCRIPT -python3 - "$fixture/workspace/.vscode/settings.json" "$repo/src/FScript/bin/Release/net10.0/fscript.dll" <<'PYSETTINGS' +python3 - "$fixture/workspace/.vscode/settings.json" "$repo/src/FScript/bin/Release/net11.0/fscript.dll" <<'PYSETTINGS' import json,pathlib,sys pathlib.Path(sys.argv[1]).write_text(json.dumps({ 'fscript.lsp.enabled': True, - 'fscript.server.path': str(pathlib.Path(sys.argv[2]).parents[5] / 'src/FScript.LanguageServer/bin/Release/net10.0/FScript.LanguageServer.dll'), + 'fscript.server.path': str(pathlib.Path(sys.argv[2]).parents[5] / 'src/FScript.LanguageServer/bin/Release/net11.0/FScript.LanguageServer.dll'), 'fscript.cli.path': sys.argv[2], 'terminal.integrated.enablePersistentSessions': False })) diff --git a/.github/scripts/verify-release-cli.sh b/.github/scripts/verify-release-cli.sh index 4ece4a37..180f7496 100755 --- a/.github/scripts/verify-release-cli.sh +++ b/.github/scripts/verify-release-cli.sh @@ -25,7 +25,7 @@ dotnet build "$repo_root/samples/ffi/Provider/FfiSample.fsproj" -c Release mkdir -p "$test_root/source" printf "[runtime]\nextern-assemblies = ['%s']\n" \ - "$repo_root/samples/ffi/Provider/bin/Release/net10.0/FScript.Ffi.Sample.dll" > "$test_root/source/fscript.toml" + "$repo_root/samples/ffi/Provider/bin/Release/net11.0/FScript.Ffi.Sample.dll" > "$test_root/source/fscript.toml" printf 'Math.sqrt 81.0\n' > "$test_root/source/check.fss" for target in csharp dotnet; do "$cli" compile "$test_root/source/check.fss" --target "$target" --output "$test_root/$target" diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e5a879d..3708cca4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to FScript are documented in this file. ## [Unreleased] +- Run the FScript CLI and language server on .NET 11 and target .NET 11 when compiling scripts to .NET or C#. - Document how compiled programs optimize `List.init`. ## [0.90.3] diff --git a/Directory.Build.props b/Directory.Build.props index b79c4e02..f05a09da 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,9 @@ false $(MSBuildThisFileDirectory)../FScript.Extensibility/src/FScript.Extensibility/FScript.Extensibility.fsproj - net10.0 + net11.0 + + 10.1.404 preview false false diff --git a/Makefile b/Makefile index cd7b589b..27891b37 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ benchmark-evaluation: # Compile once, then compare exported native functions against optimized F#. benchmark-dotnet-comparison: dotnet build benchmarks/FScript.DotNet.Comparison/FScript.DotNet.Comparison.fsproj -c Release - DOTNET_TieredCompilation=0 DOTNET_ReadyToRun=0 dotnet benchmarks/FScript.DotNet.Comparison/bin/Release/net10.0/FScript.DotNet.Comparison.dll $(or $(iterations),500) $(or $(rounds),9) "$(or $(output),out/benchmarks/dotnet-vs-fsharp)" $(if $(filter true,$(verify)),--verify-only) + DOTNET_TieredCompilation=0 DOTNET_ReadyToRun=0 dotnet benchmarks/FScript.DotNet.Comparison/bin/Release/net11.0/FScript.DotNet.Comparison.dll $(or $(iterations),500) $(or $(rounds),9) "$(or $(output),out/benchmarks/dotnet-vs-fsharp)" $(if $(filter true,$(verify)),--verify-only) fable-build: dotnet tool restore diff --git a/WORKSPACE b/WORKSPACE index 39f80eaa..d161a39a 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -12,7 +12,7 @@ variable config { default = "Release" } locals { versions = { - dotnet_sdk: "10.0.403" + dotnet_sdk: "11.0.100" node: "22" terrabuild: "latest" vsce: "4.0.0" diff --git a/benchmarks/FScript.DotNet.Comparison/CompareArtifacts.fsx b/benchmarks/FScript.DotNet.Comparison/CompareArtifacts.fsx index 3355968b..12dac516 100644 --- a/benchmarks/FScript.DotNet.Comparison/CompareArtifacts.fsx +++ b/benchmarks/FScript.DotNet.Comparison/CompareArtifacts.fsx @@ -1,6 +1,6 @@ // Build the comparison project in Release before running this script. -#r "bin/Release/net10.0/FScript.DotNet.Reference.dll" -#r "bin/Release/net10.0/FScript.DotNet.Comparison.dll" +#r "bin/Release/net11.0/FScript.DotNet.Reference.dll" +#r "bin/Release/net11.0/FScript.DotNet.Comparison.dll" open System open System.IO diff --git a/benchmarks/FScript.DotNet.Comparison/README.md b/benchmarks/FScript.DotNet.Comparison/README.md index 9089b668..e09e527d 100644 --- a/benchmarks/FScript.DotNet.Comparison/README.md +++ b/benchmarks/FScript.DotNet.Comparison/README.md @@ -2,7 +2,7 @@ This comparison measures native managed functions generated by the FScript .NET backend against equivalent F# compiled in Release mode. It also dumps both assemblies' IL. It does not measure either interpreter, Native AOT, command startup, or publishing. -Run from the repository root with the .NET 10 SDK: +Run from the repository root with the .NET 11 SDK: ```sh make benchmark-dotnet-comparison @@ -16,7 +16,7 @@ The Make target builds in Release, then starts a separate process with tiered co ```sh dotnet build benchmarks/FScript.DotNet.Comparison -c Release -dotnet benchmarks/FScript.DotNet.Comparison/bin/Release/net10.0/FScript.DotNet.Comparison.dll 500 9 out/comparison-default +dotnet benchmarks/FScript.DotNet.Comparison/bin/Release/net11.0/FScript.DotNet.Comparison.dll 500 9 out/comparison-default ``` Do not run concurrent builds or benchmarks. Repeat the process several times on an idle machine; compare medians and the per-round spread, rather than a single run. These measurements are diagnostic, not performance promises or CI timing thresholds. diff --git a/benchmarks/FScript.Evaluation.Benchmarks/FScript.Evaluation.Benchmarks.fsproj b/benchmarks/FScript.Evaluation.Benchmarks/FScript.Evaluation.Benchmarks.fsproj index 8b9b8374..8dc95f56 100644 --- a/benchmarks/FScript.Evaluation.Benchmarks/FScript.Evaluation.Benchmarks.fsproj +++ b/benchmarks/FScript.Evaluation.Benchmarks/FScript.Evaluation.Benchmarks.fsproj @@ -1,7 +1,7 @@ Exe - net10.0 + net11.0 diff --git a/benchmarks/FScript.Inference.Benchmarks/FScript.Inference.Benchmarks.fsproj b/benchmarks/FScript.Inference.Benchmarks/FScript.Inference.Benchmarks.fsproj index 5743e87f..aab42823 100644 --- a/benchmarks/FScript.Inference.Benchmarks/FScript.Inference.Benchmarks.fsproj +++ b/benchmarks/FScript.Inference.Benchmarks/FScript.Inference.Benchmarks.fsproj @@ -2,7 +2,7 @@ Exe - net10.0 + net11.0 diff --git a/docs/architecture/native-aot-size.md b/docs/architecture/native-aot-size.md index 1b6d6060..4328f9ef 100644 --- a/docs/architecture/native-aot-size.md +++ b/docs/architecture/native-aot-size.md @@ -29,7 +29,7 @@ The optional `--size-optimized` profile sets `InvariantGlobalization=true`, `Use ## Analysis and validation -For size attribution, publish the generated assembly through an isolated SDK project whose post-`CoreCompile` target copies the generated PE over its placeholder assembly, matching `DotNetPackaging`. Set `IlcGenerateMapFile=true`, `IlcGenerateMstatFile=true`, and, when investigating a dependency, `IlcGenerateDgmlFile=true`. The SDK writes maps, statistics, and dependency graphs under `obj/Release/net10.0//native/`. Compare `ResourceData` and native `MethodCode` nodes in the XML map, then follow dependency graph edges to find the root of unexpected code. FScript's regular publisher deletes this temporary project after compilation. +For size attribution, publish the generated assembly through an isolated SDK project whose post-`CoreCompile` target copies the generated PE over its placeholder assembly, matching `DotNetPackaging`. Set `IlcGenerateMapFile=true`, `IlcGenerateMstatFile=true`, and, when investigating a dependency, `IlcGenerateDgmlFile=true`. The SDK writes maps, statistics, and dependency graphs under `obj/Release/net11.0//native/`. Compare `ResourceData` and native `MethodCode` nodes in the XML map, then follow dependency graph edges to find the root of unexpected code. FScript's regular publisher deletes this temporary project after compilation. The sample integration tests publish both profiles, inspect the executable for the exact target GLFW payload and absence of every other GLFW payload, move the executable away from scripts and provider DLLs, run headless frames without a .NET installation, and check invalid frame limits. macOS ARM64 size budgets leave SDK headroom while catching the original all-platform resource regression. A packed-buffer test checks all uploaded position and normal components. Real OpenGL validation uses `--frames 3` and checks the renderer's count of teapot-colored framebuffer pixels. diff --git a/docs/guides/compilation.md b/docs/guides/compilation.md index 09462f11..ead4b704 100644 --- a/docs/guides/compilation.md +++ b/docs/guides/compilation.md @@ -6,7 +6,7 @@ FScript can run inside a host application or compile into a program that runs on | Output | Command options | Use it when | | --- | --- | --- | -| .NET assembly | `--target dotnet` | You want compiled execution with FScript's assembly optimizations. Run the DLL with .NET 10. | +| .NET assembly | `--target dotnet` | You want compiled execution with FScript's assembly optimizations. Run the DLL with .NET 11. | | Self-contained executable | `--target dotnet --single-file [--runtime ]` | You want one distributable executable that includes the .NET runtime. | | Native AOT executable | `--target dotnet --aot [--runtime ]` | You want dependencies trimmed and compiled into a native executable. | | C# project | `--target csharp` | You want to inspect, edit, or integrate generated source in a .NET build. | diff --git a/docs/guides/compile-to-csharp.md b/docs/guides/compile-to-csharp.md index 7af5f73e..d2a0703e 100644 --- a/docs/guides/compile-to-csharp.md +++ b/docs/guides/compile-to-csharp.md @@ -1,6 +1,6 @@ # Compile to C# -The C# backend writes an independently buildable .NET 10 project. Use it when generated source belongs in your build, when you need to inspect a translated program, or when you want to make further changes in C#. +The C# backend writes an independently buildable .NET 11 project. Use it when generated source belongs in your build, when you need to inspect a translated program, or when you want to make further changes in C#. For FScript's additional call, closure, tail-recursion, and pruning optimizations, use the [.NET assembly target](./compile-to-dotnet.md). Building generated C# does not enable those assembly-only passes. @@ -12,7 +12,7 @@ dotnet build out/hello-csharp/Program.csproj -c Release dotnet run --project out/hello-csharp/Program.csproj -c Release -- Ada ``` -Building the generated project requires the .NET 10 SDK. From the FScript checkout, generation can instead use: +Building the generated project requires the .NET 11 SDK. From the FScript checkout, generation can instead use: ```sh dotnet run --project src/FScript -- compile samples/hello.fss --target csharp --output out/hello-csharp diff --git a/docs/guides/compile-to-dotnet.md b/docs/guides/compile-to-dotnet.md index 5833aff5..deacd28a 100644 --- a/docs/guides/compile-to-dotnet.md +++ b/docs/guides/compile-to-dotnet.md @@ -6,11 +6,11 @@ The .NET backend compiles a typed FScript program into an optimized .NET assembl | Operation | Requirements | | --- | --- | -| Generate a `.dll` with `--target dotnet` | FScript and a .NET 10 runtime; no SDK required. Roslyn is bundled with FScript and emits the assembly in-process. | -| Publish with `--single-file` | .NET 10 SDK available through `dotnet` on PATH. | -| Publish with `--aot` | .NET 10 SDK plus the target platform's native build tools; build on the target OS. | +| Generate a `.dll` with `--target dotnet` | FScript and a .NET 11 runtime; no SDK required. Roslyn is bundled with FScript and emits the assembly in-process. | +| Publish with `--single-file` | .NET 11 SDK available through `dotnet` on PATH. | +| Publish with `--aot` | .NET 11 SDK plus the target platform's native build tools; build on the target OS. | -Running FScript itself from source with `dotnet run` requires the SDK to build FScript. That is separate from the installed compiler's requirements. A generated ordinary DLL needs a .NET 10 runtime to run; published single-file and AOT executables do not require a .NET installation on the destination machine. +Running FScript itself from source with `dotnet run` requires the SDK to build FScript. That is separate from the installed compiler's requirements. A generated ordinary DLL needs a .NET 11 runtime to run; published single-file and AOT executables do not require a .NET installation on the destination machine. ## Runnable .NET assembly @@ -21,7 +21,7 @@ dotnet out/fibonacci-dotnet/fibonacci.dll Compiled entry points print the final value by default. Add `--no-result` when compiling to suppress it and allow proven-pure discarded computations to be pruned. Explicit output, failures, and exit-code writes remain observable. Without this flag, library callers can retrieve the typed value through `Run` and format it explicitly with `FormatResult`; in discard mode, `Run` returns unit. -Output includes a `.dll`, runtime configuration, and required external managed dependencies. The minimum runtime is .NET 10. Arguments after the assembly name become `Env.Arguments`. +Output includes a `.dll`, runtime configuration, and required external managed dependencies. The minimum runtime is .NET 11. Arguments after the assembly name become `Env.Arguments`. ```sh dotnet run --project src/FScript -- compile samples/basic/basic.fss --target dotnet --output out/basic-dotnet @@ -66,7 +66,7 @@ Without that separator, `dotnet run` can consume `--runtime` itself and fail whi Windows output has an `.exe` extension; macOS and Linux output has no extension. Use a fresh output directory when switching from DLL output: existing files are not deleted. External data such as BASIC source files remains program input and is not bundled. -Publishing requires a .NET 10 SDK on the build machine and may restore runtime/compiler packs from NuGet. Native AOT additionally requires the platform's native build tools (Xcode Command Line Tools on macOS; Clang and zlib headers on Linux; Visual Studio C++ build tools on Windows). Native AOT must be built on the target OS; single-file managed publishing can target another OS. The executables still use normal OS libraries. See Microsoft's [single-file](https://learn.microsoft.com/dotnet/core/deploying/single-file/) and [Native AOT](https://learn.microsoft.com/dotnet/core/deploying/native-aot/) deployment documentation. +Publishing requires a .NET 11 SDK on the build machine and may restore runtime/compiler packs from NuGet. Native AOT additionally requires the platform's native build tools (Xcode Command Line Tools on macOS; Clang and zlib headers on Linux; Visual Studio C++ build tools on Windows). Native AOT must be built on the target OS; single-file managed publishing can target another OS. The executables still use normal OS libraries. See Microsoft's [single-file](https://learn.microsoft.com/dotnet/core/deploying/single-file/) and [Native AOT](https://learn.microsoft.com/dotnet/core/deploying/native-aot/) deployment documentation. Single-file publishing trims dependencies when all reachable FFI calls have static CLR bindings. Reachable legacy provider dispatch disables managed trimming to preserve its registration contract. Bundled native runtime libraries may be extracted by the .NET host at startup. Native AOT trims and compiles dependencies, so FFI libraries must be AOT-compatible. Dynamic loading or reflection-heavy providers may produce SDK diagnostics instead of a runnable native binary. Packaging failures are reported as `FSN710x`, including the SDK's diagnostics. @@ -86,7 +86,7 @@ For the teapot example, `samples/ffi/fscript.toml` supplies the provider path: ```toml [runtime] -extern-assemblies = ["Provider/bin/Release/net10.0/FScript.Ffi.Sample.dll"] +extern-assemblies = ["Provider/bin/Release/net11.0/FScript.Ffi.Sample.dll"] ``` Build the provider first, then analyze or compile without extra assembly flags: diff --git a/docs/guides/compiler-cli.md b/docs/guides/compiler-cli.md index 900762dc..9ec1c8c7 100644 --- a/docs/guides/compiler-cli.md +++ b/docs/guides/compiler-cli.md @@ -14,7 +14,7 @@ The IR form writes `/.fsir`. All targets create missing parent directories and deterministically replace files owned by the selected output on a repeated invocation. An unknown target is rejected before the output directory is created. Filesystem failures are reported as `FSA5101` diagnostics. -The C# target writes an independently buildable .NET 10 project. The .NET target writes `.dll`, runtime configuration, and managed dependencies. Both support existing FFI providers selected through `fscript.toml` or `--extern-assembly`; `--reference` adds managed dependencies. Generated programs execute compiled methods without an interpreter. Compiled entry points display the final value by default; `--no-result` suppresses that display. +The C# target writes an independently buildable .NET 11 project. The .NET target writes `.dll`, runtime configuration, and managed dependencies. Both support existing FFI providers selected through `fscript.toml` or `--extern-assembly`; `--reference` adds managed dependencies. Generated programs execute compiled methods without an interpreter. Compiled entry points display the final value by default; `--no-result` suppresses that display. ## FFI configuration with `fscript.toml` @@ -24,7 +24,7 @@ For example, `samples/ffi/fscript.toml` contains: ```toml [runtime] -extern-assemblies = ["Provider/bin/Release/net10.0/FScript.Ffi.Sample.dll"] +extern-assemblies = ["Provider/bin/Release/net11.0/FScript.Ffi.Sample.dll"] ``` Assembly paths in the manifest resolve from the manifest directory. Local provider projects must be built before either command loads their configured DLLs. For C# and .NET output, compilation automatically references the providers and their colocated managed dependencies; `--reference` adds other managed assemblies when needed. @@ -58,7 +58,7 @@ out/ffi/main --headless On Windows the executable is `main.exe`. Native AOT requires the platform's native toolchain. -For a self-contained executable, add `--single-file` to the .NET target. For a Native AOT executable, use `--aot`. Publishing defaults to the current platform; pass `--runtime ` to select another target. An explicitly supplied `--runtime` requires a value. Runtime identifiers use .NET names such as `osx-arm64`, `linux-x64`, and `win-x64`. Both options require a .NET 10 SDK for publishing and are rejected for other backends. +For a self-contained executable, add `--single-file` to the .NET target. For a Native AOT executable, use `--aot`. Publishing defaults to the current platform; pass `--runtime ` to select another target. An explicitly supplied `--runtime` requires a value. Runtime identifiers use .NET names such as `osx-arm64`, `linux-x64`, and `win-x64`. Both options require a .NET 11 SDK for publishing and are rejected for other backends. See [Compilation](./compilation.md), [Compile to .NET](./compile-to-dotnet.md), [Compile to C#](./compile-to-csharp.md), [Compilation and optimizations](./compiler-optimizations.md), and [Compile and Interpret FScript IR](./interpret-ir.md). The normative representations are documented in the [typed HIR](../specs/typed-hir.md) and [executable LIR](../specs/executable-lir.md) specifications. diff --git a/docs/specs/dotnet-backends.md b/docs/specs/dotnet-backends.md index ac41f990..8e567679 100644 --- a/docs/specs/dotnet-backends.md +++ b/docs/specs/dotnet-backends.md @@ -72,9 +72,9 @@ Native AOT always uses `OptimizationPreference=Size`, keeping standard culture s Executable publishing defines boolean `FScript.NativeAssets.` feature switches for every supported portable runtime identifier, true only for the requested identifier. Providers may opt in through embedded `ILLink.Substitutions.xml` resource-removal rules conditioned on their runtime's switch being false. Missing switches must retain assets, so normal DLL generation and interpreted provider loading remain portable. The compiler never guesses which arbitrary provider resources are disposable. The FFI renderer uses this contract to retain its GLFW license and selected native library while dropping other platforms' libraries in trimmed single-file and AOT output. Untrimmed legacy single-file output retains all resources. -Publishing requires a .NET 10 SDK on PATH and, for Native AOT, the platform native toolchain and compatible dependencies. SDK restore may need network access. `FSN7101` reports invalid publishing options, `FSN7102` reports an unavailable SDK command, `FSN7103` reports SDK publishing failures/timeouts or incomplete bundling, and `FSN7104` reports Native AOT cross-OS requests. The compiler captures SDK diagnostics and cleans its temporary project. Existing unrelated output-directory files are preserved. +Publishing requires a .NET 11 SDK on PATH and, for Native AOT, the platform native toolchain and compatible dependencies. SDK restore may need network access. `FSN7101` reports invalid publishing options, `FSN7102` reports an unavailable SDK command, `FSN7103` reports SDK publishing failures/timeouts or incomplete bundling, and `FSN7104` reports Native AOT cross-OS requests. The compiler captures SDK diagnostics and cleans its temporary project. Existing unrelated output-directory files are preserved. -C# output includes `Program.cs`, `Runtime.cs`, and `Program.csproj`. .NET output includes the assembly and, for console applications, a runtime configuration. External assembly references are explicit. Source generation does not invoke an installed compiler. Ordinary assembly generation requires the .NET 10 runtime but not an installed SDK; Pinned, architecture-neutral Roslyn NuGet assemblies ship with FScript. Build-host SDK Roslyn binaries must not enter release packages because their ReadyToRun code can target the build host rather than the CLI's target. Release CI tests the actual macOS archive on an ARM64 macOS runner before publication. Running the compiler from source through `dotnet run` and SDK publishing do require the SDK. Assembly generation uses Roslyn in-process with release optimization, deterministic output, unsafe code disabled, and nullable checks enabled. Compiler errors and warnings prevent publication of an output assembly. +C# output includes `Program.cs`, `Runtime.cs`, and `Program.csproj`. .NET output includes the assembly and, for console applications, a runtime configuration. External assembly references are explicit. Source generation does not invoke an installed compiler. Ordinary assembly generation requires the .NET 11 runtime but not an installed SDK; Pinned, architecture-neutral Roslyn NuGet assemblies ship with FScript. Build-host SDK Roslyn binaries must not enter release packages because their ReadyToRun code can target the build host rather than the CLI's target. Release CI tests the actual macOS archive on an ARM64 macOS runner before publication. Running the compiler from source through `dotnet run` and SDK publishing do require the SDK. Assembly generation uses Roslyn in-process with release optimization, deterministic output, unsafe code disabled, and nullable checks enabled. Compiler errors and warnings prevent publication of an output assembly. Tests load emitted assemblies, JIT every closed generated method, execute representative semantic programs and CLR calls, and build generated C# as an independent project. This checks valid IL and execution behavior without relying on FScript hosting. diff --git a/samples/ffi/README.md b/samples/ffi/README.md index ec1a113e..a8d0d8bf 100644 --- a/samples/ffi/README.md +++ b/samples/ffi/README.md @@ -4,7 +4,7 @@ FScript builds a Utah teapot from 32 bicubic Bézier patches, computes surface n ## Run -From the repository root, build the provider library once with the .NET 10 SDK: +From the repository root, build the provider library once with the .NET 11 SDK: ```sh dotnet build samples/ffi/Provider/FfiSample.fsproj -c Release @@ -57,7 +57,7 @@ out/ffi/main --headless out/ffi/main --frames 3 ``` -The output is one executable, `main.exe` on Windows, and requires no FScript installation or .NET runtime. Native AOT publishing needs the .NET 10 SDK and the platform's native compiler. The selected platform's GLFW binary is embedded in the executable and extracted to a content-addressed temporary cache when a graphical window starts. Headless mode does not initialize GLFW. Graphical execution still requires the platform's display and OpenGL drivers. +The output is one executable, `main.exe` on Windows, and requires no FScript installation or .NET runtime. Native AOT publishing needs the .NET 11 SDK and the platform's native compiler. The selected platform's GLFW binary is embedded in the executable and extracted to a content-addressed temporary cache when a graphical window starts. Headless mode does not initialize GLFW. Graphical execution still requires the platform's display and OpenGL drivers. For the smallest supported runtime profile: diff --git a/samples/ffi/Tests/GraphicsTests.fs b/samples/ffi/Tests/GraphicsTests.fs index 2cc433de..1986d0c4 100644 --- a/samples/ffi/Tests/GraphicsTests.fs +++ b/samples/ffi/Tests/GraphicsTests.fs @@ -163,7 +163,7 @@ Graphics.runHeadless 3 (fun window -> fun seconds -> Graphics.clear window { R = #else let configuration = "Release" #endif - let cli = Path.Combine(root, "src/FScript/bin", configuration, "net10.0/fscript.dll") + let cli = Path.Combine(root, "src/FScript/bin", configuration, "net11.0/fscript.dll") let start = Diagnostics.ProcessStartInfo("dotnet", RedirectStandardOutput = true, RedirectStandardError = true) for argument in [cli; "--no-config"; "--extern-assembly"; typeof.Assembly.Location; Path.Combine(root, "samples/ffi/main.fss"); "--"; argument] do @@ -189,7 +189,7 @@ Graphics.runHeadless 3 (fun window -> fun seconds -> Graphics.clear window { R = #else let configuration = "Release" #endif - let cli = Path.Combine(root, "src/FScript/bin", configuration, "net10.0/fscript.dll") + let cli = Path.Combine(root, "src/FScript/bin", configuration, "net11.0/fscript.dll") let directory = Path.Combine(Path.GetTempPath(), "fscript-teapot-native-" + Guid.NewGuid().ToString("N")) Directory.CreateDirectory(directory) |> ignore let run executable arguments timeout = @@ -206,7 +206,7 @@ Graphics.runHeadless 3 (fun window -> fun seconds -> Graphics.clear window { R = let output = Path.Combine(directory, "output") Directory.CreateDirectory(source) |> ignore for path in Directory.GetFiles(Path.Combine(root, "samples/ffi"), "*.fss") do - File.Copy(path, Path.Combine(source, Path.GetFileName path |> nonNull)) + File.Copy(path, Path.Combine(source, Path.GetFileName path)) let provider = typeof.Assembly.Location.Replace('\\', '/') File.WriteAllText(Path.Combine(source, "fscript.toml"), $"[runtime]\nextern-assemblies = ['{provider}']") let flags = if minimizeSize then ["--size-optimized"] else [] diff --git a/samples/ffi/fscript.toml b/samples/ffi/fscript.toml index b54b603b..0524b033 100644 --- a/samples/ffi/fscript.toml +++ b/samples/ffi/fscript.toml @@ -1,7 +1,7 @@ # Build first: dotnet build samples/ffi/Provider/FfiSample.fsproj -c Release # Select this configuration in VS Code to get Graphics/Math functions and host types. [runtime] -extern-assemblies = ["Provider/bin/Release/net10.0/FScript.Ffi.Sample.dll"] +extern-assemblies = ["Provider/bin/Release/net11.0/FScript.Ffi.Sample.dll"] # fscript compile main.fss uses these defaults; explicit CLI options override them. [compile] diff --git a/samples/task-sharing/fscript.toml b/samples/task-sharing/fscript.toml index b8222e9f..817a6645 100644 --- a/samples/task-sharing/fscript.toml +++ b/samples/task-sharing/fscript.toml @@ -1,3 +1,3 @@ # Build first: dotnet build samples/task-sharing/TaskSharingSample.fsproj -c Release [runtime] -extern-assemblies = ["bin/Release/net10.0/FScript.TaskSharing.Sample.dll"] +extern-assemblies = ["bin/Release/net11.0/FScript.TaskSharing.Sample.dll"] diff --git a/src/FScript.Backend.CSharp/CSharpBackend.fs b/src/FScript.Backend.CSharp/CSharpBackend.fs index f5e80cea..e0188765 100644 --- a/src/FScript.Backend.CSharp/CSharpBackend.fs +++ b/src/FScript.Backend.CSharp/CSharpBackend.fs @@ -1273,10 +1273,10 @@ module CSharpBackend = use reader = new StreamReader(stream) let runtime = reader.ReadToEnd().Replace("__NAMESPACE__",options.Namespace) let runtime = if assemblyMode then runtime.Replace("internal static class FsRuntime","internal static partial class FsRuntime") else runtime - let escapeXml (value: string) = System.Security.SecurityElement.Escape(value) |> nonNull - let references = options.References |> List.distinct |> List.map (fun path -> $" nonNull)}\">{escapeXml (Path.GetFullPath path)}true") |> String.concat "\n" + let escapeXml (value: string) = System.Security.SecurityElement.Escape(value) + let references = options.References |> List.distinct |> List.map (fun path -> $"{escapeXml (Path.GetFullPath path)}true") |> String.concat "\n" let compileItems = "" + (if hasSdk then "" else "") + (if assemblyMode then "" else "") - let project = $"Exenet10.0enabletruefalse{compileItems}{references}\n" + let project = $"Exenet11.0enabletruefalse{compileItems}{references}\n" [ yield { RelativePath = "Program.cs"; Content = source }; yield { RelativePath = "Runtime.cs"; Content = runtime }; yield { RelativePath = "Program.csproj"; Content = project } use tasksStream=typeof.Assembly.GetManifestResourceStream("FScript.Backend.CSharp.RuntimeTasks.cs") |> nonNull use tasksReader=new StreamReader(tasksStream) diff --git a/src/FScript.Backend.CSharp/FScript.Backend.CSharp.fsproj b/src/FScript.Backend.CSharp/FScript.Backend.CSharp.fsproj index 81eb3f8a..068d383e 100644 --- a/src/FScript.Backend.CSharp/FScript.Backend.CSharp.fsproj +++ b/src/FScript.Backend.CSharp/FScript.Backend.CSharp.fsproj @@ -1,5 +1,5 @@ - net10.0false + net11.0false diff --git a/src/FScript.Backend.DotNet/DotNetBackend.fs b/src/FScript.Backend.DotNet/DotNetBackend.fs index 7896afef..918f4835 100644 --- a/src/FScript.Backend.DotNet/DotNetBackend.fs +++ b/src/FScript.Backend.DotNet/DotNetBackend.fs @@ -51,7 +51,7 @@ module DotNetBackend = | Ok bytes -> let binary = { RelativePath=options.AssemblyName+".dll"; Content=bytes } let runtimeConfig = - "{\"runtimeOptions\":{\"tfm\":\"net10.0\",\"framework\":{\"name\":\"Microsoft.NETCore.App\",\"version\":\"10.0.0\"},\"rollForward\":\"LatestMinor\"}}\n" + "{\"runtimeOptions\":{\"tfm\":\"net11.0\",\"framework\":{\"name\":\"Microsoft.NETCore.App\",\"version\":\"11.0.0\"},\"rollForward\":\"LatestMinor\"}}\n" let dependencies = ClrBindings.referencedDependencies binary.Content options.References |> List.filter (fun path -> Path.GetFileNameWithoutExtension path <> options.AssemblyName) diff --git a/src/FScript.Backend.DotNet/DotNetDeadCaptures.fs b/src/FScript.Backend.DotNet/DotNetDeadCaptures.fs index 9d2d9dd5..b34d3a22 100644 --- a/src/FScript.Backend.DotNet/DotNetDeadCaptures.fs +++ b/src/FScript.Backend.DotNet/DotNetDeadCaptures.fs @@ -151,7 +151,7 @@ module internal DotNetDeadCaptures = if not (live.Contains symbol) then dead.Add symbol |> ignore if parameters.Count=0 && dead.Count=0 then compilation else let trees = compilation.SyntaxTrees |> Seq.map (fun tree -> - let root = Rewrite(compilation.GetSemanticModel(tree,false),parameters,dead).Visit(tree.GetRoot()) |> nonNull + let root = Rewrite(compilation.GetSemanticModel(tree,false),parameters,dead).Visit(tree.GetRoot()) CSharpSyntaxTree.Create(root :?> CSharpSyntaxNode,tree.Options :?> CSharpParseOptions,tree.FilePath,tree.Encoding)) |> Seq.toArray iterate (compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(trees)) iterate input diff --git a/src/FScript.Backend.DotNet/DotNetPackaging.fs b/src/FScript.Backend.DotNet/DotNetPackaging.fs index 2c5d1cd1..7a511c82 100644 --- a/src/FScript.Backend.DotNet/DotNetPackaging.fs +++ b/src/FScript.Backend.DotNet/DotNetPackaging.fs @@ -47,9 +47,9 @@ module internal DotNetPackaging = Directory.CreateDirectory(payload) |> ignore for file in files |> List.filter (fun file -> file.RelativePath.EndsWith(".dll",StringComparison.OrdinalIgnoreCase)) do File.WriteAllBytes(Path.Combine(payload,file.RelativePath),file.Content) - let xml (value: string) = SecurityElement.Escape(value) |> nonNull + let xml (value: string) = SecurityElement.Escape(value) let references=files |> List.filter (fun file -> file.RelativePath.EndsWith(".dll",StringComparison.OrdinalIgnoreCase) && file.RelativePath<>options.AssemblyName+".dll") - |> List.map (fun file -> $" nonNull)}\">payload/{xml file.RelativePath}true") |> String.concat "\n" + |> List.map (fun file -> $"payload/{xml file.RelativePath}true") |> String.concat "\n" let aot=if executable.AheadOfTime then "true" else "false" let trim=if trim then "true" else "false" let bundle=if executable.AheadOfTime then "false" else "true" @@ -66,7 +66,7 @@ module internal DotNetPackaging = else "" let project= $""" - net10.0Exe + net11.0Exe {xml options.AssemblyName}{xml executable.RuntimeIdentifier} truetrue {bundle}true @@ -110,7 +110,7 @@ module internal DotNetPackaging = let log=stdout.GetAwaiter().GetResult()+stderr.GetAwaiter().GetResult() if proc.ExitCode<>0 then let log=if log.Length>16000 then log.Substring(log.Length-16000) else log - Error [diagnostic "FSN7103" $".NET executable publishing failed for {executable.RuntimeIdentifier}. A .NET 10 SDK is required; Native AOT also requires the target's native compiler and AOT-compatible dependencies.\n{log.Trim()}"] + Error [diagnostic "FSN7103" $".NET executable publishing failed for {executable.RuntimeIdentifier}. A .NET 11 SDK is required; Native AOT also requires the target's native compiler and AOT-compatible dependencies.\n{log.Trim()}"] else let name=options.AssemblyName+(if executable.RuntimeIdentifier.StartsWith("win-",StringComparison.Ordinal) then ".exe" else "") let path=Path.Combine(output,name) @@ -125,7 +125,7 @@ module internal DotNetPackaging = if extras.Length<>0 then Error [diagnostic "FSN7103" $"Publishing left unbundled dependencies: {extraNames}."] else Ok [{RelativePath=name;Content=File.ReadAllBytes(path)}] with :? ComponentModel.Win32Exception as ex -> - Error [diagnostic "FSN7102" $"A .NET 10 SDK with dotnet on PATH is required for executable publishing: {ex.Message}"] + Error [diagnostic "FSN7102" $"A .NET 11 SDK with dotnet on PATH is required for executable publishing: {ex.Message}"] with ex -> Error [diagnostic "FSN7100" $"Cannot publish .NET executable: {ex.Message}"] try run () finally diff --git a/src/FScript.Backend.DotNet/DotNetSourceOptimization.fs b/src/FScript.Backend.DotNet/DotNetSourceOptimization.fs index ce677d80..7b6b8b26 100644 --- a/src/FScript.Backend.DotNet/DotNetSourceOptimization.fs +++ b/src/FScript.Backend.DotNet/DotNetSourceOptimization.fs @@ -167,7 +167,7 @@ module internal DotNetSourceOptimization = let optimize className isLibrary (compilation: CSharpCompilation) = let lowered= compilation.SyntaxTrees |> Seq.map (fun tree -> - let root=Lowering(compilation.GetSemanticModel(tree, false),className).Visit(tree.GetRoot()) |> nonNull + let root=Lowering(compilation.GetSemanticModel(tree, false),className).Visit(tree.GetRoot()) CSharpSyntaxTree.Create(root :?> CSharpSyntaxNode, tree.Options :?> CSharpParseOptions,tree.FilePath,tree.Encoding) ) |> Seq.toList let compilation=compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(lowered) |> DotNetDeadCaptures.optimize className let candidates=HashSet(SymbolEqualityComparer.Default) @@ -188,7 +188,7 @@ module internal DotNetSourceOptimization = | _ -> () candidates.ExceptWith(reads) let stripped=compilation.SyntaxTrees |> Seq.map (fun tree -> - let root=UnreadFields(compilation.GetSemanticModel(tree,false),candidates).Visit(tree.GetRoot()) |> nonNull + let root=UnreadFields(compilation.GetSemanticModel(tree,false),candidates).Visit(tree.GetRoot()) CSharpSyntaxTree.Create(root :?> CSharpSyntaxNode,tree.Options :?> CSharpParseOptions,tree.FilePath,tree.Encoding)) |> Seq.toList let compilation=compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(stripped) let retained=HashSet() @@ -260,6 +260,6 @@ module internal DotNetSourceOptimization = | _ -> () | _ -> () let trees=compilation.SyntaxTrees |> Seq.map (fun tree -> - let root=Pruning(retained).Visit(tree.GetRoot()) |> nonNull + let root=Pruning(retained).Visit(tree.GetRoot()) CSharpSyntaxTree.Create(root :?> CSharpSyntaxNode,tree.Options :?> CSharpParseOptions,tree.FilePath,tree.Encoding)) |> Seq.toList compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(trees) diff --git a/src/FScript.Backend.DotNet/FScript.Backend.DotNet.fsproj b/src/FScript.Backend.DotNet/FScript.Backend.DotNet.fsproj index 13266473..40e751f6 100644 --- a/src/FScript.Backend.DotNet/FScript.Backend.DotNet.fsproj +++ b/src/FScript.Backend.DotNet/FScript.Backend.DotNet.fsproj @@ -1,5 +1,5 @@ - net10.0false + net11.0false diff --git a/src/FScript.CSharpInterop/FScript.CSharpInterop.fsproj b/src/FScript.CSharpInterop/FScript.CSharpInterop.fsproj index 2b6bf1c5..b7a3dc41 100644 --- a/src/FScript.CSharpInterop/FScript.CSharpInterop.fsproj +++ b/src/FScript.CSharpInterop/FScript.CSharpInterop.fsproj @@ -1,7 +1,7 @@ - net10.0 + net11.0 enable diff --git a/src/FScript.Compiler/ClrBindings.fs b/src/FScript.Compiler/ClrBindings.fs index 5a843629..4adb1c76 100644 --- a/src/FScript.Compiler/ClrBindings.fs +++ b/src/FScript.Compiler/ClrBindings.fs @@ -52,7 +52,7 @@ module ClrBindings = | null -> () | entry when String.IsNullOrEmpty entry.Location -> () | entry -> - let deps = Path.ChangeExtension(entry.Location, ".deps.json") |> nonNull + let deps = Path.ChangeExtension(entry.Location, ".deps.json") if File.Exists deps then use document = JsonDocument.Parse(File.ReadAllText deps) let mutable targets = Unchecked.defaultof @@ -62,7 +62,7 @@ module ClrBindings = if library.Name.StartsWith("runtimepack.Microsoft.NETCore.App.Runtime.", StringComparison.Ordinal) then let mutable runtime = Unchecked.defaultof if library.Value.TryGetProperty("runtime", &runtime) then - for asset in runtime.EnumerateObject() do names.Add(Path.GetFileName asset.Name |> nonNull) |> ignore + for asset in runtime.EnumerateObject() do names.Add(Path.GetFileName asset.Name) |> ignore names /// Include managed dependencies colocated with explicit reference assemblies. diff --git a/src/FScript.Compiler/FScript.Compiler.fsproj b/src/FScript.Compiler/FScript.Compiler.fsproj index 8e586e33..6fa4125c 100644 --- a/src/FScript.Compiler/FScript.Compiler.fsproj +++ b/src/FScript.Compiler/FScript.Compiler.fsproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 false diff --git a/src/FScript.DebugAdapter/FScript.DebugAdapter.csproj b/src/FScript.DebugAdapter/FScript.DebugAdapter.csproj index d18f8b5d..4c4db23b 100644 --- a/src/FScript.DebugAdapter/FScript.DebugAdapter.csproj +++ b/src/FScript.DebugAdapter/FScript.DebugAdapter.csproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 enable enable false diff --git a/src/FScript.Interpreter.Lir/FScript.Interpreter.Lir.fsproj b/src/FScript.Interpreter.Lir/FScript.Interpreter.Lir.fsproj index 3533c5b8..864682aa 100644 --- a/src/FScript.Interpreter.Lir/FScript.Interpreter.Lir.fsproj +++ b/src/FScript.Interpreter.Lir/FScript.Interpreter.Lir.fsproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 false diff --git a/src/FScript.LanguageServer/FScript.LanguageServer.csproj b/src/FScript.LanguageServer/FScript.LanguageServer.csproj index 25b10a88..d5ac648e 100644 --- a/src/FScript.LanguageServer/FScript.LanguageServer.csproj +++ b/src/FScript.LanguageServer/FScript.LanguageServer.csproj @@ -1,7 +1,7 @@ Exe - net10.0 + net11.0 enable enable diff --git a/src/FScript.Runtime/FScript.Runtime.fsproj b/src/FScript.Runtime/FScript.Runtime.fsproj index a168abfb..3fec244c 100644 --- a/src/FScript.Runtime/FScript.Runtime.fsproj +++ b/src/FScript.Runtime/FScript.Runtime.fsproj @@ -58,8 +58,8 @@ - - + + diff --git a/src/FScript/CompileOptions.fs b/src/FScript/CompileOptions.fs index 8a8ec649..c2ca646c 100644 --- a/src/FScript/CompileOptions.fs +++ b/src/FScript/CompileOptions.fs @@ -39,7 +39,7 @@ let resolve (arguments: string array) (scriptPath: string) (defaults: CompileCon option "--output" |> Option.map Path.GetFullPath |> Option.orElse defaults.OutputDirectory |> Option.defaultWith (fun () -> - let root = Path.Combine(Path.GetDirectoryName(scriptPath) |> nonNull, "bin", Path.GetFileNameWithoutExtension(scriptPath) |> nonNull, backend) + let root = Path.Combine(Path.GetDirectoryName(scriptPath) |> nonNull, "bin", Path.GetFileNameWithoutExtension(scriptPath), backend) if native && (aot || single) then Path.Combine(root, runtime.Value, if aot then "aot" else "single-file") else root) Ok { Backend=backend; AheadOfTime=aot; SingleFile=single; MinimizeSize=size; RuntimeIdentifier=runtime; OutputDirectory=output } with :? ArgumentException as error -> Error error.Message diff --git a/src/FScript/FScript.fsproj b/src/FScript/FScript.fsproj index 30363a23..c24843ce 100644 --- a/src/FScript/FScript.fsproj +++ b/src/FScript/FScript.fsproj @@ -7,7 +7,7 @@ fscript true - net10.0 + net11.0 enable true MagnusOpera.FScript diff --git a/src/FScript/Program.fs b/src/FScript/Program.fs index 90662543..87296e78 100644 --- a/src/FScript/Program.fs +++ b/src/FScript/Program.fs @@ -102,7 +102,7 @@ let runCompileCommand (argv: string array) = | "ir" -> let baseName = match Path.GetFileNameWithoutExtension(scriptPath) with - | null | "" -> "program" + | "" -> "program" | value -> value let name = baseName + ".fsir" report "Writing IR artifact..." @@ -119,7 +119,7 @@ let runCompileCommand (argv: string array) = complete (Path.Combine(outputDirectory, "Program.csproj")) | "dotnet" -> let options: FScript.Compiler.DotNetOptions = - { AssemblyName=Path.GetFileNameWithoutExtension scriptPath |> nonNull; Namespace="FScript.Generated"; ClassName="Program" + { AssemblyName=Path.GetFileNameWithoutExtension scriptPath; Namespace="FScript.Generated"; ClassName="Program" OutputKind=FScript.Compiler.ConsoleApplication; References=references } report "Generating .NET assembly..." let generated= @@ -223,7 +223,7 @@ let runAnalyzeCommand (argv: string array) = let providers = loaded.ProviderMethods |> List.map snd let purity = FScript.Compiler.ClrBindings.providerPurity providers let options = TaskSharingContracts.fromProviders providers |> TaskSharingContracts.withRuntime loaded.Registration - let program = parseEnvironmentPrelude (Some(Path.GetFileName path |> nonNull)) [] @ FScript.parseFileWithIncludes settings.RootDirectory path + let program = parseEnvironmentPrelude (Some(Path.GetFileName path)) [] @ FScript.parseFileWithIncludes settings.RootDirectory path let resolved = TypeInfer.inferResolvedProgramWithRegistrationAndPurity loaded.Registration purity program TaskSharingAnalysis.analyze loaded.Registration options resolved |> List.iter reportTaskSharingWarning 0 @@ -239,7 +239,6 @@ let runFile printResult (registration: ExtensionRegistration) (rootDirectory: st else let scriptName = match Path.GetFileName(scriptPath) with - | null | "" -> scriptPath | value -> value let envProgram = parseEnvironmentPrelude (Some scriptName) arguments diff --git a/tests/FScript.Backend.DotNet.Tests/FScript.Backend.DotNet.Tests.fsproj b/tests/FScript.Backend.DotNet.Tests/FScript.Backend.DotNet.Tests.fsproj index 0ed3d922..16ad93c3 100644 --- a/tests/FScript.Backend.DotNet.Tests/FScript.Backend.DotNet.Tests.fsproj +++ b/tests/FScript.Backend.DotNet.Tests/FScript.Backend.DotNet.Tests.fsproj @@ -1,5 +1,5 @@ - net10.0falsefalse + net11.0falsefalse diff --git a/tests/FScript.Cli.Tests.Fixtures.Conflict/FScript.Cli.Tests.Fixtures.Conflict.fsproj b/tests/FScript.Cli.Tests.Fixtures.Conflict/FScript.Cli.Tests.Fixtures.Conflict.fsproj index e0e67a7b..2be8265c 100644 --- a/tests/FScript.Cli.Tests.Fixtures.Conflict/FScript.Cli.Tests.Fixtures.Conflict.fsproj +++ b/tests/FScript.Cli.Tests.Fixtures.Conflict/FScript.Cli.Tests.Fixtures.Conflict.fsproj @@ -1,7 +1,7 @@ - net10.0 + net11.0 false false enable diff --git a/tests/FScript.Cli.Tests.Fixtures.Consumer/FScript.Cli.Tests.Fixtures.Consumer.fsproj b/tests/FScript.Cli.Tests.Fixtures.Consumer/FScript.Cli.Tests.Fixtures.Consumer.fsproj index 767e068e..f92dcca6 100644 --- a/tests/FScript.Cli.Tests.Fixtures.Consumer/FScript.Cli.Tests.Fixtures.Consumer.fsproj +++ b/tests/FScript.Cli.Tests.Fixtures.Consumer/FScript.Cli.Tests.Fixtures.Consumer.fsproj @@ -1,5 +1,5 @@ - net10.0false + net11.0false diff --git a/tests/FScript.Cli.Tests.Fixtures.Invalid/FScript.Cli.Tests.Fixtures.Invalid.fsproj b/tests/FScript.Cli.Tests.Fixtures.Invalid/FScript.Cli.Tests.Fixtures.Invalid.fsproj index e0e67a7b..2be8265c 100644 --- a/tests/FScript.Cli.Tests.Fixtures.Invalid/FScript.Cli.Tests.Fixtures.Invalid.fsproj +++ b/tests/FScript.Cli.Tests.Fixtures.Invalid/FScript.Cli.Tests.Fixtures.Invalid.fsproj @@ -1,7 +1,7 @@ - net10.0 + net11.0 false false enable diff --git a/tests/FScript.Cli.Tests.Fixtures.Valid/FScript.Cli.Tests.Fixtures.Valid.fsproj b/tests/FScript.Cli.Tests.Fixtures.Valid/FScript.Cli.Tests.Fixtures.Valid.fsproj index 8eb08f75..04b1d50f 100644 --- a/tests/FScript.Cli.Tests.Fixtures.Valid/FScript.Cli.Tests.Fixtures.Valid.fsproj +++ b/tests/FScript.Cli.Tests.Fixtures.Valid/FScript.Cli.Tests.Fixtures.Valid.fsproj @@ -1,7 +1,7 @@ - net10.0 + net11.0 false false enable diff --git a/tests/FScript.Cli.Tests.Fixtures.Valid/NuGetFixture.fs b/tests/FScript.Cli.Tests.Fixtures.Valid/NuGetFixture.fs index 8dc35ee5..25ed04f5 100644 --- a/tests/FScript.Cli.Tests.Fixtures.Valid/NuGetFixture.fs +++ b/tests/FScript.Cli.Tests.Fixtures.Valid/NuGetFixture.fs @@ -24,7 +24,7 @@ type NuGetFixture() = use writer = new StreamWriter(entry.Open()) writer.Write($"{packageName}{version}FScript testsOffline extension fixture{dependencies}") for assembly in assemblyPaths do - archive.CreateEntryFromFile(assembly, "lib/net10.0/" + Path.GetFileName assembly) |> ignore + archive.CreateEntryFromFile(assembly, "lib/net11.0/" + Path.GetFileName assembly) |> ignore member this.AddProvider(version: string) = this.AddPackage(name, version, [| typeof.Assembly.Location |], "") member _.WriteManifest(version: string) = diff --git a/tests/FScript.Cli.Tests/CliTests.fs b/tests/FScript.Cli.Tests/CliTests.fs index 5c1e34a1..0afbacdb 100644 --- a/tests/FScript.Cli.Tests/CliTests.fs +++ b/tests/FScript.Cli.Tests/CliTests.fs @@ -704,7 +704,7 @@ type CliTests() = let directory = Path.Combine(Path.GetTempPath(), $"fscript-command-config-{Guid.NewGuid():N}") Directory.CreateDirectory(directory) |> ignore try - let providerFile = Path.GetFileName(validProviderAssemblyPath ()) |> nonNull + let providerFile = Path.GetFileName(validProviderAssemblyPath ()) File.Copy(validProviderAssemblyPath (), Path.Combine(directory, providerFile)) File.WriteAllText(Path.Combine(directory, "fscript.toml"), $"[runtime]\nextern-assemblies = ['{providerFile}']") let script = Path.Combine(directory, "main.fss") @@ -745,7 +745,7 @@ type CliTests() = Assert.That(code, Is.Zero, output + error) let executable = Path.Combine(published, if OperatingSystem.IsWindows() then "fscript.exe" else "fscript") let script = Path.Combine(directory, "answer.fss") - let providerFile = Path.GetFileName(validProviderAssemblyPath ()) |> nonNull + let providerFile = Path.GetFileName(validProviderAssemblyPath ()) File.Copy(validProviderAssemblyPath (), Path.Combine(directory, providerFile)) File.WriteAllText(Path.Combine(directory, "fscript.toml"), $"[runtime]\nextern-assemblies = ['{providerFile}']") File.WriteAllText(script, "Ext.answer") diff --git a/tests/FScript.Cli.Tests/FScript.Cli.Tests.fsproj b/tests/FScript.Cli.Tests/FScript.Cli.Tests.fsproj index 166ecb75..1f0ae793 100644 --- a/tests/FScript.Cli.Tests/FScript.Cli.Tests.fsproj +++ b/tests/FScript.Cli.Tests/FScript.Cli.Tests.fsproj @@ -1,7 +1,7 @@ - net10.0 + net11.0 false false enable diff --git a/tests/FScript.Compiler.Tests/CseTests.fs b/tests/FScript.Compiler.Tests/CseTests.fs index 49e17c9b..a124743b 100644 --- a/tests/FScript.Compiler.Tests/CseTests.fs +++ b/tests/FScript.Compiler.Tests/CseTests.fs @@ -14,7 +14,7 @@ type CseTests() = let add a b=expr TInt (Lir.Operation(Lir.IntAdd,[a;b])) let tuple values=expr (TTuple(List.map (fun (v: Lir.Expression) -> v.Type) values)) (Lir.Tuple values) let empty entry : Lir.Program={Types=[];ImportedRecords=[];Functions=[];Declarations=[];Entry=Some entry} - let count label program=(Lir.format program).Split('\n') |> Array.filter (fun line -> line.TrimStart().StartsWith(label,StringComparison.Ordinal)) |> Array.length + let count (label: string) program=(Lir.format program).Split('\n') |> Array.filter (fun line -> line.TrimStart().StartsWith(label,StringComparison.Ordinal)) |> Array.length let optimize p=LirCommonSubexpressions.optimize p let compile externs purity source = let p=match Compiler.compileWithPurity purity {Program=Parser.parseProgram source;Externs=externs} with Ok p -> p.Lir | Error errors -> failwith (string errors) diff --git a/tests/FScript.Compiler.Tests/FScript.Compiler.Tests.fsproj b/tests/FScript.Compiler.Tests/FScript.Compiler.Tests.fsproj index 6760ca8b..502a6ec0 100644 --- a/tests/FScript.Compiler.Tests/FScript.Compiler.Tests.fsproj +++ b/tests/FScript.Compiler.Tests/FScript.Compiler.Tests.fsproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 false false diff --git a/tests/FScript.Conformance.Tests/FScript.Conformance.Tests.fsproj b/tests/FScript.Conformance.Tests/FScript.Conformance.Tests.fsproj index 1b947dbc..dc3ab118 100644 --- a/tests/FScript.Conformance.Tests/FScript.Conformance.Tests.fsproj +++ b/tests/FScript.Conformance.Tests/FScript.Conformance.Tests.fsproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 false false diff --git a/tests/FScript.DebugAdapter.Tests/AdapterTests.js b/tests/FScript.DebugAdapter.Tests/AdapterTests.js index 683bc18a..ab691972 100644 --- a/tests/FScript.DebugAdapter.Tests/AdapterTests.js +++ b/tests/FScript.DebugAdapter.Tests/AdapterTests.js @@ -7,7 +7,7 @@ const { spawn } = require('node:child_process'); const { waitForMessage } = require('./EventWait'); const root = path.resolve(__dirname, '../..'); -const cli = process.env.FSCRIPT_DEBUG_CLI || path.join(root, 'src/FScript/bin/Release/net10.0/fscript.dll'); +const cli = process.env.FSCRIPT_DEBUG_CLI || path.join(root, 'src/FScript/bin/Release/net11.0/fscript.dll'); class Client { constructor() { this.process = spawn(cli.endsWith('.dll') ? 'dotnet' : cli, cli.endsWith('.dll') ? [cli, '--debug-adapter'] : ['--debug-adapter'], { cwd: root, stdio: ['pipe', 'pipe', 'pipe'] }); diff --git a/tests/FScript.Interpreter.Lir.Tests/FScript.Interpreter.Lir.Tests.fsproj b/tests/FScript.Interpreter.Lir.Tests/FScript.Interpreter.Lir.Tests.fsproj index 652fa5f2..610b3fed 100644 --- a/tests/FScript.Interpreter.Lir.Tests/FScript.Interpreter.Lir.Tests.fsproj +++ b/tests/FScript.Interpreter.Lir.Tests/FScript.Interpreter.Lir.Tests.fsproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 false false diff --git a/tests/FScript.Language.Tests/FScript.Language.Tests.fsproj b/tests/FScript.Language.Tests/FScript.Language.Tests.fsproj index 6fb3b369..a02a664e 100644 --- a/tests/FScript.Language.Tests/FScript.Language.Tests.fsproj +++ b/tests/FScript.Language.Tests/FScript.Language.Tests.fsproj @@ -1,7 +1,7 @@ - net10.0 + net11.0 false false enable diff --git a/tests/FScript.LanguageServer.Tests/FScript.LanguageServer.Tests.csproj b/tests/FScript.LanguageServer.Tests/FScript.LanguageServer.Tests.csproj index 7ea2792e..fc3e7980 100644 --- a/tests/FScript.LanguageServer.Tests/FScript.LanguageServer.Tests.csproj +++ b/tests/FScript.LanguageServer.Tests/FScript.LanguageServer.Tests.csproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 false enable enable diff --git a/tests/FScript.LanguageServer.Tests/LspClient.cs b/tests/FScript.LanguageServer.Tests/LspClient.cs index 247905c8..215ee3d9 100644 --- a/tests/FScript.LanguageServer.Tests/LspClient.cs +++ b/tests/FScript.LanguageServer.Tests/LspClient.cs @@ -41,7 +41,7 @@ private static string FindRepoRoot() } var root = FindRepoRoot(); var serverProject = Path.Combine(root, "src", "FScript.LanguageServer", "FScript.LanguageServer.csproj"); - var serverDll = Path.Combine(root, "src", "FScript.LanguageServer", "bin", "Release", "net10.0", "FScript.LanguageServer.dll"); + var serverDll = Path.Combine(root, "src", "FScript.LanguageServer", "bin", "Release", "net11.0", "FScript.LanguageServer.dll"); var buildPsi = new ProcessStartInfo { diff --git a/tests/FScript.Runtime.Tests/FScript.Runtime.Tests.fsproj b/tests/FScript.Runtime.Tests/FScript.Runtime.Tests.fsproj index 769a963a..cda1a1a4 100644 --- a/tests/FScript.Runtime.Tests/FScript.Runtime.Tests.fsproj +++ b/tests/FScript.Runtime.Tests/FScript.Runtime.Tests.fsproj @@ -1,7 +1,7 @@ - net10.0 + net11.0 false false enable diff --git a/tests/FScript.Runtime.Tests/NuGetEnvironmentTests.fs b/tests/FScript.Runtime.Tests/NuGetEnvironmentTests.fs index 4f45ea63..5a166b61 100644 --- a/tests/FScript.Runtime.Tests/NuGetEnvironmentTests.fs +++ b/tests/FScript.Runtime.Tests/NuGetEnvironmentTests.fs @@ -82,7 +82,7 @@ type NuGetEnvironmentTests() = use fixture = new NuGetFixture() let dependency = fixture.Name + ".Dependency" fixture.AddPackage(dependency, "1.0.0", [| typeof.Assembly.Location |], "") - fixture.AddPackage(fixture.Name, "1.0.0", [| typeof.Assembly.Location |], $"") + fixture.AddPackage(fixture.Name, "1.0.0", [| typeof.Assembly.Location |], $"") fixture.WriteManifest "1.0.0" let loaded = EnvironmentLoader.loadWithInfoAndPermissions FScript.Language.HostPermissions.All (settings fixture) |> get Assert.That(loaded.AssemblyPaths |> List.exists (fun p -> Path.GetFileName(p) = "FScript.Extensibility.dll"), Is.True) @@ -95,7 +95,7 @@ type NuGetEnvironmentTests() = let dependency = fixture.Name + ".Dependency" fixture.AddPackage(dependency, "1.0.0", [| typeof.Assembly.Location |], "") fixture.AddPackage(dependency, "2.0.0", [| typeof.Assembly.Location |], "") - fixture.AddPackage(fixture.Name, "1.0.0", [| typeof.Assembly.Location |], $"") + fixture.AddPackage(fixture.Name, "1.0.0", [| typeof.Assembly.Location |], $"") fixture.WriteManifest "1.0.0" File.AppendAllText(fixture.ConfigPath, $"\n[[runtime.packages]]\nname = '{dependency}'\nversion = '1.0.0'\n") match EnvironmentLoader.loadWithPermissions FScript.Language.HostPermissions.All (settings fixture) with @@ -141,7 +141,7 @@ type NuGetEnvironmentTests() = fixture.AddProvider "1.0.0" let consumer = fixture.Name + ".Consumer" let assembly = typeof.Assembly.Location - fixture.AddPackage(consumer, "1.0.0", [| assembly |], $"") + fixture.AddPackage(consumer, "1.0.0", [| assembly |], $"") fixture.WriteManifest "1.0.0" if not explicitOwner then File.WriteAllText(fixture.ConfigPath, "") File.AppendAllText(fixture.ConfigPath, $"\n[[runtime.packages]]\nname = '{consumer}'\nversion = '1.0.0'\n") @@ -172,7 +172,7 @@ type NuGetEnvironmentTests() = stream.Close() let dependency = fixture.Name + ".Collision" fixture.AddPackage(dependency, "1.0.0", [| alternate |], "") - fixture.AddPackage(fixture.Name, "1.0.0", [| original |], $"") + fixture.AddPackage(fixture.Name, "1.0.0", [| original |], $"") fixture.WriteManifest "1.0.0" match EnvironmentLoader.loadWithPermissions FScript.Language.HostPermissions.All (settings fixture) with | Ok _ -> Assert.Fail "Conflicting CLR identities were accepted" diff --git a/tests/FScript.VscodeDebug.Tests/index.js b/tests/FScript.VscodeDebug.Tests/index.js index 6f5d41de..d834c2cd 100644 --- a/tests/FScript.VscodeDebug.Tests/index.js +++ b/tests/FScript.VscodeDebug.Tests/index.js @@ -18,7 +18,7 @@ exports.run = async function run() { const fs = require('node:fs'); const path = require('node:path'); const repo = path.resolve(__dirname, '../..'); - const provider = path.join(repo, 'tests/FScript.Cli.Tests.Fixtures.Valid/bin/Release/net10.0/FScript.Cli.Tests.Fixtures.Valid.dll'); + const provider = path.join(repo, 'tests/FScript.Cli.Tests.Fixtures.Valid/bin/Release/net11.0/FScript.Cli.Tests.Fixtures.Valid.dll'); assert.ok(fs.existsSync(provider), 'Build the real provider fixture before the smoke test'); const ffiDirectory = path.join(folder.uri.fsPath, 'numerics/examples'); const plainDirectory = path.join(folder.uri.fsPath, 'other/examples'); diff --git a/vscode-fscript/README.md b/vscode-fscript/README.md index 559a5514..60cdc58d 100644 --- a/vscode-fscript/README.md +++ b/vscode-fscript/README.md @@ -83,7 +83,7 @@ The extension starts the language server with one of these strategies: 1. Custom path from `fscript.server.path` (if configured) 2. Packaged server: `server/FScript.LanguageServer.dll` -3. Local development fallback: builds `../src/FScript.LanguageServer/FScript.LanguageServer.csproj` and runs `bin/Debug/net10.0/FScript.LanguageServer.dll` +3. Local development fallback: builds `../src/FScript.LanguageServer/FScript.LanguageServer.csproj` and runs `bin/Debug/net11.0/FScript.LanguageServer.dll` Map annotations use postfix forms such as `string map[int]` and `string map[Priority]`. String-keyed maps appear as `string map`, including when annotated with `map[string]`. Hover and inlay hints preserve inferred key types. @@ -153,7 +153,7 @@ workspace-folder settings to the resulting DLL, for example: ```json { - "fscript.cli.path": "/absolute/path/to/FScript/src/FScript/bin/Release/net10.0/fscript.dll" + "fscript.cli.path": "/absolute/path/to/FScript/src/FScript/bin/Release/net11.0/fscript.dll" } ``` diff --git a/vscode-fscript/extension.js b/vscode-fscript/extension.js index 7e5b6514..27dca558 100644 --- a/vscode-fscript/extension.js +++ b/vscode-fscript/extension.js @@ -128,7 +128,7 @@ async function createServerOptions(context, config, folder) { 'FScript.LanguageServer', 'bin', 'Debug', - 'net10.0', + 'net11.0', 'FScript.LanguageServer.dll' ); diff --git a/website/docs/compiler/compilation.md b/website/docs/compiler/compilation.md index 400a0855..e408cf55 100644 --- a/website/docs/compiler/compilation.md +++ b/website/docs/compiler/compilation.md @@ -10,7 +10,7 @@ FScript can run inside a host application or compile into a program that runs on | Output | Command options | Use it when | | --- | --- | --- | -| .NET assembly | `--target dotnet` | You want compiled execution with FScript's assembly optimizations. Run the DLL with .NET 10. | +| .NET assembly | `--target dotnet` | You want compiled execution with FScript's assembly optimizations. Run the DLL with .NET 11. | | Self-contained executable | `--target dotnet --single-file [--runtime ]` | You want one distributable executable that includes the .NET runtime. | | Native AOT executable | `--target dotnet --aot [--runtime ]` | You want dependencies trimmed and compiled into a native executable. | | C# project | `--target csharp` | You want to inspect, edit, or integrate generated source in a .NET build. | diff --git a/website/docs/compiler/compile-to-csharp.md b/website/docs/compiler/compile-to-csharp.md index 1c640711..420d1c87 100644 --- a/website/docs/compiler/compile-to-csharp.md +++ b/website/docs/compiler/compile-to-csharp.md @@ -4,7 +4,7 @@ title: Compile to C# slug: /compiler/csharp --- -The C# backend writes an independently buildable .NET 10 project. Use it when generated source belongs in your build, when you need to inspect a translated program, or when you want to make further changes in C#. +The C# backend writes an independently buildable .NET 11 project. Use it when generated source belongs in your build, when you need to inspect a translated program, or when you want to make further changes in C#. For FScript's additional call, closure, tail-recursion, and pruning optimizations, use the [.NET assembly target](./compile-to-dotnet.md). Building generated C# does not enable those assembly-only passes. @@ -16,7 +16,7 @@ dotnet build out/hello-csharp/Program.csproj -c Release dotnet run --project out/hello-csharp/Program.csproj -c Release -- Ada ``` -Building the generated project requires the .NET 10 SDK. From the FScript checkout, generation can instead use: +Building the generated project requires the .NET 11 SDK. From the FScript checkout, generation can instead use: ```sh dotnet run --project src/FScript -- compile samples/hello.fss --target csharp --output out/hello-csharp diff --git a/website/docs/compiler/compile-to-dotnet.md b/website/docs/compiler/compile-to-dotnet.md index a615f644..fc502b18 100644 --- a/website/docs/compiler/compile-to-dotnet.md +++ b/website/docs/compiler/compile-to-dotnet.md @@ -10,11 +10,11 @@ The .NET backend compiles a typed FScript program into an optimized .NET assembl | Operation | Requirements | | --- | --- | -| Generate a `.dll` with `--target dotnet` | FScript and a .NET 10 runtime; no SDK required. Roslyn is bundled with FScript and emits the assembly in-process. | -| Publish with `--single-file` | .NET 10 SDK available through `dotnet` on PATH. | -| Publish with `--aot` | .NET 10 SDK plus the target platform's native build tools; build on the target OS. | +| Generate a `.dll` with `--target dotnet` | FScript and a .NET 11 runtime; no SDK required. Roslyn is bundled with FScript and emits the assembly in-process. | +| Publish with `--single-file` | .NET 11 SDK available through `dotnet` on PATH. | +| Publish with `--aot` | .NET 11 SDK plus the target platform's native build tools; build on the target OS. | -Running FScript itself from source with `dotnet run` requires the SDK to build FScript. That is separate from the installed compiler's requirements. A generated ordinary DLL needs a .NET 10 runtime to run; published single-file and AOT executables do not require a .NET installation on the destination machine. +Running FScript itself from source with `dotnet run` requires the SDK to build FScript. That is separate from the installed compiler's requirements. A generated ordinary DLL needs a .NET 11 runtime to run; published single-file and AOT executables do not require a .NET installation on the destination machine. ## Runnable .NET assembly @@ -25,7 +25,7 @@ dotnet out/fibonacci-dotnet/fibonacci.dll Compiled entry points print the final value by default. Add `--no-result` when compiling to suppress it and allow proven-pure discarded computations to be pruned. Explicit output, failures, and exit-code writes remain observable. Without this flag, library callers can retrieve the typed value through `Run` and format it explicitly with `FormatResult`; in discard mode, `Run` returns unit. -Output includes a `.dll`, runtime configuration, and required external managed dependencies. The minimum runtime is .NET 10. Arguments after the assembly name become `Env.Arguments`. +Output includes a `.dll`, runtime configuration, and required external managed dependencies. The minimum runtime is .NET 11. Arguments after the assembly name become `Env.Arguments`. ```sh dotnet run --project src/FScript -- compile samples/basic/basic.fss --target dotnet --output out/basic-dotnet @@ -85,7 +85,7 @@ Without that separator, `dotnet run` can consume `--runtime` itself and fail whi Windows output has an `.exe` extension; macOS and Linux output has no extension. Use a fresh output directory when switching from DLL output: existing files are not deleted. External data such as BASIC source files remains program input and is not bundled. -Publishing requires a .NET 10 SDK on the build machine and may restore runtime/compiler packs from NuGet. Native AOT additionally requires the platform's native build tools (Xcode Command Line Tools on macOS; Clang and zlib headers on Linux; Visual Studio C++ build tools on Windows). Native AOT must be built on the target OS; single-file managed publishing can target another OS. The executables still use normal OS libraries. See Microsoft's [single-file](https://learn.microsoft.com/dotnet/core/deploying/single-file/) and [Native AOT](https://learn.microsoft.com/dotnet/core/deploying/native-aot/) deployment documentation. +Publishing requires a .NET 11 SDK on the build machine and may restore runtime/compiler packs from NuGet. Native AOT additionally requires the platform's native build tools (Xcode Command Line Tools on macOS; Clang and zlib headers on Linux; Visual Studio C++ build tools on Windows). Native AOT must be built on the target OS; single-file managed publishing can target another OS. The executables still use normal OS libraries. See Microsoft's [single-file](https://learn.microsoft.com/dotnet/core/deploying/single-file/) and [Native AOT](https://learn.microsoft.com/dotnet/core/deploying/native-aot/) deployment documentation. Single-file publishing trims dependencies when all reachable FFI calls have static CLR bindings. Reachable legacy provider dispatch disables managed trimming to preserve its registration contract. Bundled native runtime libraries may be extracted by the .NET host at startup. Native AOT trims and compiles dependencies, so FFI libraries must be AOT-compatible. Dynamic loading or reflection-heavy providers may produce SDK diagnostics instead of a runnable native binary. Packaging failures are reported as `FSN710x`, including the SDK's diagnostics. @@ -143,7 +143,7 @@ For the teapot example, `samples/ffi/fscript.toml` supplies the provider path: ```toml [runtime] -extern-assemblies = ["Provider/bin/Release/net10.0/FScript.Ffi.Sample.dll"] +extern-assemblies = ["Provider/bin/Release/net11.0/FScript.Ffi.Sample.dll"] ``` Build the provider first, then analyze or compile without extra assembly flags: diff --git a/website/docs/examples/ffi-graphics.md b/website/docs/examples/ffi-graphics.md index 0cec4ffa..3d1102a1 100644 --- a/website/docs/examples/ffi-graphics.md +++ b/website/docs/examples/ffi-graphics.md @@ -22,7 +22,7 @@ Execution starts in `main.fss`, which loads the scene and starts rendering throu ### One-time provider setup -Check out the [FScript repository](https://github.com/MagnusOpera/FScript) and build the provider library with the .NET 10 SDK before the first run: +Check out the [FScript repository](https://github.com/MagnusOpera/FScript) and build the provider library with the .NET 11 SDK before the first run: ```sh dotnet build samples/ffi/Provider/FfiSample.fsproj -c Release @@ -67,7 +67,7 @@ The sample enables `size-optimized = true` in its manifest to trade culture supp On macOS ARM64 with .NET SDK 10.0.403, the executable shrank from 4,378,616 bytes to 2,181,464 bytes with ordinary AOT, or 1,882,776 bytes with `--size-optimized`. Both profiles passed headless and real OpenGL checks. Sizes depend on SDK and platform; see [Native AOT executable size](../compiler/compile-to-dotnet.md#native-aot-executable-size) for the investigation and runtime tradeoffs. -The compiler reports its phases and output path. The result is one executable, `main.exe` on Windows. Publishing requires the .NET 10 SDK and the platform's native compiler; running the result requires no .NET installation. The provider supplies static CLR companions and typed setup/render delegates. GLFW binaries are embedded in the renderer and extracted only for graphical startup. Desktop graphics and OpenGL drivers are still required for a window. +The compiler reports its phases and output path. The result is one executable, `main.exe` on Windows. Publishing requires the .NET 11 SDK and the platform's native compiler; running the result requires no .NET installation. The provider supplies static CLR companions and typed setup/render delegates. GLFW binaries are embedded in the renderer and extracted only for graphical startup. Desktop graphics and OpenGL drivers are still required for a window. ## Find your way through the files @@ -249,7 +249,7 @@ Build the sample in Release, then run **FScript: Select Configuration** in VS Co ```toml [runtime] -extern-assemblies = ["Provider/bin/Release/net10.0/FScript.Ffi.Sample.dll"] +extern-assemblies = ["Provider/bin/Release/net11.0/FScript.Ffi.Sample.dll"] ``` The path is relative to the manifest. In a trusted workspace, the editor loads the provider's descriptors and schemes for completion, hover, and diagnostics. Provider discovery creates no window or GPU resources. If several manifests exist in the workspace, select this one explicitly. diff --git a/website/docs/reference/cli-reference.md b/website/docs/reference/cli-reference.md index 125f8650..541a5e94 100644 --- a/website/docs/reference/cli-reference.md +++ b/website/docs/reference/cli-reference.md @@ -45,7 +45,7 @@ Compiled executables display the final value by default. Compile with `--no-resu These targets support .NET FFI providers selected by the normal environment configuration. See [Compile to .NET](../compiler/compile-to-dotnet.md) and [Compile to C#](../compiler/compile-to-csharp.md). -For a self-contained executable, add `--single-file` to the .NET target. For a Native AOT executable, use `--aot`. Publishing defaults to the current platform; pass `--runtime ` to select another target. An explicitly supplied `--runtime` requires a value. Runtime identifiers use .NET names such as `osx-arm64`, `linux-x64`, and `win-x64`. Both options require a .NET 10 SDK for publishing and are rejected for other backends. Add `--size-optimized` with `--aot` to use invariant globalization, resource-key framework errors, and disable runtime stack traces and EventSource. Ordinary `--aot` keeps those capabilities. See [Native AOT executable size](../compiler/compile-to-dotnet.md#native-aot-executable-size) for measurements and tradeoffs. +For a self-contained executable, add `--single-file` to the .NET target. For a Native AOT executable, use `--aot`. Publishing defaults to the current platform; pass `--runtime ` to select another target. An explicitly supplied `--runtime` requires a value. Runtime identifiers use .NET names such as `osx-arm64`, `linux-x64`, and `win-x64`. Both options require a .NET 11 SDK for publishing and are rejected for other backends. Add `--size-optimized` with `--aot` to use invariant globalization, resource-key framework errors, and disable runtime stack traces and EventSource. Ordinary `--aot` keeps those capabilities. See [Native AOT executable size](../compiler/compile-to-dotnet.md#native-aot-executable-size) for measurements and tradeoffs. Continue with [Compilation](../compiler/compilation.md), [Compilation and optimizations](../compiler/compiler-optimizations.md), or [Interpret IR](../compiler/interpret-ir.md).