[mtouch] Fix an unnecessary re-link when the linker copies assemblies without processing them. (#1534)
Event sequence: * mtouch is executed with the linker disabled. * The linker pipeline copies all input assemblies (since the linker is disabled the assemblies don't change) into the PreBuild directory. This will keep the original timestamps of the input assemblies. * mtouch is executed again, when none of the input assemblies changed. * The linker pipeline will re-execute, because it will see that at least one of the input assemblies (at least the .exe) is newer than at least one of the assemblies in the PreBuild directory (usually a framework assembly, because those have the original timestamp from their install location). Fix: Touch all the assemblies in the PreBuild directory after the linker pipeline executes the first time. This way the second time mtouch is executed, it will find that all assemblies in the PreBuild directory have timestamps later than all the input assemblies, so it will load the cached linked assemblies, instead of re-executing the linker pipeline.
This commit is contained in:
Родитель
72080fb320
Коммит
786ae13f80
|
@ -117,6 +117,22 @@ namespace Xamarin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void RebuildTest_DontLink ()
|
||||||
|
{
|
||||||
|
using (var mtouch = new MTouchTool ()) {
|
||||||
|
mtouch.NoFastSim = true;
|
||||||
|
mtouch.Linker = MTouchLinker.DontLink;
|
||||||
|
mtouch.CreateTemporaryApp ();
|
||||||
|
mtouch.Verbosity = 4;
|
||||||
|
mtouch.CreateTemporaryCacheDirectory ();
|
||||||
|
mtouch.AssertExecute (MTouchAction.BuildSim, "build 1");
|
||||||
|
mtouch.AssertOutputPattern ("Linking .*/testApp.exe into .*/PreBuild using mode 'None'");
|
||||||
|
mtouch.AssertExecute (MTouchAction.BuildSim, "build 2");
|
||||||
|
mtouch.AssertOutputPattern ("Cached assemblies reloaded.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
// Simulator
|
// Simulator
|
||||||
[TestCase (Target.Sim, Config.Release, PackageMdb.Default, MSym.Default, false, false, "")]
|
[TestCase (Target.Sim, Config.Release, PackageMdb.Default, MSym.Default, false, false, "")]
|
||||||
|
|
|
@ -18,6 +18,7 @@ using PlatformException = Xamarin.Bundler.MonoMacException;
|
||||||
namespace Xamarin.Bundler {
|
namespace Xamarin.Bundler {
|
||||||
public partial class Assembly
|
public partial class Assembly
|
||||||
{
|
{
|
||||||
|
public List<string> Satellites;
|
||||||
public Application App { get { return Target.App; } }
|
public Application App { get { return Target.App; } }
|
||||||
|
|
||||||
string full_path;
|
string full_path;
|
||||||
|
@ -392,5 +393,28 @@ namespace Xamarin.Bundler {
|
||||||
{
|
{
|
||||||
return FileName;
|
return FileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This returns the path to all related files:
|
||||||
|
// * The assembly itself
|
||||||
|
// * Any debug files (mdb/pdb)
|
||||||
|
// * Any config files
|
||||||
|
// * Any satellite assemblies
|
||||||
|
public IEnumerable<string> GetRelatedFiles ()
|
||||||
|
{
|
||||||
|
yield return FullPath;
|
||||||
|
var mdb = FullPath + ".mdb";
|
||||||
|
if (File.Exists (mdb))
|
||||||
|
yield return mdb;
|
||||||
|
var pdb = Path.ChangeExtension (FullPath, ".pdb");
|
||||||
|
if (File.Exists (pdb))
|
||||||
|
yield return pdb;
|
||||||
|
var config = FullPath + ".config";
|
||||||
|
if (File.Exists (config))
|
||||||
|
yield return config;
|
||||||
|
if (Satellites != null) {
|
||||||
|
foreach (var satellite in Satellites)
|
||||||
|
yield return satellite;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ using Xamarin.Utils;
|
||||||
namespace Xamarin.Bundler {
|
namespace Xamarin.Bundler {
|
||||||
public partial class Assembly
|
public partial class Assembly
|
||||||
{
|
{
|
||||||
public List<string> Satellites;
|
|
||||||
List<string> dylibs;
|
List<string> dylibs;
|
||||||
public string Dylib;
|
public string Dylib;
|
||||||
|
|
||||||
|
|
|
@ -545,8 +545,21 @@ namespace Xamarin.Bundler
|
||||||
assemblies = linked_assemblies;
|
assemblies = linked_assemblies;
|
||||||
|
|
||||||
// Make the assemblies point to the right path.
|
// Make the assemblies point to the right path.
|
||||||
foreach (var a in Assemblies)
|
foreach (var a in Assemblies) {
|
||||||
a.FullPath = Path.Combine (PreBuildDirectory, a.FileName);
|
a.FullPath = Path.Combine (PreBuildDirectory, a.FileName);
|
||||||
|
// The linker can copy files (and not update timestamps), and then we run into this sequence:
|
||||||
|
// * We run the linker, nothing changes, so the linker copies
|
||||||
|
// all files to the PreBuild directory, with timestamps intact.
|
||||||
|
// * This means that for instance SDK assemblies will have the original
|
||||||
|
// timestamp from their installed location, and the exe will have the
|
||||||
|
// timestamp of when it was built.
|
||||||
|
// * mtouch is executed again for some reason, and none of the input assemblies changed.
|
||||||
|
// We'll still re-execute the linker, because at least one of the input assemblies
|
||||||
|
// (the .exe) has a newer timestamp than some of the assemblies in the PreBuild directory.
|
||||||
|
// So here we manually touch all the assemblies we have, to make sure their timestamps
|
||||||
|
// change (this is us saying 'we know these files are up-to-date at this point in time').
|
||||||
|
Driver.Touch (a.GetRelatedFiles ());
|
||||||
|
}
|
||||||
|
|
||||||
File.WriteAllText (cache_path, string.Join ("\n", linked_assemblies));
|
File.WriteAllText (cache_path, string.Join ("\n", linked_assemblies));
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,6 +751,14 @@ namespace Xamarin.Bundler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Touch (IEnumerable<string> filenames, DateTime? timestamp = null)
|
||||||
|
{
|
||||||
|
if (timestamp == null)
|
||||||
|
timestamp = DateTime.Now;
|
||||||
|
foreach (var filename in filenames)
|
||||||
|
new FileInfo (filename).LastWriteTime = timestamp.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public static string Quote (string f)
|
public static string Quote (string f)
|
||||||
{
|
{
|
||||||
if (f.IndexOf (' ') == -1 && f.IndexOf ('\'') == -1 && f.IndexOf (',') == -1 && f.IndexOf ('$') == -1)
|
if (f.IndexOf (' ') == -1 && f.IndexOf ('\'') == -1 && f.IndexOf (',') == -1 && f.IndexOf ('$') == -1)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче