Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

/deterministic msbuild flag does not create deterministic .winmd files #23456

Open
martinsuchan opened this issue Nov 29, 2017 · 10 comments
Open
Labels
Area-External Concept-Determinism The issue involves our ability to support determinism in binaries and PDBs created at build time. Feature Request
Milestone

Comments

@martinsuchan
Copy link

I'm trying to make perfect deterministic/reproducible builds for our C# UWP app.
Source: http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html

The flag /deterministic works for standard UWP apps and libs (.exe and .dll files), but not for .winmd files created for Windows Runtime Components.

Version Used:
Using VS 15.4.5, msbuild 15.4.8.50001

Steps to Reproduce:
The attachment contains repro with simple Hello World UWP app with simple Windows Runtime Component: ReproTest.zip

  1. Build it using the build.ps1 command and extract the ReproTest_1.0.0.0_x86_bundle.appxupload to a new folder. Extract all files within this package and all nested appx packages.
  2. Build the project for a second time and extract the second .appxupload to a different folder.
  3. Compare these two folders. Ideally both should contain exactly same files.

The repro already includes two builds, that can be compared using the compare.ps1 script

Expected Behavior:
When using /deterministic flag and building UWP Windows Runtime Component in the same directory multiple times, the created .winmd files should be always byte-to-byte identical.

Actual Behavior:
The .winmd files created by the steps above are different each time.

Note the created .pri files are also different, maybe I should create another ticket for making the MakePri.exe tool deterministic as well?

@tmat
Copy link
Member

tmat commented Nov 29, 2017

WinRT components built from C# are built in two steps - the Roslyn compiler produces an intermediary file that is transformed by WinMDExp tool. That tool is not deterministic. This is not a bug in Roslyn compilers, although it can be argued that we shouldn't need this extra post-processing step and the compilers should produce .winmd files directly.

@martinsuchan
Copy link
Author

Hi, any chance to forward this issue to .NET Native team that is maintaining the WinMDExp and MakePri tools? It would be really useful if these tools supported deterministic builds as well with optional flags, thanks!

@jcouv
Copy link
Member

jcouv commented Nov 30, 2017

Tagging @MichalStrehovsky
I'm not sure how .NET Native tracks such feature requests.

@jcouv jcouv added Area-External Concept-Determinism The issue involves our ability to support determinism in binaries and PDBs created at build time. Feature Request labels Nov 30, 2017
@MichalStrehovsky
Copy link
Member

.NET Native team doesn't own WinMDExp or MakePri. WinMDExp is part of the (desktop CLR) .NET SDK and MakePri is part of the Windows SDK. I don't know how those are tracked either.

@MichalStrehovsky
Copy link
Member

Maybe cc @russellhadley for the WinMDExp?

@martinsuchan
Copy link
Author

Here's the thought that started all this:

Windows Microsoft Store uses when updating apps differential updates, where only modified file blocks since the last version are downloaded.
Let's say our UWP app, which is used by 100 000 users, consists of 6 projects, each producing 100KB DLL during the build process.

We plan to release update with changes only in one project. Without deterministic builds the build process for Store creates 6 new different DLLs inside the appxupload package, or 3x6 DLLs in case of build for x86, x64 and ARM. That's 1.8MB update size for 100K users for change in just one project.

With deterministic builds only one changed DLL will be produced per platform, making the update size only 300KB per user. That's 150GB less traffic just for one update of one app in Microsoft Store.
Using deterministic build process for all UWP Store packages by default could save terabytes of traffic each day, basically for free! This is not just a cosmetic change, this could save real money at the end.

@MichalStrehovsky
Copy link
Member

Here's the thought that started all this

Oh, okay - deterministic IL assemblies won't help much with this. The appxupload file is not what the user will download to their device.

Once appxupload bundle is received by the Store, it gets compiled to native code with the .NET Native compiler. At that point all the input IL files get compiled down to native code and produces a single DLL with native code in it for the entire app (you can have a look at it by inspecting the outputs of a Release build of your app).

This process is deterministic. But: at the point of native compilation, global/whole program optimizations are applied to the program. The change in the single input assembly can have ripple effects on this native DLL that can completely invalidate all 64 kB blocks within the file (shift things around enough so that a block based differential update will be invalidated).

.NET Native tries to at least move type information to the beginning of the file so that code changes that don't affect the shape of types don't invalidate the section, but we haven't made investments beyond that.

There are differential update techniques that better apply to native code, but I don't know if Store uses them.

@gafter
Copy link
Member

gafter commented Aug 2, 2019

Moving to a sooner release so we can track forwarding this to an appropriate product team.

@martinsuchan
Copy link
Author

Hi, are there any news regarding deterministic .winmd builds? It has been three years since the last update, thanks.

@jaredpar
Copy link
Member

I think the best approach here is to file a VS feedback bug. That will get the issue routed to the appropriate team here and it will be more meaningful if it's coming from a customer. If you post the link to the issue here I can keep an eye on it and see who ends up with it.

There really isn't much we can do though in terms of our pipeline as these tools exist outside of it. The artifacts we produce are deterministic to my understanding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-External Concept-Determinism The issue involves our ability to support determinism in binaries and PDBs created at build time. Feature Request
Projects
None yet
Development

No branches or pull requests

7 participants