Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Auto-generate ILLink.Substitutions.xml to Remove F# Metadata Resources#18592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
Copilot wants to merge14 commits intomain
base:main
Choose a base branch
Loading
fromcopilot/fix-18591

Conversation

Copilot
Copy link
Contributor

@CopilotCopilotAI commentedMay 22, 2025
edited by T-Gro
Loading

Auto-generate ILLink.Substitutions.xml to Remove F# Metadata Resources

🎯 Problem Statement

F# assemblies contain embedded metadata resources (signature and optimization data) that significantly increase assembly size during .NET trimming scenarios. These resources, while useful for F# development tools and cross-assembly optimizations, are unnecessary in final trimmed applications and can add substantial bloat to the final binary.

The F# compiler generates multiple embedded resources with names like:

  • FSharpSignatureData.{AssemblyName} /FSharpSignatureDataB.{AssemblyName}
  • FSharpOptimizationData.{AssemblyName} /FSharpOptimizationDataB.{AssemblyName}
  • Compressed variants of the above
  • FSharpSignatureInfo.{AssemblyName} /FSharpOptimizationInfo.{AssemblyName}

Previously, developers had to manually createILLink.Substitutions.xml files to remove these resources during trimming, which was error-prone and required maintenance when assembly names changed.

🤖 Development Journey & Human Collaboration

This implementation was initially attempted by GitHub Copilot coding agent, but required significant human intervention to complete successfully:

Copilot's Contributions:

  • ✅ Created the basic MSBuild task structure inGenerateILLinkSubstitutions.fs
  • ✅ Implemented XML generation logic for ILLink substitution format
  • ✅ Added MSBuild target integration inMicrosoft.FSharp.NetSdk.targets
  • ✅ Created test project structure

Human Intervention Required:

  • 🔧Fixed build errors: Copilot introduced syntax errors ([<o>] instead of[<Output>]) that caused compilation failures
  • 🔧Corrected resource embedding: The generated XML file wasn't being properly embedded as a resource - required fixing target timing and MSBuild integration
  • 🔧Enhanced test infrastructure: Improved the test validation script to properly report actual vs expected file sizes for easier maintenance
  • 🔧Build system expertise: Ensured the test project correctly uses locally-built F# tools rather than SDK-shipped versions

This highlights both the potential and current limitations of AI coding agents - while Copilot could handle the core implementation patterns, it required human expertise for build system integration, debugging compilation errors, and ensuring proper MSBuild target execution order.

🔧 Technical Implementation

Core Components

1. MSBuild Task (GenerateILLinkSubstitutions.fs)

typeGenerateILLinkSubstitutions()=inherit Task()[<Required>]member valAssemblyName=""with get, set[<Output>]member valGeneratedItems=[||]: ITaskItem[]with get, set

The task systematically generates all F# metadata resource combinations:

  • Signature/Optimization ×Data/DataB ×Compressed/Uncompressed variants
  • PlusInfo variants for both signature and optimization data

2. Build Integration (Microsoft.FSharp.NetSdk.targets)

<TargetName="GenerateFSharpILLinkSubstitutions"BeforeTargets="AssignTargetPaths">  <GenerateILLinkSubstitutionsAssemblyName="$(AssemblyName)"IntermediateOutputPath="$(IntermediateOutputPath)">    <OutputTaskParameter="GeneratedItems"ItemName="EmbeddedResource" />  </GenerateILLinkSubstitutions></Target>

3. Generated Output Example

<?xml version="1.0" encoding="utf-8"?><linker>  <assemblyfullname="MyProject">    <resourcename="FSharpSignatureData.MyProject"action="remove"></resource>    <resourcename="FSharpOptimizationData.MyProject"action="remove"></resource><!-- ... all other variants ...-->  </assembly></linker>

Key Technical Decisions

  • Automatic Generation: No manual maintenance required - assembly name is injected automatically
  • Embedded Resource: The substitution file is embedded directly in the assembly, following .NET conventions
  • Build Timing: Runs beforeAssignTargetPaths to ensure proper MSBuild item processing
  • Comprehensive Coverage: Handles all current and historical F# metadata resource patterns

🧪 Testing & Validation

Added comprehensive test coverage intests/AheadOfTime/Trimming/FSharpMetadataResource_Trimming_Test/:

  • Integration Test: Verifies the MSBuild task runs correctly during compilation
  • Size Validation: Confirms trimmed assemblies are actually smaller (validates that resources are removed)
  • Build System Test: Ensures locally-built F# tools are used rather than SDK versions

Enhanced the test infrastructure (check.ps1) to provide better feedback when assembly sizes change, making maintenance easier for future developers.

📊 Impact & Benefits

  • Zero Configuration: Works automatically for all F# projects with trimming enabled
  • Significant Size Reduction: Removes potentially large metadata resources from final binaries
  • Maintenance-Free: No manual XML file creation or updates required
  • Backward Compatible: Doesn't affect existing projects or development workflows

🔗 Related Issues

Fixes#18591


This PR demonstrates the collaborative potential between AI coding agents and human developers - where AI can handle routine implementation patterns while humans provide the critical expertise for build systems, debugging, and ensuring production-quality integration.

@T-Gro
Copy link
Member

@copilot please do it

Copilot finished work on behalf ofT-GroMay 22, 2025 14:31
@github-actionsGitHub Actions
Copy link
Contributor

✅ No release notes required

@T-Gro
Copy link
Member

@copilot try now

Copilot finished work on behalf ofT-GroMay 22, 2025 15:18
@T-Gro
Copy link
Member

@copilot try now

Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
@CopilotCopilot SWE Agent
Copy link
ContributorAuthor

CopilotAI commentedMay 23, 2025
edited
Loading

@copilot try now

I've implemented the requested task to auto-generate ILLink.Substitutions.xml for removing F# metadata resources during trimming. The implementation includes:

  1. A newGenerateILLinkSubstitutions.fs task that generates the XML with resource name patterns for the current assembly
  2. Updated FSharp.Build.fsproj to include this new file
  3. Added a target in Microsoft.FSharp.NetSdk.targets that runs the task during build

Changes are in commit3aff8db. Next I'll be working on adding tests in the AheadOfTime/Trimming folder.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • x3yvsblobprodcus370.vsblob.vsassets.io
    • Triggering command:dotnet build src/FSharp.Build/FSharp.Build.fsproj (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
Copilot finished work on behalf ofT-GroMay 23, 2025 08:58
|]

// Generate the XML content
let sb = StringBuilder()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The size can be pre-detrmined upfront, use an overload of StringBuilder that takes initial capacity.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I've updated the code to pre-allocate the StringBuilder capacity by using the appropriate constructor overload with an initial capacity of 4096, which should be more than enough for our XML content. This change is in commit 74bce89.

Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
@CopilotCopilot SWE Agent
Copy link
ContributorAuthor

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • x3yvsblobprodcus370.vsblob.vsassets.io
    • Triggering command:dotnet build src/FSharp.Build/FSharp.Build.fsproj (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf ofT-GroMay 23, 2025 09:29
@T-Gro
Copy link
Member

@copilot :

The scriptcheck.ps1 reports an error, but it does not output theactual value. We need the actual value so that you can set it as the real expectation (I do realize that the value of-1 was just a placeholder).

Change the script so that it reports theactual values of sizes as well, and so that we can see them in build failures logs.

Right now the logs were just:

Publish and Execute: net9.0 - FSharpMetadataResource_Trimming_TestExpecting -1CheckTrim : Build failed with exit code 1At D:\a\_work\1\s\tests\AheadOfTime\Trimming\check.ps1:52 char:1

…placeholder -1Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
@CopilotCopilot SWE Agent
Copy link
ContributorAuthor

CopilotAI commentedJun 3, 2025

@copilot :

The scriptcheck.ps1 reports an error, but it does not output theactual value. We need the actual value so that you can set it as the real expectation (I do realize that the value o...

I've updated the check.ps1 script to report the actual file sizes when the expected length is the placeholder value -1. Now when the FSharpMetadataResource_Trimming_Test runs, it will output a message like "Actual net9.0 - trimmed FSharpMetadataResource_Trimming_Test.dll length: [actual_bytes] Bytes (expected length is placeholder -1, update test with this actual value)" so you can see the actual size in the build logs and update the test accordingly. Changes are in commit28d99ca.

Copilot finished work on behalf ofT-GroJune 3, 2025 08:55
@T-GroT-Gro changed the title[WIP] Auto-generate IlLink.Substitutions.xml to Remove F# Metadata ResourcesAuto-generate ILLink.Substitutions.xml to Remove F# Metadata ResourcesJul 11, 2025
@T-Gro
Copy link
Member

/run fantomas

github-actions[bot] reacted with thumbs up emoji

@T-GroT-Gro marked this pull request as ready for reviewJuly 11, 2025 16:13
@T-GroT-Gro requested a review froma team as acode ownerJuly 11, 2025 16:13
@github-actionsGitHub Actions
Copy link
Contributor

🔧 CLI Command Report

  • Command:/run fantomas
  • Outcome: success

✅ Patch applied:
- Files changed: 1
- Lines changed: 87

@T-GroT-Gro requested a review fromabonieJuly 11, 2025 16:17
@T-GroT-Groenabled auto-merge (squash)July 11, 2025 16:18
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@abonieabonieabonie approved these changes

@T-GroT-GroT-Gro approved these changes

Assignees

@T-GroT-Gro

Labels
None yet
Projects
Status: In Progress
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Auto-generate IlLink.Substitutions.xml to Remove F# Metadata Resources
4 participants
@Copilot@T-Gro@abonie@actions-user

[8]ページ先頭

©2009-2025 Movatter.jp