[Xamarin.Android.Build.Tests] Support MSBuild (#912)

This commit reworks the tests to pass on MSBuild. xbuild is
deprecated, so we should ensure that our system works on MSBuild.

Lots of changes. Highlights include:

We have to NOT use `$(BuildingInsideVisualStudio)` when building
under `msbuild`. Setting this property to `true` has a side effect
of telling `msbuild` "Dont bother to build @(ProjectReferences)".
This is because under VS that is something the IDE takes care of.
It turns out that the bug we had to do with `__NonExistantFile__`
causing the `csc` task to run ALL the time was fixed.

All of the `IsTargetSkipped` checks have been unified to call the
`BuildOutput.IsTargetSkipped()` method. It has also been updated
to include more target "skipped" formats which xbuild and MSBuild
generate.

There is also a difference in behaviour between xbuild and MSBuild.
You may well have noticed that ALL the tests that have had the

	"debug" -> "release"

changes (including the debugger attribute one) are around

	$(DebugType) == "None"

Under xbuild when `$(DebugType)` == "None" and
`$(DebugSymbols)` == "True", we end up with
`$(DebugType)` == "None" and `$(DebugSymbols)` == "True" (no changes).
This results in a debug runtime and apk.

However, under MSBuild when `$(DebugType)` == "None"
and `$(DebugSymbols)` == "True" we end up with
`$(DebugType)` == "portable" and `$(DebugSymbols)` == "False" (!).
This results in a release runtime and apk.

This is because `None` is NOT a valid value for `$(DebugType)` in
MSBuild, so it resets BOTH `$(DebugType)` and `$(DebugSymbols)`.
This results in difference of behaviour between the two systems.

Update `Xamarin.Android.Common.targets` to check for this, and update
`$(DebugType)` and `$(DebugSymbols)` so that xbuild behaves like
MSBuild. This improves consistency (and our own sanity!).
(This may break some QA tests, but this is now expected and the tests
should be updated to reflect this.)
This commit is contained in:
Dean Ellis 2017-10-18 20:51:34 +01:00 коммит произвёл Jonathan Pryor
Родитель e699140b1a
Коммит 8643ded9ee
18 изменённых файлов: 209 добавлений и 95 удалений

Просмотреть файл

@ -14,7 +14,7 @@ Copyright (C) 2014 Xamarin. All rights reserved.
</PropertyGroup>
<Target Name="_RegisterMdbFilesWithFileWrites" BeforeTargets="IncrementalClean">
<CreateItem Include="$(OutDir)*.dll.mdb;$(MonoAndroidIntermediateAssemblyDir)*.dll.mdb">
<CreateItem Include="$(OutDir)*.dll.mdb;$(MonoAndroidIntermediateAssemblyDir)*.dll.mdb;$(MonoAndroidLinkerInputDir)*.dll.mdb">
<Output TaskParameter="Include" ItemName="_FilesToRegister" />
</CreateItem>
<CreateItem Include="$([System.IO.Path]::GetFullPath('%(_FilesToRegister.Identity)'))"

Просмотреть файл

@ -41,6 +41,9 @@ namespace Xamarin.Android.Tasks
[Required]
public bool UseManagedResourceGenerator { get; set; }
[Required]
public bool DesignTimeBuild { get; set; }
private Dictionary<string, string> resource_fixup = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
public override bool Execute ()
@ -121,7 +124,13 @@ namespace Xamarin.Android.Tasks
var suffix = assemblyName.ItemSpec.EndsWith (".dll") ? String.Empty : ".dll";
string hintPath = assemblyName.GetMetadata ("HintPath").Replace (Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
string fileName = assemblyName.ItemSpec + suffix;
resolver.Load (Path.GetFullPath (assemblyName.ItemSpec));
string fullPath = Path.GetFullPath (assemblyName.ItemSpec);
// Skip non existing files in DesignTimeBuild
if (!File.Exists (fullPath) && DesignTimeBuild) {
Log.LogDebugMessage ("Skipping non existant dependancy '{0}' due to design time build.", fullPath);
continue;
}
resolver.Load (fullPath);
if (!String.IsNullOrEmpty (hintPath) && !File.Exists (hintPath)) // ignore invalid HintPath
hintPath = null;
string assemblyPath = String.IsNullOrEmpty (hintPath) ? fileName : hintPath;

Просмотреть файл

@ -397,10 +397,17 @@ namespace Xamarin.Android.Tasks {
using (var resolver = new DirectoryAssemblyResolver (this.CreateTaskLogger (), loadDebugSymbols: false)) {
foreach (var assemblyItem in Assemblies) {
string fullPath = Path.GetFullPath (assemblyItem.ItemSpec);
if (DesignTimeBuild && !File.Exists (fullPath)) {
LogWarning ("Failed to load '{0}'. Check the file exists or the project has been built.", fullPath);
continue;
}
if (assemblies.Contains (fullPath)) {
LogDebugMessage (" Skip assembly: {0}, it was already processed", fullPath);
continue;
}
// don't try to even load mscorlib it will fail.
if (string.Compare (Path.GetFileNameWithoutExtension (fullPath), "mscorlib", StringComparison.OrdinalIgnoreCase) == 0)
continue;
assemblies.Add (fullPath);
resolver.Load (fullPath);
// Append source file name (without the Xamarin. prefix or extension) to the base folder

Просмотреть файл

@ -39,6 +39,9 @@ namespace Xamarin.Android.Tasks
public string CacheFile { get; set; }
[Required]
public bool DesignTimeBuild { get; set; }
[Output]
public string [] Jars { get; set; }
@ -207,6 +210,11 @@ namespace Xamarin.Android.Tasks
continue;
}
if (!File.Exists (assemblyPath) && DesignTimeBuild) {
Log.LogDebugMessage ("Skipping non existant dependancy '{0}' due to design time build.", assemblyPath);
continue;
}
Log.LogDebugMessage ("Refreshing {0}", assemblyPath);
Directory.CreateDirectory (importsDir);

Просмотреть файл

@ -28,10 +28,10 @@ namespace Xamarin.Android.Build.Tests
b.ThrowOnBuildFailure = false;
Assert.IsTrue (b.Build (proj), "first build failed");
Assert.IsTrue (b.Build (proj), "second build failed");
Assert.IsTrue (b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), "failed to skip some build");
Assert.IsTrue (b.Output.IsTargetSkipped ("_Sign"), "failed to skip some build");
proj.AndroidResources.First ().Timestamp = null; // means "always build"
Assert.IsTrue (b.Build (proj), "third build failed");
Assert.IsFalse (b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), "incorrectly skipped some build");
Assert.IsFalse (b.Output.IsTargetSkipped ("_Sign"), "incorrectly skipped some build");
}
}
@ -74,15 +74,18 @@ using System.Runtime.CompilerServices;
},
};
proj.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", useManagedParser.ToString ());
if (useManagedParser)
proj.SetProperty ("BuildingInsideVisualStudio", "True");
using (var l = CreateDllBuilder (Path.Combine (path, lib.ProjectName), false, false)) {
using (var b = CreateApkBuilder (Path.Combine (path, proj.ProjectName), false, false)) {
l.Verbosity = LoggerVerbosity.Diagnostic;
l.Target = "Build";
Assert.IsTrue(l.Clean(lib), "Lib1 should have cleaned successfully");
Assert.IsTrue (l.Build (lib), "Lib1 should have built successfully");
b.Verbosity = LoggerVerbosity.Diagnostic;
b.ThrowOnBuildFailure = false;
Assert.IsTrue (b.Clean(proj), "App should have cleaned successfully");
Assert.IsTrue (b.UpdateAndroidResources (proj, doNotCleanupOnUpdate: true, parameters: new string [] { "DesignTimeBuild=true" }, environmentVariables: envVar),
b.Target = "Compile";
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, parameters: new string [] { "DesignTimeBuild=true" }, environmentVariables: envVar),
"first build failed");
Assert.AreEqual (!useManagedParser, b.LastBuildOutput.Contains ("Skipping download of "),
"failed to skip the downloading of files.");
@ -156,7 +159,7 @@ using System.Runtime.CompilerServices;
image.Timestamp = DateTimeOffset.UtcNow.AddMinutes (1);
Assert.IsTrue (b.Build (proj), "Second build should have succeeded.");
Assert.IsFalse (File.Exists (Path.Combine (b.ProjectDirectory, oldpath)), "XamarinProject.UpdateProjectFiles() failed to delete file");
Assert.IsFalse (b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), "incorrectly skipped some build");
Assert.IsFalse (b.Output.IsTargetSkipped ("_Sign"), "incorrectly skipped some build");
}
}
@ -194,25 +197,23 @@ using System.Runtime.CompilerServices;
Assert.IsTrue (b.Build (proj), "Second build was supposed to build without errors");
Assert.IsTrue (firstBuildTime > b.LastBuildTime, "Second build was supposed to be quicker than the first");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_GenerateAndroidResourceDir\" because"),
b.Output.IsTargetSkipped ("_GenerateAndroidResourceDir"),
"The Target _GenerateAndroidResourceDir should have been skipped");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"),
b.Output.IsTargetSkipped ("_CompileJava"),
"The Target _CompileJava should have been skipped");
image1.Timestamp = DateTime.UtcNow;
var layout = proj.AndroidResources.First (x => x.Include() == "Resources\\layout\\Main.axml");
layout.Timestamp = DateTime.UtcNow;
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate:true, saveProject: false), "Third build was supposed to build without errors");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Target _GenerateAndroidResourceDir needs to be built as input file") ||
b.LastBuildOutput.Contains ("Building target \"_GenerateAndroidResourceDir\" completely."),
Assert.IsFalse (
b.Output.IsTargetSkipped ("_GenerateAndroidResourceDir"),
"The Target _GenerateAndroidResourceDir should not have been skipped");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"),
b.Output.IsTargetSkipped ("_CompileJava"),
"The Target _CompileJava (2) should have been skipped");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Target _CreateBaseApk needs to be built as input file") ||
b.LastBuildOutput.Contains ("Building target \"_CreateBaseApk\" completely."),
Assert.IsFalse (
b.Output.IsTargetSkipped ("_CreateBaseApk"),
"The Target _CreateBaseApk should not have been skipped");
}
}
@ -957,7 +958,7 @@ namespace Lib1 {
using (var appBuilder = CreateApkBuilder (Path.Combine (path, appProj.ProjectName))) {
appBuilder.Verbosity = LoggerVerbosity.Diagnostic;
appBuilder.Target = "Compile";
Assert.IsTrue (appBuilder.Build (appProj, parameters: new string[] { "DesignTimeBuild=true"} ),
Assert.IsTrue (appBuilder.Build (appProj, parameters: new string[] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" } ),
"DesignTime Application Build should have succeeded.");
Assert.IsFalse (appProj.CreateBuildOutput (appBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"),
"Target '_ManagedUpdateAndroidResgen' should have run.");
@ -1021,15 +1022,17 @@ namespace Lib1 {
appProj.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", "True");
using (var libBuilder = CreateDllBuilder (Path.Combine (path, libProj.ProjectName), false, false)) {
libBuilder.Verbosity = LoggerVerbosity.Diagnostic;
libBuilder.ThrowOnBuildFailure = false;
using (var appBuilder = CreateApkBuilder (Path.Combine (path, appProj.ProjectName), false, false)) {
appBuilder.Verbosity = LoggerVerbosity.Diagnostic;
appBuilder.ThrowOnBuildFailure = false;
libBuilder.Target = "Compile";
Assert.IsTrue (libBuilder.Build (libProj, parameters: new string [] { "DesignTimeBuild=true" }), "Library project should have built");
Assert.IsTrue (libBuilder.Build (libProj, parameters: new string [] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" }), "Library project should have built");
Assert.LessOrEqual (libBuilder.LastBuildTime.TotalMilliseconds, maxBuildTimeMs, "DesingTime build should be less than 5 seconds.");
Assert.IsFalse (libProj.CreateBuildOutput (libBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"),
"Target '_ManagedUpdateAndroidResgen' should have run.");
appBuilder.Target = "Compile";
Assert.IsTrue (appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true" }), "Library project should have built");
Assert.AreEqual (!appBuilder.RunningMSBuild, appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" }), "Application project should have built");
Assert.LessOrEqual (appBuilder.LastBuildTime.TotalMilliseconds, maxBuildTimeMs, "DesingTime build should be less than 5 seconds.");
Assert.IsFalse (appProj.CreateBuildOutput (appBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"),
"Target '_ManagedUpdateAndroidResgen' should have run.");
@ -1049,7 +1052,7 @@ namespace Lib1 {
Assert.IsTrue (libProj.CreateBuildOutput (libBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"),
"Target '_ManagedUpdateAndroidResgen' should not have run.");
appBuilder.Target = "Compile";
Assert.IsTrue (appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true" }), "App project should have built");
Assert.IsTrue (appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" }), "App project should have built");
Assert.LessOrEqual (appBuilder.LastBuildTime.TotalMilliseconds, maxBuildTimeMs, "DesingTime build should be less than 5 seconds.");
Assert.IsFalse (appProj.CreateBuildOutput (appBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"),
"Target '_ManagedUpdateAndroidResgen' should have run.");

Просмотреть файл

@ -133,7 +133,7 @@ namespace Xamarin.Android.Build.Tests
/* debugType */ "",
/* optimize */ true ,
/* embedassebmlies */ true ,
/* expectedResult */ "debug",
/* expectedResult */ "release",
},
new object[] {
/* supportedAbi */ new string[] { "armeabi-v7a"},
@ -141,7 +141,7 @@ namespace Xamarin.Android.Build.Tests
/* debugType */ "",
/* optimize */ true ,
/* embedassebmlies */ false ,
/* expectedResult */ "debug",
/* expectedResult */ "release",
},
new object[] {
/* supportedAbi */ new string[] { "armeabi-v7a"},

Просмотреть файл

@ -131,12 +131,16 @@ printf ""%d"" x
//var fi = new FileInfo (Path.Combine (b.ProjectDirectory, proj.IntermediateOutputPath,
// "__library_projects__", "Library1", "library_project_imports", ""));
//fi.Attributes != FileAttributes.ReadOnly;
var ignoreFiles = new string [] {
"TemporaryGeneratedFile",
"CopyComplete"
};
Assert.IsTrue (b.Clean (proj), "Clean should have succeeded.");
var fileCount = Directory.GetFiles (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath), "*", SearchOption.AllDirectories)
.Where (x => !Path.GetFileName (x).StartsWith ("TemporaryGeneratedFile")).Count ();
.Where (x => !ignoreFiles.Any (i => !Path.GetFileName (x).Contains (i))).Count ();
Assert.AreEqual (0, fileCount, "{0} should be Empty", proj.IntermediateOutputPath);
fileCount = Directory.GetFiles (Path.Combine (Root, b.ProjectDirectory, proj.OutputPath), "*", SearchOption.AllDirectories)
.Where (x => !Path.GetFileName (x).StartsWith ("TemporaryGeneratedFile")).Count ();
.Where (x => !ignoreFiles.Any (i => !Path.GetFileName (x).Contains (i))).Count ();
Assert.AreEqual (0, fileCount, "{0} should be Empty", proj.OutputPath);
}
}
@ -258,10 +262,10 @@ printf ""%d"" x
}
Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"),
b.Output.IsTargetSkipped ("_CompileJava"),
"the _CompileJava target should be skipped");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"),
b.Output.IsTargetSkipped ("_BuildApkEmbed"),
"the _BuildApkEmbed target should be skipped");
}
}
@ -309,10 +313,10 @@ printf ""%d"" x
}
Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"),
b.Output.IsTargetSkipped ("_CompileJava"),
"the _CompileJava target should be skipped");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"),
b.Output.IsTargetSkipped ("_BuildApkEmbed"),
"the _BuildApkEmbed target should be skipped");
}
}
@ -449,15 +453,15 @@ namespace UnnamedProject {
b.LastBuildTime, firstBuildTime
);
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"),
b.Output.IsTargetSkipped ("_Sign"),
"the _Sign target should not run");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_StripEmbeddedLibraries\" because"),
b.Output.IsTargetSkipped ("_StripEmbeddedLibraries"),
"the _StripEmbeddedLibraries target should not run");
proj.AndroidResources.First ().Timestamp = null;
Assert.IsTrue (b.Build (proj), "third build failed");
Assert.IsFalse (
b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"),
b.Output.IsTargetSkipped ("_Sign"),
"the _Sign target should run");
}
}
@ -485,21 +489,20 @@ namespace UnnamedProject {
b.LastBuildTime, firstBuildTime
);
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"),
b.Output.IsTargetSkipped ("_Sign"),
"the _Sign target should not run");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_StripEmbeddedLibraries\" because"),
b.Output.IsTargetSkipped ("_StripEmbeddedLibraries"),
"the _StripEmbeddedLibraries target should not run");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_LinkAssembliesShrink\" because"),
b.Output.IsTargetSkipped ("_LinkAssembliesShrink"),
"the _LinkAssembliesShrink target should not run");
foo.Timestamp = DateTime.UtcNow;
Assert.IsTrue (b.Build (proj), "third build failed");
Assert.IsTrue (b.LastBuildOutput.Contains ("Target CoreCompile needs to be built as input file ") ||
b.LastBuildOutput.Contains ("Building target \"CoreCompile\" completely."),
Assert.IsFalse (b.Output.IsTargetSkipped ("CoreCompile"),
"the Core Compile target should run");
Assert.IsFalse (
b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"),
b.Output.IsTargetSkipped ("_Sign"),
"the _Sign target should run");
}
}
@ -530,8 +533,11 @@ namespace UnnamedProject {
"UnnamedProject.dll.mdb must be copied to the Intermediate directory");
Assert.IsTrue (b.Build (proj), "second build failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"),
b.Output.IsTargetSkipped ("_CopyMdbFiles"),
"the _CopyMdbFiles target should be skipped");
Assert.IsTrue (
b.Output.IsTargetSkipped ("_CopyPdbFiles"),
"the _CopyPdbFiles target should be skipped");
Assert.IsTrue (
File.Exists (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android/assets/UnnamedProject.dll.mdb")) ||
File.Exists (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android/assets/UnnamedProject.pdb")),
@ -592,13 +598,31 @@ namespace App1
Assert.IsTrue (
File.Exists (assetsPdb),
"Library1.pdb must be copied to Intermediate directory");
Assert.IsTrue (
Assert.IsFalse (
File.Exists (linkDst),
"Library1.pdb must be copied to linkdst directory");
"Library1.pdb should not be copied to linkdst directory because it has no Abstrsact methods to fix up.");
Assert.IsTrue (
File.Exists (linkSrc),
"Library1.pdb must be copied to linksrc directory");
FileAssert.AreEqual (linkDst, assetsPdb, $"Library1.pdb in {assetsPdb} should match {linkDst}");
var outputPath = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath);
using (var apk = ZipHelper.OpenZip (Path.Combine (outputPath, proj.PackageName + ".apk"))) {
var data = ZipHelper.ReadFileFromZip (apk, "assemblies/Library1.pdb");
var filedata = File.ReadAllBytes (linkSrc);
Assert.AreEqual (filedata.Length, data.Length, "Library1.pdb in the apk should match {0}", linkSrc);
}
linkDst = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linkdst", "App1.pdb");
linkSrc = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linksrc", "App1.pdb");
Assert.IsTrue (
File.Exists (linkDst),
"App1.pdb should be copied to linkdst directory because it has Abstrsact methods to fix up.");
Assert.IsTrue (
File.Exists (linkSrc),
"App1.pdb must be copied to linksrc directory");
FileAssert.AreEqual (linkSrc, linkDst, "{0} and {1} should not differ.", linkSrc, linkDst);
linkDst = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linkdst", "App1.dll");
linkSrc = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linksrc", "App1.dll");
FileAssert.AreEqual (linkSrc, linkDst, "{0} and {1} should match.", linkSrc, linkDst);
}
}
}
@ -648,13 +672,13 @@ namespace App1
"NetStandard16.pdb must be copied to Intermediate directory");
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "second build failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"),
b.Output.IsTargetSkipped ("_CopyMdbFiles"),
"the _CopyMdbFiles target should be skipped");
var lastTime = File.GetLastAccessTimeUtc (pdbToMdbPath);
pdb.Timestamp = DateTime.UtcNow;
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "third build failed");
Assert.IsFalse (
b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"),
b.Output.IsTargetSkipped ("_CopyMdbFiles"),
"the _CopyMdbFiles target should not be skipped");
Assert.Less (lastTime,
File.GetLastAccessTimeUtc (pdbToMdbPath),
@ -683,7 +707,7 @@ namespace App1
"UnnamedProject.dll.config was must be copied to Intermediate directory");
Assert.IsTrue (b.Build (proj), "second build failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CopyConfigFiles\" because"),
b.Output.IsTargetSkipped ("_CopyConfigFiles"),
"the _CopyConfigFiles target should be skipped");
}
}
@ -717,13 +741,12 @@ namespace App1
b.Verbosity = LoggerVerbosity.Diagnostic;
b.ThrowOnBuildFailure = false;
Assert.IsTrue (b.Build (proj), "Build should not have failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Target _AddStaticResources needs to be built as output file") ||
b.LastBuildOutput.Contains ("Building target \"_AddStaticResources\" completely."),
Assert.IsFalse (
b.Output.IsTargetSkipped ("_AddStaticResources"),
"The _AddStaticResources should have been run");
Assert.IsTrue (b.Build (proj), "Build should not have failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_AddStaticResources\" because"),
b.Output.IsTargetSkipped ("_AddStaticResources"),
"The _AddStaticResources should NOT have been run");
}
}
@ -1048,6 +1071,8 @@ namespace App1
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
var apkPath = Path.Combine (Root, b.ProjectDirectory,
proj.IntermediateOutputPath,"android", "bin", "UnnamedProject.UnnamedProject.apk");
if (debugSymbols && optimize.HasValue && optimize.Value && debugType == "" && !b.RunningMSBuild)
expectedRuntime = "debug";
using (var apk = ZipHelper.OpenZip (apkPath)) {
foreach (var abi in supportedAbi) {
var runtime = runtimeInfo.FirstOrDefault (x => x.Abi == abi && x.Runtime == expectedRuntime);
@ -1745,15 +1770,16 @@ public class Test
"assemblies/PdbTestLibrary.pdb"),
"assemblies/PdbTestLibrary.pdb should not exist in the apk.");
}
b.BuildLogFile = "build1.log";
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "second build failed");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"),
b.Output.IsTargetSkipped ("_CopyMdbFiles"),
"the _CopyMdbFiles target should be skipped");
var lastTime = File.GetLastAccessTimeUtc (pdbToMdbPath);
pdb.Timestamp = DateTime.UtcNow;
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "third build failed");
Assert.IsFalse (
b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"),
b.Output.IsTargetSkipped ("_CopyMdbFiles"),
"the _CopyMdbFiles target should not be skipped");
Assert.Less (lastTime,
File.GetLastAccessTimeUtc (pdbToMdbPath),

Просмотреть файл

@ -59,20 +59,20 @@ public class TestMe {
using (var b = CreateApkBuilder (Path.Combine ("temp", "JavacTaskDoesNotRunOnSecondBuild"), false, false)) {
Assert.IsTrue (b.Build (app), "First build should have succeeded");
Assert.IsFalse (
b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"),
b.Output.IsTargetSkipped ("_CompileJava"),
"the _CompileJava target should not be skipped");
Assert.IsFalse (
b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"),
b.Output.IsTargetSkipped ("_BuildApkEmbed"),
"the _BuildApkEmbed target should not be skipped");
var expectedOutput = Path.Combine (Root, b.ProjectDirectory, app.IntermediateOutputPath, "android", "bin", "classes",
"com", "android", "test", "TestMe.class");
Assert.IsTrue (File.Exists (expectedOutput), string.Format ("{0} should exist.", expectedOutput));
Assert.IsTrue (b.Build (app), "Second build should have succeeded");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"),
b.Output.IsTargetSkipped ("_CompileJava"),
"the _CompileJava target should be skipped");
Assert.IsTrue (
b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"),
b.Output.IsTargetSkipped ("_BuildApkEmbed"),
"the _BuildApkEmbed target should be skipped");
Assert.IsTrue (File.Exists (expectedOutput), string.Format ("{0} should exist.", expectedOutput));
}

Просмотреть файл

@ -17,7 +17,7 @@ namespace Xamarin.Android.Build.Tests
new object[] { "", true, false, },
new object[] { "", false, true, },
new object[] { "None", true, false, },
new object[] { "None", false, false, },
new object[] { "None", false, true, },
new object[] { "PdbOnly", true, false, },
new object[] { "PdbOnly", false, true, },
new object[] { "Full", true, false, },

Просмотреть файл

@ -480,6 +480,8 @@ namespace Bug12935
using (var builder = CreateApkBuilder (Path.Combine ("temp", $"DebuggerAttribute_{debugType}_{isRelease}_{expected}"), false, false)) {
Assert.IsTrue (builder.Build (proj), "Build should have succeeded");
var manifest = builder.Output.GetIntermediaryAsText (Root, Path.Combine ("android", "AndroidManifest.xml"));
if (!isRelease && debugType == "None" && !builder.RunningMSBuild)
expected = false;
Assert.AreEqual (expected, manifest.Contains ("android:debuggable=\"true\""), $"Manifest {(expected ? "should" : "should not")} contain the andorid:debuggable attribute");
}
}

Просмотреть файл

@ -222,7 +222,13 @@ namespace Xamarin.Android.Build.Tests
TestContext.Out.WriteLine ("*************************************************************************");
TestContext.Out.WriteLine (file);
TestContext.Out.WriteLine ();
TestContext.Out.WriteLine (File.ReadAllText (file));
using (StreamReader reader = new StreamReader (file)) {
string line;
while ((line = reader.ReadLine ()) != null) {
TestContext.Out.WriteLine (line);
TestContext.Out.Flush ();
}
}
TestContext.Out.WriteLine ("*************************************************************************");
TestContext.Out.Flush ();
}

Просмотреть файл

@ -49,7 +49,10 @@ namespace Xamarin.ProjectTools
if (!Builder.LastBuildOutput.Contains (target))
throw new ArgumentException (string.Format ("Target '{0}' is not even in the build output.", target));
return Builder.LastBuildOutput.Contains (string.Format ("Target {0} skipped due to ", target))
|| Builder.LastBuildOutput.Contains (string.Format ("Skipping target \"{0}\" because it has no outputs.", target))
|| Builder.LastBuildOutput.Contains (string.Format ("Target \"{0}\" skipped, due to", target))
|| Builder.LastBuildOutput.Contains (string.Format ("Skipping target \"{0}\" because its outputs are up-to-date", target))
|| Builder.LastBuildOutput.Contains (string.Format ("target {0}, skipping", target))
|| Builder.LastBuildOutput.Contains ($"Skipping target \"{target}\" because all output files are up-to-date");
}

Просмотреть файл

@ -40,8 +40,10 @@ namespace Xamarin.ProjectTools
public string XABuildExe {
get {
if (IsUnix) {
if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("USE_MSBUILD"))) {
RunningMSBuild = true;
var useMSBuild = Environment.GetEnvironmentVariable ("USE_MSBUILD");
if (string.IsNullOrEmpty (useMSBuild) || useMSBuild == "0") {
RunningMSBuild = false;
}
return Path.GetFullPath (Path.Combine (Root, "..", "..", "tools", "scripts", "xabuild"));
}
@ -167,9 +169,12 @@ namespace Xamarin.ProjectTools
var start = DateTime.UtcNow;
var args = new StringBuilder ();
var psi = new ProcessStartInfo (XABuildExe);
args.AppendFormat ("{0} /t:{1} {2} /p:UseHostCompilerIfAvailable=false /p:BuildingInsideVisualStudio=true",
args.AppendFormat ("{0} /t:{1} {2}",
QuoteFileName(Path.Combine (Root, projectOrSolution)), target, logger);
if (RunningMSBuild)
args.Append (" /p:BuildingOutOfProcess=true");
else
args.Append (" /p:UseHostCompilerIfAvailable=false /p:BuildingInsideVisualStudio=true");
if (parameters != null) {
foreach (var param in parameters) {
args.AppendFormat (" /p:{0}", param);

Просмотреть файл

@ -24,31 +24,43 @@ namespace Xamarin.ProjectTools
foreach (var p in Projects) {
using (var pb = new ProjectBuilder (Path.Combine (SolutionPath, p.ProjectName))) {
pb.Save (p);
p.NuGetRestore (Path.Combine (SolutionPath, p.ProjectName), Path.Combine (SolutionPath, "packages"));
}
}
// write a sln.
var sb = new StringBuilder ();
sb.AppendFormat ("Microsoft Visual Studio Solution File, Format Version {0}\n", "12.00");
sb.AppendFormat ("# Visual Studio {0}\n", "2012");
sb.AppendFormat ("Microsoft Visual Studio Solution File, Format Version {0}\r\n", "12.00");
sb.AppendFormat ("# Visual Studio {0}\r\n", "2012");
foreach (var p in Projects) {
sb.AppendFormat ("Project(\"{{{0}}}\") = \"{1}\", \"{2}\", \"{{{3}}}\"\n", p.ProjectTypeGuid, p.ProjectName,
sb.AppendFormat ("Project(\"{{{0}}}\") = \"{1}\", \"{2}\", \"{{{3}}}\"\r\n", p.ProjectTypeGuid, p.ProjectName,
Path.Combine(p.ProjectName,p.ProjectFilePath), p.ProjectGuid);
sb.Append ("EndProject\n");
sb.Append ("EndProject\r\n");
}
sb.Append ("Global\n");
sb.Append ("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n");
sb.Append ("\t\tDebug|AnyCPU = Debug|AnyCPU\n");
sb.Append ("\t\tRelease|AnyCPU = Release|AnyCPU\n");
sb.Append ("\tEndGlobalSection\n");
sb.Append ("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n");
sb.Append ("Global\r\n");
sb.Append ("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n");
sb.Append ("\t\tDebug|AnyCPU = Debug|AnyCPU\r\n");
sb.Append ("\t\tRelease|AnyCPU = Release|AnyCPU\r\n");
sb.Append ("\tEndGlobalSection\r\n");
sb.Append ("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n");
foreach (var p in Projects) {
sb.AppendFormat ("{{{0}}}.Debug|AnyCPU.ActiveCfg = Debug|AnyCPU\n", p.ProjectGuid);
sb.AppendFormat ("{{{0}}}.Debug|AnyCPU.Build.0 = Debug|AnyCPU\n", p.ProjectGuid);
sb.AppendFormat ("{{{0}}}.Release|AnyCPU.ActiveCfg = Release|AnyCPU\n", p.ProjectGuid);
sb.AppendFormat ("{{{0}}}.Release|AnyCPU.Build.0 = Release|AnyCPU\n", p.ProjectGuid);
sb.AppendFormat ("\t\t{{{0}}}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU\r\n", p.ProjectGuid);
sb.AppendFormat ("\t\t{{{0}}}.Debug|AnyCPU.Build.0 = Debug|Any CPU\r\n", p.ProjectGuid);
if (p is XamarinAndroidApplicationProject)
sb.AppendFormat ("\t\t{{{0}}}.Debug|AnyCPU.Deploy.0 = Debug|Any CPU\r\n", p.ProjectGuid);
sb.AppendFormat ("\t\t{{{0}}}.Release|AnyCPU.ActiveCfg = Release|Any CPU\r\n", p.ProjectGuid);
sb.AppendFormat ("\t\t{{{0}}}.Release|AnyCPU.Build.0 = Release|Any CPU\r\n", p.ProjectGuid);
if (p is XamarinAndroidApplicationProject)
sb.AppendFormat ("\t\t{{{0}}}.Release|AnyCPU.Deploy.0 = Release|Any CPU\r\n", p.ProjectGuid);
}
sb.Append ("\tEndGlobalSection\n");
sb.Append ("EndGlobal\n");
sb.Append ("\tEndGlobalSection\r\n");
sb.Append ("\tGlobalSection (SolutionProperties) = preSolution\r\n");
sb.Append ("\t\tHideSolutionNode = FALSE\r\n");
sb.Append ("\tEndGlobalSection\r\n");
sb.Append ("\tGlobalSection (ExtensibilityGlobals) = postSolution\r\n");
sb.Append ("\t\tSolutionGuid = { BA9651E4 - A332 - 4729 - 9FB4 - 24520221DC3C}\r\n");
sb.Append ("\tEndGlobalSection\r\n");
sb.Append ("EndGlobal\r\n");
File.WriteAllText (Path.Combine (SolutionPath, SolutionName), sb.ToString ());
}

Просмотреть файл

@ -61,7 +61,6 @@ namespace Xamarin.ProjectTools
SetProperty ("ConsolePause", "false");
SetProperty ("RootNamespace", () => RootNamespace ?? ProjectName);
SetProperty ("AssemblyName", () => AssemblyName ?? ProjectName);
SetProperty ("BuildingInsideVisualStudio", "True");
SetProperty ("BaseIntermediateOutputPath", "obj\\", " '$(BaseIntermediateOutputPath)' == '' ");
SetProperty (DebugProperties, "DebugSymbols", "true");
@ -257,7 +256,7 @@ namespace Xamarin.ProjectTools
Timestamp = ItemGroupList.SelectMany (ig => ig).Where (i => i.Timestamp != null).Select (i => (DateTimeOffset)i.Timestamp).Max (),
Path = ProjectFilePath,
Content = SaveProject (),
Encoding = System.Text.Encoding.Unicode
Encoding = System.Text.Encoding.UTF8,
});
}

Просмотреть файл

@ -297,6 +297,7 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved.
<ResolveLibraryProjectImports
ContinueOnError="$(DesignTimeBuild)"
CacheFile="$(_AndroidLibraryProjectImportsCache)"
DesignTimeBuild="$(DesignTimeBuild)"
Assemblies="@(ReferencePath);@(ReferenceDependencyPaths)"
ImportsDirectory="$(_LibraryProjectImportsDirectoryName)"
UseShortFileNames="$(UseShortFileNames)"

Просмотреть файл

@ -277,6 +277,12 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
</PropertyGroup>
<!-- Force Xbuild to behave like msbuild -->
<PropertyGroup>
<DebugSymbols Condition=" '$(DebugType)' == 'None' ">false</DebugSymbols>
<DebugType Condition=" '$(DebugType)' == 'None' ">portable</DebugType>
</PropertyGroup>
<Choose>
<When Condition=" '$(DebugSymbols)' == 'True' And '$(DebugType)' != '' And ('$(EmbedAssembliesIntoApk)' == 'False' Or '$(Optimize)' != 'True') ">
<PropertyGroup>
@ -456,7 +462,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
<Target Name="_StripEmbeddedLibraries"
Inputs="@(ResolvedAssemblies)"
Outputs="$(_AndroidStripFlag)"
DependsOnTargets="_CopyIntermediateAssemblies;_CopyMdbFiles">
DependsOnTargets="_CopyIntermediateAssemblies;_CopyPdbFiles;_CopyMdbFiles">
<StripEmbeddedLibraries
Condition="'$(AndroidLinkMode)' != 'None' AND '$(AndroidUseSharedRuntime)' != 'true'"
Assemblies="@(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')" />
@ -1079,6 +1085,7 @@ because xbuild doesn't support framework reference assemblies.
IsApplication="$(AndroidApplication)"
References="@(ReferencePath)"
UseManagedResourceGenerator="True"
DesignTimeBuild="$(DesignTimeBuild)"
/>
<ItemGroup>
<CorrectCasedItem Include="%(Compile.Identity)" Condition="'%(Compile.Identity)' == '$(AndroidResgenFile)'"/>
@ -1148,6 +1155,7 @@ because xbuild doesn't support framework reference assemblies.
<ResolveLibraryProjectImports
ContinueOnError="$(DesignTimeBuild)"
CacheFile="$(_AndroidLibraryProjectImportsCache)"
DesignTimeBuild="$(DesignTimeBuild)"
Assemblies="@(ReferencePath);@(ReferenceDependencyPaths)"
ImportsDirectory="$(_LibraryProjectImportsDirectoryName)"
UseShortFileNames="$(UseShortFileNames)"
@ -1411,6 +1419,7 @@ because xbuild doesn't support framework reference assemblies.
IsApplication="$(AndroidApplication)"
References="@(ReferencePath)"
UseManagedResourceGenerator="False"
DesignTimeBuild="$(DesignTimeBuild)"
/>
<!-- Only copy if the file contents changed, so users only get Reload? dialog for real changes -->
@ -1644,25 +1653,49 @@ because xbuild doesn't support framework reference assemblies.
Overwrite="false" />
</Target>
<Target Name="_CopyMdbFiles"
Inputs="@(_ResolvedMdbFiles);@(_ResolvedPortablePdbFiles)"
Outputs="@(_ResolvedMdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)');@(_ResolvedPortablePdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
DependsOnTargets="_ConvertPdbFiles;_CollectMdbFiles" >
<Target Name="_CopyPdbFiles"
Inputs="@(_ResolvedPortablePdbFiles)"
Outputs="@(_ResolvedPortablePdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
DependsOnTargets="_ConvertPdbFiles">
<CopyMdbFiles
SourceFiles="@(_ResolvedMdbFiles);@(_ResolvedPortablePdbFiles)"
DestinationFiles="@(_ResolvedMdbFiles->'$(OutputPath)%(Filename)%(Extension)');@(_ResolvedPortablePdbFiles->'$(OutputPath)%(Filename)%(Extension)')">
<Output TaskParameter="CopiedFiles" ItemName="_MdbFilesCopied" />
SourceFiles="@(_ResolvedPortablePdbFiles)"
DestinationFiles="@(_ResolvedPortablePdbFiles->'$(OutputPath)%(Filename)%(Extension)')">
<Output TaskParameter="CopiedFiles" ItemName="_PdbFilesCopied" />
<Output TaskParameter="CopiedFiles" ItemName="FileWrites" />
</CopyMdbFiles>
<Copy
SourceFiles="@(_ResolvedMdbFiles->'$(OutputPath)%(Filename)%(Extension)');@(_ResolvedPortablePdbFiles->'$(OutputPath)%(Filename)%(Extension)')"
DestinationFiles="@(_ResolvedMdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)');@(_ResolvedPortablePdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
SourceFiles="@(_ResolvedPortablePdbFiles->'$(OutputPath)%(Filename)%(Extension)')"
DestinationFiles="@(_ResolvedPortablePdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true">
<Output TaskParameter="CopiedFiles" ItemName="_DebugFilesCopiedToLinkerSrc" />
<Output TaskParameter="CopiedFiles" ItemName="_PdbDebugFilesCopiedToLinkerSrc" />
<Output TaskParameter="CopiedFiles" ItemName="FileWrites" />
</Copy>
<Touch Files="@(_DebugFilesCopiedToLinkerSrc)" />
<WriteLinesToFile
File="$(IntermediateOutputPath)$(CleanFile)"
Lines="@(_MdbFilesCopied);@(_DebugFilesCopiedToLinkerSrc)"
Lines="@(_PdbFilesCopied->'%(FullPath)');@(_PdbDebugFilesCopiedToLinkerSrc->'%(FullPath)')"
Overwrite="false" />
</Target>
<Target Name="_CopyMdbFiles"
Inputs="@(_ResolvedMdbFiles)"
Outputs="@(_ResolvedMdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
DependsOnTargets="_CollectMdbFiles" >
<CopyMdbFiles
SourceFiles="@(_ResolvedMdbFiles)"
DestinationFiles="@(_ResolvedMdbFiles->'$(OutputPath)%(Filename)%(Extension)')">
<Output TaskParameter="CopiedFiles" ItemName="_MdbFilesCopied" />
</CopyMdbFiles>
<Copy
SourceFiles="@(_ResolvedMdbFiles->'$(OutputPath)%(Filename)%(Extension)')"
DestinationFiles="@(_ResolvedMdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true">
<Output TaskParameter="CopiedFiles" ItemName="_MdbDebugFilesCopiedToLinkerSrc" />
</Copy>
<Touch Files="@(_DebugFilesCopiedToLinkerSrc)" />
<WriteLinesToFile
File="$(IntermediateOutputPath)$(CleanFile)"
Lines="@(_MdbFilesCopied->'%(FullPath)');@(_MdbDebugFilesCopiedToLinkerSrc->'%(FullPath)')"
Overwrite="false" />
</Target>

Просмотреть файл

@ -83,7 +83,7 @@ else
fi
if [[ "$MSBUILD" == "msbuild" ]] ; then
exec mono "$prefix/bin/xabuild.exe" "$@"
exec mono "$prefix/bin/xabuild.exe" "$@" "/p:MonoDroidInstallDirectory=$prefix"
exit $?
fi
@ -129,7 +129,7 @@ export MSBuildExtensionsPath="$TARGETS_DIR"
case "$MSBUILD" in
*msbuild*)
XABUILD_FLAGS+=(/p:TargetFrameworkRootPath="$TARGETS_DIR-frameworks")
XABUILD_FLAGS+=(/p:TargetFrameworkRootPath="$TARGETS_DIR-frameworks/")
;;
*xbuild*)
export XBUILD_FRAMEWORK_FOLDERS_PATH="$TARGETS_DIR-frameworks"