Summary
src/targetPacks/Directory.Build.targets (the BuildIlFile target) invokes ilasm without the -deterministic flag. As a result, every assembled .dll (netstandard.dll, mscorlib.dll, the ~115 netfx-redist reference assemblies under Microsoft.NET.Build.Extensions/*/lib/) gets a fresh, wall-clock-derived PE TimeDateStamp and a fresh GUID-derived MVID on each invocation. This breaks reproducibility of these assemblies and cascades into every downstream C# DLL that references them.
Current code
<Target Name="BuildIlFile" DependsOnTargets="ResolveIlToolPaths">
<Error Condition="'$(IlasmPath)' == ''" Text="The 'IlasmPath' property must be set." />
<Exec Command="$(IlasmPath) $(IlFile) -dll -quiet -nologo "-output=$(OutputFile)""
IgnoreStandardErrorWarningFormat="true"
CustomErrorRegularExpression=": error : " />
</Target>
The <Exec> is missing -deterministic.
Proposed fix
- <Exec Command="$(IlasmPath) $(IlFile) -dll -quiet -nologo "-output=$(OutputFile)""
+ <Exec Command="$(IlasmPath) $(IlFile) -dll -quiet -nologo -deterministic "-output=$(OutputFile)""
IgnoreStandardErrorWarningFormat="true"
CustomErrorRegularExpression=": error : " />
ILAsm has supported -deterministic since dotnet/runtime#109091 (merged 2025-01-09, fixing dotnet/runtime#8293). With this flag, ILAsm:
- Computes the PE TimeDateStamp as a content hash with the upper bit set (per the deterministic-PE convention).
- Derives the MVID deterministically from the input.
- Emits a deterministic CodeView debug entry.
Cascade impact
This is a high-leverage fix. The reference assemblies produced by this target are referenced by virtually every Roslyn-compiled assembly in the SDK. Because Roslyn deterministic compilation hashes the byte content of every referenced metadata-resolved DLL into the consumer's MVID, every C# DLL compiled against these reference assemblies also drifts between builds — analyzers, source generators, the Razor toolchain, hot-reload assemblies, SBRP-built reference packages (Newtonsoft.Json, Microsoft.IdentityModel.*, Microsoft.Css.Parser, etc.), and so on.
In the dotnet/dotnet source-build SDK reproducibility test, this single root cause accounts for ~17 directly-affected reference assemblies and over a hundred cascade-affected downstream DLLs.
Long-term alternative
#1313 proposes replacing the IL/ILAsm-based targeting-pack generation with GenAPI/C# entirely. If that lands, this fix becomes moot. But until then, the one-line -deterministic addition is a strict improvement.
Context
Found while building the SDK reproducibility validation test for the dotnet/dotnet VMR (dotnet/source-build#5486). Resolution of this issue is important to meet the goal of reproducible builds: dotnet/source-build#4963
Summary
src/targetPacks/Directory.Build.targets(theBuildIlFiletarget) invokesilasmwithout the-deterministicflag. As a result, every assembled.dll(netstandard.dll, mscorlib.dll, the ~115 netfx-redist reference assemblies underMicrosoft.NET.Build.Extensions/*/lib/) gets a fresh, wall-clock-derived PE TimeDateStamp and a fresh GUID-derived MVID on each invocation. This breaks reproducibility of these assemblies and cascades into every downstream C# DLL that references them.Current code
The
<Exec>is missing-deterministic.Proposed fix
ILAsm has supported
-deterministicsince dotnet/runtime#109091 (merged 2025-01-09, fixing dotnet/runtime#8293). With this flag, ILAsm:Cascade impact
This is a high-leverage fix. The reference assemblies produced by this target are referenced by virtually every Roslyn-compiled assembly in the SDK. Because Roslyn deterministic compilation hashes the byte content of every referenced metadata-resolved DLL into the consumer's MVID, every C# DLL compiled against these reference assemblies also drifts between builds — analyzers, source generators, the Razor toolchain, hot-reload assemblies, SBRP-built reference packages (Newtonsoft.Json, Microsoft.IdentityModel.*, Microsoft.Css.Parser, etc.), and so on.
In the dotnet/dotnet source-build SDK reproducibility test, this single root cause accounts for ~17 directly-affected reference assemblies and over a hundred cascade-affected downstream DLLs.
Long-term alternative
#1313 proposes replacing the IL/ILAsm-based targeting-pack generation with GenAPI/C# entirely. If that lands, this fix becomes moot. But until then, the one-line
-deterministicaddition is a strict improvement.Context
Found while building the SDK reproducibility validation test for the dotnet/dotnet VMR (dotnet/source-build#5486). Resolution of this issue is important to meet the goal of reproducible builds: dotnet/source-build#4963