Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,24 @@ bool Execute (DirectoryAssemblyResolver res)
else if (!MonoAndroidHelper.IsForceRetainedAssembly (filename))
continue;

MonoAndroidHelper.CopyIfChanged (copysrc, Path.Combine (copydst, filename));
var assemblyDestination = Path.Combine (copydst, filename);
if (MonoAndroidHelper.CopyIfChanged (copysrc, assemblyDestination)) {
MonoAndroidHelper.SetLastAccessAndWriteTimeUtc (assemblyDestination, DateTime.UtcNow, Log);
}
try {
MonoAndroidHelper.CopyIfChanged (assembly.ItemSpec + ".mdb", Path.Combine (copydst, filename + ".mdb"));
var mdbDestination = assemblyDestination + ".mdb";
if (MonoAndroidHelper.CopyIfChanged (assembly.ItemSpec + ".mdb", mdbDestination)) {
MonoAndroidHelper.SetLastAccessAndWriteTimeUtc (mdbDestination, DateTime.UtcNow, Log);
}
} catch (Exception) { // skip it, mdb sometimes fails to read and it's optional
}
var pdb = Path.ChangeExtension (copysrc, "pdb");
if (File.Exists (pdb) && Files.IsPortablePdb (pdb))
MonoAndroidHelper.CopyIfChanged (pdb, Path.ChangeExtension (Path.Combine (copydst, filename), "pdb"));
if (File.Exists (pdb) && Files.IsPortablePdb (pdb)) {
var pdbDestination = Path.ChangeExtension (Path.Combine (copydst, filename), "pdb");
if (MonoAndroidHelper.CopyIfChanged (pdb, pdbDestination)) {
MonoAndroidHelper.SetLastAccessAndWriteTimeUtc (pdbDestination, DateTime.UtcNow, Log);
}
}
}
} catch (ResolutionException ex) {
Diagnostic.Error (2006, ex, "Could not resolve reference to '{0}' (defined in assembly '{1}') with scope '{2}'. When the scope is different from the defining assembly, it usually means that the type is forwarded.", ex.Member, ex.Member.Module.Assembly, ex.Scope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,31 @@ public void FooMethod () {
}
}

[Test]
public void CheckTimestamps ()
{
var start = DateTime.UtcNow.AddSeconds (-1);
var proj = new XamarinAndroidApplicationProject ();
using (var b = CreateApkBuilder ("temp/CheckTimestamps")) {
//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))
Directory.Delete (intermediate, true);
var output = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath);
if (Directory.Exists (output))
Directory.Delete (output, true);
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");

//Absolutely non of these files should be *older* than the starting time of this test!
var files = Directory.EnumerateFiles (intermediate, "*", SearchOption.AllDirectories).ToList ();
files.AddRange (Directory.EnumerateFiles (output, "*", SearchOption.AllDirectories));
foreach (var file in files) {
var info = new FileInfo (file);
Assert.IsTrue (info.LastWriteTimeUtc > start, $"`{file}` is older than `{start}`, with a timestamp of `{info.LastWriteTimeUtc}`!");
}
}
}

[Test]
public void BuildApplicationAndClean ([Values (false, true)] bool isRelease)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public void UseLatestAndroidSdk (string buildtools, string jdk, ApiInfo[] apis,
Directory.Delete (Path.Combine (Root, path), recursive: true);
}

[Test]
[Test, NonParallelizable]
public void ResolveSdkTiming ()
{
var path = Path.Combine ("temp", TestName);
Expand Down Expand Up @@ -226,7 +226,7 @@ public void ResolveSdkTiming ()
var start = DateTime.UtcNow;
Assert.IsTrue (task.Execute ());
var executionTime = DateTime.UtcNow - start;
Assert.LessOrEqual (executionTime, TimeSpan.FromSeconds(1), "Task should not take more than 1 second to run.");
Assert.LessOrEqual (executionTime, TimeSpan.FromSeconds(2), "Task should not take more than 2 seconds to run.");
Assert.AreEqual (task.AndroidApiLevel, "26", "AndroidApiLevel should be 26");
Assert.AreEqual (task.TargetFrameworkVersion, "v8.0", "TargetFrameworkVersion should be v8.0");
Assert.AreEqual (task.AndroidApiLevelName, "26", "AndroidApiLevelName should be 26");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1704,6 +1704,7 @@ because xbuild doesn't support framework reference assemblies.
SourceFiles="$(MonoPlatformJarPath)"
DestinationFiles="$(IntermediateOutputPath)android\bin\mono.android.jar"
SkipUnchangedFiles="true" />
<Touch Files="$(IntermediateOutputPath)android\bin\mono.android.jar" />

<Touch Files="$(_AndroidStaticResourcesFlag)" AlwaysCreate="true" />
</Target>
Expand All @@ -1730,7 +1731,7 @@ because xbuild doesn't support framework reference assemblies.
DestinationFiles="@(_AndroidResolvedSatellitePaths->'$(MonoAndroidLinkerInputDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"
/>
<Touch Files="@(ResolvedUserAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dellis1972: Is this change correct? IIRC in Debug builds, @(ResolvedAssemblies) may contain system-installed assemblies such as Mono.Android.dll, which we almost certainly don't want to be <Touch/>ing...

Copy link
Member Author

@jonathanpeppers jonathanpeppers May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What made me think this was a mistake was the previous line:

<Copy
	SourceFiles="@(ResolvedAssemblies)"
	DestinationFiles="@(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
	SkipUnchangedFiles="true" />

I was thinking DestinationFiles from <Copy /> needs to match Files from <Touch />.

If an item in @(ResolvedAssemblies) was the system Mono.Android.dll, for example, @(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)') should evaluate to obj\Debug\linksrc\Mono.Android.dll.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @jonathanpeppers is right on this one. We are touching the files in the Intermediate dir so it should be ok.

<Touch Files="@(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')" />
<Touch Files="@(_AndroidResolvedSatellitePaths->'$(MonoAndroidLinkerInputDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
<Delete Files="@(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension).mdb')" />
</Target>
Expand Down