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

[One .NET] fix for incremental CoreCompile #5661

Merged

Conversation

jonathanpeppers
Copy link
Member

Context: https://github.com/xamarin/Xamarin.Forms/tree/main-handler

I noticed that when building Maui, CoreCompile seems to be running
on every build no matter what:

Building target "CoreCompile" completely.
Input file "obj\Debug\net6.0-android\Core-net6.csproj.CoreCompileInputs.cache" is newer than output file "bin\Debug\net6.0-android\Microsoft.Maui.xml".

I could reproduce this in a test:

  • Build AppA & LibraryB
  • Build AppA & LibraryB again, LibraryB will run CoreCompile
    every time.

There is a _GenerateCompileDependencyCache target that basically does:

<Hash ItemsToHash="@(CoreCompileCache)">
  <Output TaskParameter="HashResult" PropertyName="CoreCompileDependencyHash" />
</Hash>
<WriteLinesToFile
    Lines="$(CoreCompileDependencyHash)"
    File="$(IntermediateOutputPath)$(MSBuildProjectFile).CoreCompileInputs.cache"
    Overwrite="True"
    WriteOnlyWhenDifferent="True"
/>

https://github.com/dotnet/msbuild/blob/83cd7d4e36b71d5b2cefd02cb9a5a58d27dd6a75/src/Tasks/Microsoft.Common.CurrentVersion.targets#L3529

This *.CoreCompileInputs.cache file triggers CoreCompile to run
again when it needs to.

However, this file is actually updating on every build, because:

  1. Our "outer" build has all our preprocessor defines listed in
    @(CoreCompileCache) like __MOBILE__, __ANDROID__, etc.
  2. The "inner" build for each $(RuntimeIdentifier) does not have
    these symbols!

And so we get into a situation where CoreCompile will always run.
The inner & outer builds write different values in this file.

To solve this problem, I added our _AddAndroidDefines to run before
CoreCompile in inner builds.

I also needed some changes to our MSBuild test framework:

  • Make IsTargetSkipped() and AssertTargetIsSkipped() supported for
    new project types.
  • Make IsTargetSkipped() return false if a Building target "{target}" completely. message is found.

Context: https://github.com/xamarin/Xamarin.Forms/tree/main-handler

I noticed that when building Maui, `CoreCompile` seems to be running
on every build no matter what:

    Building target "CoreCompile" completely.
    Input file "obj\Debug\net6.0-android\Core-net6.csproj.CoreCompileInputs.cache" is newer than output file "bin\Debug\net6.0-android\Microsoft.Maui.xml".

I could reproduce this in a test:

* Build `AppA` & `LibraryB`
* Build `AppA` & `LibraryB` again, `LibraryB` will run `CoreCompile`
  *every* time.

There is a `_GenerateCompileDependencyCache` target that basically does:

    <Hash ItemsToHash="@(CoreCompileCache)">
      <Output TaskParameter="HashResult" PropertyName="CoreCompileDependencyHash" />
    </Hash>
    <WriteLinesToFile
        Lines="$(CoreCompileDependencyHash)"
        File="$(IntermediateOutputPath)$(MSBuildProjectFile).CoreCompileInputs.cache"
        Overwrite="True"
        WriteOnlyWhenDifferent="True"
    />

https://github.com/dotnet/msbuild/blob/83cd7d4e36b71d5b2cefd02cb9a5a58d27dd6a75/src/Tasks/Microsoft.Common.CurrentVersion.targets#L3529

This `*.CoreCompileInputs.cache` file triggers `CoreCompile` to run
again when it needs to.

However, this file is actually updating on every build, because:

1. Our "outer" build has all our preprocessor defines listed in
   `@(CoreCompileCache)` like `__MOBILE__`, `__ANDROID__`, etc.
2. The "inner" build for each `$(RuntimeIdentifier)` does *not* have
   these symbols!

And so we get into a situation where `CoreCompile` will always run.
The inner & outer builds write different values in this file.

To solve this problem, I added our `_AddAndroidDefines` to run before
`CoreCompile` in inner builds.

I also needed some changes to our MSBuild test framework:

* Make `IsTargetSkipped()` and `AssertTargetIsSkipped()` supported for
  new project types.
* Make `IsTargetSkipped()` return `false` if a `Building target
  "{target}" completely.` message is found.
@dotnet dotnet deleted a comment from azure-pipelines bot Feb 26, 2021
@jonathanpeppers jonathanpeppers marked this pull request as ready for review March 2, 2021 15:22
@jonathanpeppers jonathanpeppers merged commit 905878b into dotnet:master Mar 2, 2021
@jonathanpeppers jonathanpeppers deleted the dotnet-incremental-fix branch March 2, 2021 15:44
@github-actions github-actions bot locked and limited conversation to collaborators Jan 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants