[Build] Add per-file up-to-date check in CompileNativeAssembly#11055
Draft
davidnguyen-tech wants to merge 3 commits intodotnet:mainfrom
Draft
[Build] Add per-file up-to-date check in CompileNativeAssembly#11055davidnguyen-tech wants to merge 3 commits intodotnet:mainfrom
davidnguyen-tech wants to merge 3 commits intodotnet:mainfrom
Conversation
When _CompileNativeAssemblySources runs, it recompiles ALL .ll files even if only some have changed. This is because MSBuild's target-level Inputs/Outputs is all-or-nothing — if any .ll file is newer than any .o file, every file gets recompiled. Add a per-file timestamp check in RunAssembler() — if the output .o is newer than the input .ll, that file is skipped. This saves time on incremental CoreCLR builds where upstream generators use CopyIfStreamChanged to preserve .ll timestamps for unchanged files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add CompileNativeAssemblySourcesSkipsUnchangedFiles integration test that verifies on incremental CoreCLR builds, unchanged .ll files are not recompiled by the CompileNativeAssembly task while changed .ll files are still correctly compiled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
41fdedd to
f644fca
Compare
Remove build-specific MVID data from the CoreCLR debug typemap assemblies array, making the generated .ll files byte-identical across incremental builds when only C# code changes (no type additions/removals). Generator changes (TypeMappingDebugNativeAssemblyGeneratorCLR.cs): - Remove mvid_hash field from TypeMapAssembly struct - Remove MVID field (was already NativeAssembler-ignored) - Sort data.UniqueAssemblies by name before building the assembly names blob, ensuring deterministic blob offsets - Sort uniqueAssemblies list by Name instead of mvid_hash Runtime changes (typemap.cc, xamarin-app.hh): - Remove mvid_hash from the native TypeMapAssembly struct - Replace MVID-based binary search with assembly iteration: for each assembly, construct "TypeName, AssemblyName" and look up in the managed-to-java map. The array is small (~80-100 entries), so iteration cost is negligible vs the previous hash+binary-search. This eliminates the root cause of typemaps.*.ll content changes during C#-only incremental edits. Combined with the per-file skip from commit d2f07a1, this saves ~2.85s per CoreCLR incremental build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related changes that together skip
_CompileNativeAssemblySourceson no-type-change incremental CoreCLR builds:typemaps.<abi>.ll, lettingFiles.CopyIfStreamChangedpreserve its mtime → MSBuild's target-level Inputs/Outputs check skips_CompileNativeAssemblySourcesentirely.llcup-to-date check as defense-in-depth: when the target does run (because some.lldid change), skip individual files whose.ois already up to date.Problem
On incremental CoreCLR builds,
_CompileNativeAssemblySourceswas rebuilding every.ll→.oeven when nothing relevant had changed:TypeMappingDebugNativeAssemblyGeneratorCLRembedded anmvid_hashand emitted entries in hash-bucket order, so any assembly rebuild flipped bytes insidetypemaps.<abi>.lleven when the type set was identical.CopyIfStreamChangedthen updated mtime, which busted the target's Inputs/Outputs check.<CompileNativeAssembly>(the task) had no per-file granularity — once the target ran, it calledllcfor every source even if.owas newer than.ll.Fix
Utilities/TypeMappingDebugNativeAssemblyGeneratorCLR.csmvid_hashfrom emitted typemap entries.Tasks/CompileNativeAssembly.csRunAssembler(), compareFile.GetLastWriteTimeUtcof the output.oagainst the input.ll. If.oexists and is ≥.ll, skip thellcinvocation and log:[LLVM llc] Skipping '<x>.ll' because '<x>.o' is up to dateThese changes also benefit
_CompileNativeAssemblySourcescallers inMicrosoft.Android.Sdk.NativeRuntime.targetsandMicrosoft.Android.Sdk.NativeAOT.targets.Verification
Verified end-to-end on Samsung SM-G960F (
R58Y30J85VV) againstdotnet new maui -sc(MauiVersion11.0.0-preview.4.26221.9,net11.0-android, CoreCLR,arm64-v8a, Debug):typemaps.arm64-v8a.llbyte-identical and mtime-preserved across a no-type-change edit.Skipping target "_CompileNativeAssemblySources" because all output files are up-to-dateBuilding target "_CompileNativeAssemblySources" completelyllcskip — exercised by the integration test (see below).MainActivityresolves through the typemap name-iterate path.Testing
CompileNativeAssemblySourcesSkipsUnchangedFiles(inIncrementalBuildTest.cs) verifies both behaviours in one build:[Activity]-attributedTypeMapProbeActivityclass —GenerateJavaStubsadds a JCW, sotypemaps.<abi>.llcontent + mtime genuinely change._CompileNativeAssemblySourcesis not skipped at the target level.environment.<abi>.ll(which is unaffected by user types and so stays up-to-date).Test runs at Detailed verbosity so
LogDebugMessage(Low importance) is captured.