Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] _LinkAssembliesNoShrink timestamps (#2028)
Browse files Browse the repository at this point in the history
Context: xamarin/monodroid#821
Context: 3d999d3#diff-42a9402e6466c65d49d0ee7caf21f327R164

Since commit 3d999d3, a test is failing downstream in monodroid that
is testing the following scenario:

 1. With `Fast Deployment` enabled, run `/t:Install`
 2. Make a small code change
 3. Run `/t:Install` again
 4. Assemblies are getting uploaded to the device that should already be
    up to date!

3d999d3 was addressing a symptom of the problem, but not the root
cause.  The `OutputStep` of the linker has various uses of
[`File.Copy()`][0], which preserves the timestamp of the source file:

> The attributes of the original file are retained in the copied file.

File timestamps are considered "attributes of the original file".

The solution, then, is to run the `<Touch/>` MSBuild task on the
linker's output.  This will create appropriate timestamps, and a
portion of the changes in 3d999d3 are no longer needed.

I updated the `CheckTimestamps()` test to validate `Debug` and
`Release` configurations, so the `_LinkAssembliesShrink` target is
also tested in this manner.  It turns out `_LinkAssembliesShrink` is
currently working fine, since it uses `$(_AndroidLinkFlag)` as its
`Outputs` Target attribute.

[0]: https://docs.microsoft.com/en-us/dotnet/api/system.io.file.copy?view=netframework-4.7.2#System_IO_File_Copy_System_String_System_String_
  • Loading branch information
jonathanpeppers authored and jonpryor committed Aug 3, 2018
1 parent d5d93d5 commit ce2ee0d
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 8 deletions.
4 changes: 1 addition & 3 deletions src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,8 @@ bool Execute (DirectoryAssemblyResolver res)
// We cannot just copy the linker output from *current* run output, because
// it always renew the assemblies, in *different* binary values, whereas
// the dll in the OptionalDestinationDirectory must retain old and unchanged.
if (File.Exists (assemblyDestination)) {
MonoAndroidHelper.SetLastAccessAndWriteTimeUtc (assemblyDestination, DateTime.UtcNow, Log);
if (File.Exists (assemblyDestination))
continue;
}
} else {
// Prefer fixup assemblies if exists, otherwise just copy the original.
copysrc = Path.Combine (OutputDirectory, filename);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,13 @@ public void TargetFrameworkMonikerAssemblyAttributesPath ()
}

[Test]
public void CheckTimestamps ()
public void CheckTimestamps ([Values (true, false)] bool isRelease)
{
var start = DateTime.UtcNow.AddSeconds (-1);
var proj = new XamarinAndroidApplicationProject ();
using (var b = CreateApkBuilder ("temp/CheckTimestamps")) {
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
};
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
//To be sure we are at a clean state, delete bin/obj
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
if (Directory.Exists (intermediate))
Expand Down Expand Up @@ -240,7 +242,8 @@ public void CheckTimestamps ()

//One last build with no changes
Assert.IsTrue (b.Build (proj), "third build should have succeeded.");
Assert.IsTrue (b.Output.IsTargetSkipped ("_LinkAssembliesNoShrink"), "`_LinkAssembliesNoShrink` should be skipped!");
string targetName = isRelease ? "_LinkAssembliesShrink" : "_LinkAssembliesNoShrink";
Assert.IsTrue (b.Output.IsTargetSkipped (targetName), $"`{targetName}` should be skipped!");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2078,7 +2078,13 @@ because xbuild doesn't support framework reference assemblies.
LinkOnlyNewerThan="$(_AndroidLinkFlag)"
ResolvedAssemblies="@(ResolvedAssemblies)" />

<!-- We don't have to depend on flag file for NoShrink, but it is used to check timestamp -->
<!--NOTE: the linker's use of File.Copy requires us to update the timestamps of output files -->
<ItemGroup>
<_FilesToTouch Include="$(MonoAndroidIntermediateAssemblyTempDir)*" />
</ItemGroup>
<Touch Files="@(_FilesToTouch)" />

<!-- We don't have to depend on flag file for NoShrink, but it is used to check timestamp -->
<Touch Files="$(_AndroidLinkFlag)" AlwaysCreate="true" />
</Target>

Expand Down

0 comments on commit ce2ee0d

Please sign in to comment.