diff --git a/src/FSharp.Build/FSharp.Build.fsproj b/src/FSharp.Build/FSharp.Build.fsproj index 8f2fd4f5951..080c53399b1 100644 --- a/src/FSharp.Build/FSharp.Build.fsproj +++ b/src/FSharp.Build/FSharp.Build.fsproj @@ -46,6 +46,7 @@ + diff --git a/src/FSharp.Build/GenerateILLinkSubstitutions.fs b/src/FSharp.Build/GenerateILLinkSubstitutions.fs new file mode 100644 index 00000000000..3bf461ce928 --- /dev/null +++ b/src/FSharp.Build/GenerateILLinkSubstitutions.fs @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Build + +open System +open System.IO +open System.Text +open Microsoft.Build.Framework +open Microsoft.Build.Utilities + +/// +/// MSBuild task that generates ILLink.Substitutions.xml file to remove F# metadata resources during IL linking. +/// +type GenerateILLinkSubstitutions() = + inherit Task() + + /// + /// Assembly name to use when generating resource names to be removed. + /// + [] + member val AssemblyName = "" with get, set + + /// + /// Intermediate output path for storing the generated file. + /// + [] + member val IntermediateOutputPath = "" with get, set + + /// + /// Generated embedded resource items. + /// + [] + member val GeneratedItems = [| |] : ITaskItem[] with get, set + + override this.Execute() = + try + // Define the resource prefixes that need to be removed + let resourcePrefixes = + [| + // Signature variants + yield! [| for dataType in [| "Data"; "DataB" |] do + for compression in [| ""; "Compressed" |] do + yield $"FSharpSignature{compression}{dataType}" |] + + // Optimization variants + yield! [| for dataType in [| "Data"; "DataB" |] do + for compression in [| ""; "Compressed" |] do + yield $"FSharpOptimization{compression}{dataType}" |] + + // Info variants + yield "FSharpOptimizationInfo" + yield "FSharpSignatureInfo" + |] + + // Generate the XML content + let sb = StringBuilder(4096) // pre-allocate capacity + sb.AppendLine("") |> ignore + sb.AppendLine("") |> ignore + sb.AppendLine($" ") |> ignore + + // Add each resource entry with proper closing tag on the same line + for prefix in resourcePrefixes do + sb.AppendLine($" ") |> ignore + + // Close assembly and linker tags + sb.AppendLine(" ") |> ignore + sb.AppendLine("") |> ignore + + let xmlContent = sb.ToString() + + // Create a file in the intermediate output path + let outputFileName = Path.Combine(this.IntermediateOutputPath, "ILLink.Substitutions.xml") + Directory.CreateDirectory(this.IntermediateOutputPath) |> ignore + File.WriteAllText(outputFileName, xmlContent) + + // Create a TaskItem for the generated file + let item = TaskItem(outputFileName) :> ITaskItem + item.SetMetadata("LogicalName", "ILLink.Substitutions.xml") + + this.GeneratedItems <- [| item |] + true + with ex -> + this.Log.LogErrorFromException(ex, true) + false \ No newline at end of file diff --git a/src/FSharp.Build/Microsoft.FSharp.NetSdk.targets b/src/FSharp.Build/Microsoft.FSharp.NetSdk.targets index 2b121a778b2..6e3dbe14f2c 100644 --- a/src/FSharp.Build/Microsoft.FSharp.NetSdk.targets +++ b/src/FSharp.Build/Microsoft.FSharp.NetSdk.targets @@ -154,6 +154,18 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and true + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/AheadOfTime/Trimming/check.ps1 b/tests/AheadOfTime/Trimming/check.ps1 index 50a8a9e6422..4c3016c9e70 100644 --- a/tests/AheadOfTime/Trimming/check.ps1 +++ b/tests/AheadOfTime/Trimming/check.ps1 @@ -42,8 +42,11 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) { # NOTE: Trimming now errors out on desktop TFMs, as shown below: # error NETSDK1124: Trimming assemblies requires .NET Core 3.0 or higher. -# Check net7.0 trimmed assemblies +# Check net9.0 trimmed assemblies CheckTrim -root "SelfContained_Trimming_Test" -tfm "net9.0" -outputfile "FSharp.Core.dll" -expected_len 300032 -# Check net8.0 trimmed assemblies +# Check net9.0 trimmed assemblies with static linked FSharpCore CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net9.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 9150976 + +# Check net9.0 trimmed assemblies with F# metadata resources removed +CheckTrim -root "FSharpMetadataResource_Trimming_Test" -tfm "net9.0" -outputfile "FSharpMetadataResource_Trimming_Test.dll" -expected_len -1