diff --git a/src/FSharp.Build/FSharp.Build.fsproj b/src/FSharp.Build/FSharp.Build.fsproj index b689f90f1a8..b38e2981b7b 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..0478d36201d --- /dev/null +++ b/src/FSharp.Build/GenerateILLinkSubstitutions.fs @@ -0,0 +1,93 @@ +// 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 diff --git a/src/FSharp.Build/Microsoft.FSharp.NetSdk.targets b/src/FSharp.Build/Microsoft.FSharp.NetSdk.targets index 2b121a778b2..6b38487d22c 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 + + + + + + + + + +