_Microsoft.Android.Resource.Designer.dll carries the build's wall-clock time as its PE TimeDateStamp, so Release builds are not reproducible (GenerateResourceDesignerAssembly passes no WriterParameters.Timestamp)
维护者通常 1 天内回复
评估
这个 Issue 还没有评估数据。
描述
Android framework version
net10.0-android
Affected platform version
.NET SDK 10.0.303, workload set 10.0.302.1, Microsoft.Android.Sdk.Windows 36.1.69, Microsoft.NETCore.App.Runtime.Mono.android-arm64 10.0.10, MAUI 10.0.110, Windows 11 x64 host. The generator source on main as of 2026-10-14 (src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs) shows the same code path.
Description
I am working towards reproducible Release builds of a MAUI Android app (OWASP MASWE-0075). With the toolchain pinned (global.json, lock files), deterministic passed to the Mono AOT compiler, --deterministic to the trimmer and ContinuousIntegrationBuild=true, two builds of one commit from a clean obj still differ, and the first stage at which a difference appears is the generated obj/Release/net10.0-android/_Microsoft.Android.Resource.Designer.dll.
Between two builds of the same commit that file differs in exactly 18 bytes:
- the COFF header
TimeDateStamp(file offsets 137-140), which is the wall-clock time of the build:0x6acf16c1(2026-10-14 05:44:33Z) in one build,0x6acf1946in the next; - the 16-byte MVID in the
#GUIDheap, which Cecil derives by hashing the written image, stamp included, whenDeterministicMvidis set.
As far as I can read it, GenerateResourceDesignerAssembly writes with new WriterParameters { DeterministicMvid = Deterministic } and no Timestamp, and Cecil's ModuleDefinition initialises a new module's timestamp from DateTime.UtcNow (Mono.Cecil/ModuleDefinition.cs), so every build gets a new stamp and, from it, a new "deterministic" MVID. Cecil reads no environment variable such as SOURCE_DATE_EPOCH.
The difference cascades. Roslyn's portable PDB records each metadata reference's MVID, so the application assembly's own deterministic outputs change too: 72 bytes (PE stamp, MVID, PDB id, PDB checksum), IL and metadata otherwise byte-identical. Downstream, libassembly-store.so, libxamarin-app.so (the type map) and the two libaot-*.dll.so images for these assemblies differ by those ids. In my measurement that accounts for 8 of the 16 entries that still differ between two clean builds of one commit (the other 8 are a separate Mono AOT compiler matter, reported on dotnet/runtime).
Expected: with Deterministic true, the generated designer assembly is byte-identical for identical inputs, for example WriterParameters.Timestamp set to a fixed value, to a value derived from the content (as Roslyn does), or to SOURCE_DATE_EPOCH when it is set.
Steps to Reproduce
dotnet new maui -n Reprotargeting net10.0-android; leaveDeterministicat its default (true).dotnet publish -f net10.0-android -c Release; copyobj/Release/net10.0-android/_Microsoft.Android.Resource.Designer.dllaside.- Delete
binandobj; publish again. - Compare the two copies:
cmp -llists 18 differing bytes (offsets 137-140 and the 16 bytes of the MVID in the GUID heap);[System.Reflection.Assembly]::ReflectionOnlyLoadFrom(path).ManifestModule.ModuleVersionIddiffers between the two; theTimeDateStampread ate_lfanew + 8is each build's wall-clock time.
Did you find any workaround?
No. AndroidUseDesignerAssembly=false (the designer as C# source) stops with XA1034 as soon as a referenced library uses the designer assembly; Microsoft.Maui.Controls, Microsoft.Maui and Microsoft.Identity.Client all do. Rewriting the generated file with a fixed timestamp in a custom target would work, but a custom step over a generated file is not something I want to maintain.
Relevant log output
cmp -l build1/_Microsoft.Android.Resource.Designer.dll build2/_Microsoft.Android.Resource.Designer.dll
18 bytes differ: offsets 137-138 (within the TimeDateStamp at 137-140) and 702925-702940 (the MVID), file size 731648 in both
PE TimeDateStamp: build1 0x6acf16c1 (2026-10-14 05:44:33Z), build2 0x6acf1946 (2026-10-14 05:55:18Z)
MVID: build1 7b52a131-b4f4-49f8-af05-f1f48b2279f9, build2 fd067989-df7b-4d27-bc12-a1e00dffd964
Application assembly from the same two builds (Roslyn, Deterministic + ContinuousIntegrationBuild):
72 bytes differ: 137-140 (TimeDateStamp), 708901-708916 (MVID), 779129-779132, 779213-779228 (PDB id), 779307-779338 (PDB checksum)
- 主要语言
- C#
- 星标
- 2.1k
- 派生
- 581
- 平均合并
- 1 天 23 小时
- 30 天内合并 PR
- 243
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 没有贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
dotnet/android 的其他 Issue
-
Area: App+Library Build
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
Area: Mono.Android
难度 2/5 1-3 小时 新手友好度 65/100
dotnet/android#9192 · 4 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
Area: App+Library Build needs-triage
难度 4/5 3-5 天 新手友好度 22/100
维护者通常 1 天内回复
-
Area: App+Library Build needs-triage
难度 4/5 3-5 天 新手友好度 35/100
dotnet/android#13148 · 4 条评论 ·
维护者通常 1 天内回复
-
.NET 11 RC2 MAUI app fails to compile (NativeAOT) with MAUI Community Toolkit可能已有人在做 @simonrozsival 于 1 天前认领。 未关闭Area: App+Library Build needs-triage
难度 4/5 3-5 天 新手友好度 15/100
dotnet/android#13143 · 1 条评论 ·
维护者通常 1 天内回复
相似的 Issue
-
7.0
难度 2/5 1-3 小时 新手友好度 72/100
unoplatform/uno.extensions#3253 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 62/100
Sector-Vestige/Sector-Vestige#476 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100
PowerShell/platyPS#868 ·
-
S: Untriaged
难度 2/5 1-3 小时 新手友好度 62/100
Trauma-Station/Trauma-Station#5058 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 2 天内回复