Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] fix _CopyIntermediateAssemblies outputs
Browse files Browse the repository at this point in the history
Context: dotnet#2247
Context: dotnet#2128

The `_CopyIntermediateAssemblies` target has a bug for incremental
builds, reproduced by the following:
- Build a Xamarin.Android app project
- `touch` the project's assembly in `$(IntermediateOutputPath)`
- Build a second time. `_CopyIntermediateAssemblies` will run as
  expected.
- Build a third time. `_CopyIntermediateAssemblies` will still run!

When in this state, `_CopyIntermediateAssemblies` will always run.
This is bad because it triggers other expensive targets like
`_UpdateAndroidResgen` _every time_.

I believe I introduced this in dotnet#2128, which was when I saw
`_CopyIntermediateAssemblies` taking more time than it used to. It was
a good tradeoff though, since it prevented `_UpdateAndroidResgen` from
running too often. 15.9 does not have dotnet#2128.

To fix this problem properly, I introduced a new
`_copyintermediate.stamp` file to be used as the `Outputs` of the
target. In addition to fixing our incremental build here, there should
be performance gains in only verifying the timestamp of one file in
`Outputs`.

The `Inputs` of the `_CopyIntermediateAssemblies` were also incorrect,
as it was not using the "satellite" assembly files as an input.

This does not fully complete dotnet#2247, as there are two other targets
listed I need to investigate further. These are likely unrelated to
the changes in dotnet#2128.
  • Loading branch information
jonathanpeppers committed Oct 16, 2018
1 parent b78dd8b commit a5754a6
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -318,5 +318,29 @@ public Class2 ()
}
}
}

[Test]
public void CopyIntermediateAssemblies ()
{
var target = "_CopyIntermediateAssemblies";
var proj = new XamarinFormsAndroidApplicationProject ();
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "first build should succeed");
Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped!");

var assembly = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, proj.ProjectName + ".dll");
FileAssert.Exists (assembly);
File.SetLastWriteTimeUtc (assembly, DateTime.UtcNow);
File.SetLastAccessTimeUtc (assembly, DateTime.UtcNow);

//NOTE: second build, target will run because inputs changed
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "second build should succeed");
Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped on second build!");

//NOTE: third build, it should certainly *not* run! there are no changes
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "third build should succeed");
Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on third build!");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1974,8 +1974,8 @@ because xbuild doesn't support framework reference assemblies.
</Target>

<Target Name="_CopyIntermediateAssemblies"
Inputs="@(ResolvedUserAssemblies)"
Outputs="@(ResolvedUserAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
Inputs="@(ResolvedUserAssemblies);@(_AndroidResolvedSatellitePaths)"
Outputs="$(IntermediateOutputPath)_copyintermediate.stamp"
DependsOnTargets="_ResolveAssemblies;_ResolveSatellitePaths;_CreatePackageWorkspace;_CreateIntermediateAssembliesDir;_CopyConfigFiles">
<!-- Make a copy of every assembly we need in assemblies -->
<CopyIfChanged
Expand All @@ -1987,6 +1987,10 @@ because xbuild doesn't support framework reference assemblies.
DestinationFiles="@(_AndroidResolvedSatellitePaths->'$(MonoAndroidLinkerInputDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
/>
<Delete Files="@(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension).mdb')" />
<Touch Files="$(IntermediateOutputPath)_copyintermediate.stamp" AlwaysCreate="True" />
<ItemGroup>
<FileWrites Include="$(IntermediateOutputPath)_copyintermediate.stamp" />
</ItemGroup>
</Target>

<Target Name="_CollectConfigFiles"
Expand Down Expand Up @@ -3103,6 +3107,7 @@ because xbuild doesn't support framework reference assemblies.
<Delete Files="$(MonoAndroidIntermediate)stub_application_data.txt" />
<Delete Files="$(IntermediateOutputPath)_javac.stamp" />
<Delete Files="$(IntermediateOutputPath)_javastubs.stamp" />
<Delete Files="$(IntermediateOutputPath)_copyintermediate.stamp" />
<Delete Files="$(_AndroidResFlagFile)" />
<Delete Files="$(_AndroidLinkFlag)" />
<Delete Files="$(_AndroidComponentResgenFlagFile)" />
Expand Down

0 comments on commit a5754a6

Please sign in to comment.