diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 6d463af1bc9c1..59f8edae77958 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -361,47 +361,73 @@ private bool ExecuteInternal() foreach (var assemblyItem in _assembliesToCompile) argsList.Add(GetPrecompileArgumentsFor(assemblyItem, monoPaths)); - //FIXME: check the nothing changed at all case - _totalNumAssemblies = _assembliesToCompile.Count; - int allowedParallelism = Math.Min(_assembliesToCompile.Count, Environment.ProcessorCount); - if (BuildEngine is IBuildEngine9 be9) - allowedParallelism = be9.RequestCores(allowedParallelism); - - if (DisableParallelAot || allowedParallelism == 1) + if (CheckAllUpToDate(argsList)) { + Log.LogMessage(MessageImportance.High, "Everything is up-to-date, nothing to precompile"); + + _fileWrites.AddRange(argsList.SelectMany(args => args.ProxyFiles).Select(pf => pf.TargetFile)); foreach (var args in argsList) - { - if (!PrecompileLibrarySerial(args)) - return !Log.HasLoggedErrors; - } + compiledAssemblies.GetOrAdd(args.AOTAssembly.ItemSpec, args.AOTAssembly); } else { - ParallelLoopResult result = Parallel.ForEach( - argsList, - new ParallelOptions { MaxDegreeOfParallelism = allowedParallelism }, - (args, state) => PrecompileLibraryParallel(args, state)); + int allowedParallelism = Math.Min(_assembliesToCompile.Count, Environment.ProcessorCount); + if (BuildEngine is IBuildEngine9 be9) + allowedParallelism = be9.RequestCores(allowedParallelism); - if (!result.IsCompleted) + if (DisableParallelAot || allowedParallelism == 1) { - return false; + foreach (var args in argsList) + { + if (!PrecompileLibrarySerial(args)) + return !Log.HasLoggedErrors; + } + } + else + { + ParallelLoopResult result = Parallel.ForEach( + argsList, + new ParallelOptions { MaxDegreeOfParallelism = allowedParallelism }, + (args, state) => PrecompileLibraryParallel(args, state)); + + if (!result.IsCompleted) + { + return false; + } } + + int numUnchanged = _totalNumAssemblies - _numCompiled; + if (numUnchanged > 0 && numUnchanged != _totalNumAssemblies) + Log.LogMessage(MessageImportance.High, $"[{numUnchanged}/{_totalNumAssemblies}] skipped unchanged assemblies."); } - int numUnchanged = _totalNumAssemblies - _numCompiled; - if (numUnchanged > 0 && numUnchanged != _totalNumAssemblies) - Log.LogMessage(MessageImportance.High, $"[{numUnchanged}/{_totalNumAssemblies}] skipped unchanged assemblies."); + CompiledAssemblies = ConvertAssembliesDictToOrderedList(compiledAssemblies, _assembliesToCompile).ToArray(); if (_cache.Save(CacheFilePath!)) _fileWrites.Add(CacheFilePath!); - - CompiledAssemblies = ConvertAssembliesDictToOrderedList(compiledAssemblies, _assembliesToCompile).ToArray(); FileWrites = _fileWrites.ToArray(); return !Log.HasLoggedErrors; } + private bool CheckAllUpToDate(IList argsList) + { + foreach (var args in argsList) + { + // compare original assembly vs it's outputs.. all it's outputs! + string assemblyPath = args.AOTAssembly.GetMetadata("FullPath"); + if (args.ProxyFiles.Any(pf => IsNewerThanOutput(assemblyPath, pf.TargetFile))) + return false; + } + + return true; + + static bool IsNewerThanOutput(string inFile, string outFile) + => !File.Exists(inFile) || !File.Exists(outFile) || + (File.GetLastWriteTimeUtc(inFile) > File.GetLastWriteTimeUtc(outFile)); + } + private IList EnsureAndGetAssembliesInTheSameDir(ITaskItem[] originalAssemblies) { List filteredAssemblies = new(); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs index b97a0490d2e87..d64188ee86d7b 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs @@ -25,8 +25,8 @@ public MainWithArgsTests(ITestOutputHelper output, SharedBuildPerTestClassFixtur ).WithRunHosts(host).UnwrapItemsAsArrays(); [Theory] - [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] - [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] + // [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] + [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ true, RunHost.V8 })] public void AsyncMainWithArgs(BuildArgs buildArgs, string[] args, RunHost host, string id) => TestMainWithArgs("async_main_with_args", @" public class TestClass { diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/NativeRebuildTestsBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/NativeRebuildTestsBase.cs index 9047fd062a82e..038027f56a4ab 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/NativeRebuildTestsBase.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/NativeRebuildTestsBase.cs @@ -28,8 +28,8 @@ public NativeRebuildTestsBase(ITestOutputHelper output, SharedBuildPerTestClassF { List data = new(); // relinking - data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: false)); - data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: true)); + // data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: false)); + // data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: true)); // aot data.AddRange(GetData(aot: true, nativeRelinking: false, invariant: false)); @@ -76,6 +76,7 @@ protected string Rebuild(bool nativeRelink, bool invariant, BuildArgs buildArgs, File.WriteAllText(Path.Combine(_projectDir!, $"{buildArgs.ProjectName}.csproj"), buildArgs.ProjectFileContents); buildArgs = newBuildArgs; + Console.WriteLine($"{Environment.NewLine}Rebuilding with no changes ..{Environment.NewLine}"); _testOutput.WriteLine($"{Environment.NewLine}Rebuilding with no changes ..{Environment.NewLine}"); (_, string output) = BuildProject(buildArgs, id: id,