diff --git a/external/xamarin-android-tools.override.props b/external/xamarin-android-tools.override.props new file mode 100644 index 00000000000..05002e1cacc --- /dev/null +++ b/external/xamarin-android-tools.override.props @@ -0,0 +1,3 @@ + + + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index b17f7beafbb..f3df17b4c1c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -2577,5 +2577,27 @@ public void SimilarAndroidXAssemblyNames ([Values(true, false)] bool publishTrim using var builder = CreateApkBuilder (); Assert.IsTrue (builder.Build (proj), "Build should have succeeded."); } + + /// + /// Build with MSBuild.exe on .NET framework, instead of 'dotnet build' + /// + [Test] + public void BuildWithMSBuild ([Values (true, false)] bool isRelease) + { + if (!IsWindows) + Assert.Ignore ("Test is only valid on Windows platforms"); + + var proj = new XamarinAndroidApplicationProject { + IsRelease = isRelease, + }; + using var builder = CreateApkBuilder (); + + // Use MSBuild.exe, setting %PATH% to our local 'dotnet' directory + builder.BuildTool = TestEnvironment.GetVisualStudioInstance ().MSBuildPath; + var environment = new Dictionary (); + environment ["PATH"] = $"{TestEnvironment.DotNetPreviewDirectory};{Environment.GetEnvironmentVariable ("PATH")}"; + + Assert.IsTrue (builder.Build (proj, environmentVariables: environment), "Build should have succeeded."); + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/MSBuildSdkExtrasProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/MSBuildSdkExtrasProject.cs index 2c8304041de..249549f0465 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/MSBuildSdkExtrasProject.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/MSBuildSdkExtrasProject.cs @@ -20,11 +20,6 @@ public MSBuildSdkExtrasProject () public string StringsXml { get; set; } - /// - /// /t:Restore or /restore is always required - /// - public override bool ShouldRestorePackageReferences => true; - public string TargetFrameworks { get => GetProperty (nameof (TargetFrameworks)); set => SetProperty (nameof (TargetFrameworks), value); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs index 334aa28ddfb..d3d2b31d9d4 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs @@ -53,16 +53,22 @@ public IEnumerable LastBuildOutput { /// public bool AutomaticNuGetRestore { get; set; } = true; + string _buildTool; + public string BuildTool { - get { - if (UseDotNet) - return Path.Combine (TestEnvironment.DotNetPreviewDirectory, "dotnet"); + get => _buildTool ??= FindBuildTool (); + set => _buildTool = value; + } - string xabuild = IsUnix ? XABuildPaths.XABuildScript : XABuildPaths.XABuildExe; - if (File.Exists (xabuild) && TestEnvironment.UseLocalBuildOutput) - return xabuild; - return IsUnix ? "msbuild" : TestEnvironment.GetVisualStudioInstance ().MSBuildPath; - } + string FindBuildTool () + { + if (UseDotNet) + return Path.Combine (TestEnvironment.DotNetPreviewDirectory, "dotnet"); + + string xabuild = IsUnix ? XABuildPaths.XABuildScript : XABuildPaths.XABuildExe; + if (File.Exists (xabuild) && TestEnvironment.UseLocalBuildOutput) + return xabuild; + return IsUnix ? "msbuild" : TestEnvironment.GetVisualStudioInstance ().MSBuildPath; } public bool CrossCompilerAvailable (string supportedAbis) @@ -186,7 +192,7 @@ protected virtual void Dispose (bool disposing) RegexOptions.Multiline | RegexOptions.Compiled ); - protected bool BuildInternal (string projectOrSolution, string target, string [] parameters = null, Dictionary environmentVariables = null, bool restore = true, string binlogName = "msbuild") + protected bool BuildInternal (string projectOrSolution, string target, string [] parameters = null, Dictionary environmentVariables = null, string binlogName = "msbuild") { buildLogFullPath = (!string.IsNullOrEmpty (BuildLogFile)) ? Path.GetFullPath (Path.Combine (XABuildPaths.TestOutputDirectory, Path.GetDirectoryName (projectOrSolution), BuildLogFile)) @@ -204,8 +210,11 @@ protected bool BuildInternal (string projectOrSolution, string target, string [] var args = new StringBuilder (); var psi = new ProcessStartInfo (BuildTool); var responseFile = Path.Combine (XABuildPaths.TestOutputDirectory, Path.GetDirectoryName (projectOrSolution), "project.rsp"); + var isMSBuild = string.Equals (Path.GetFileNameWithoutExtension (psi.FileName), "MSBuild", StringComparison.OrdinalIgnoreCase); if (UseDotNet) { - args.Append ("build "); + if (!isMSBuild) { + args.Append ("build "); + } if (TestEnvironment.UseLocalBuildOutput) { psi.SetEnvironmentVariable ("DOTNETSDK_WORKLOAD_MANIFEST_ROOTS", TestEnvironment.WorkloadManifestOverridePath); psi.SetEnvironmentVariable ("DOTNETSDK_WORKLOAD_PACK_ROOTS", TestEnvironment.WorkloadPackOverridePath); @@ -213,11 +222,11 @@ protected bool BuildInternal (string projectOrSolution, string target, string [] } args.AppendFormat ("{0} /t:{1} {2}", QuoteFileName (Path.Combine (XABuildPaths.TestOutputDirectory, projectOrSolution)), target, logger); - if (UseDotNet) { + if (UseDotNet && !isMSBuild) { if (!AutomaticNuGetRestore) { args.Append (" --no-restore"); } - } else if (AutomaticNuGetRestore && restore) { + } else if (AutomaticNuGetRestore) { args.Append (" /restore"); } @@ -256,6 +265,7 @@ protected bool BuildInternal (string projectOrSolution, string target, string [] } psi.SetEnvironmentVariable ("MSBUILD", "msbuild"); + psi.SetEnvironmentVariable ("MSBUILDLOGALLENVIRONMENTVARIABLES", "1"); // So .binlog files contain all env vars sw.WriteLine ($"/bl:\"{Path.GetFullPath (Path.Combine (XABuildPaths.TestOutputDirectory, Path.GetDirectoryName (projectOrSolution), $"{binlogName}.binlog"))}\""); if (environmentVariables != null) { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs index cc396f31c0f..4a1d15c1711 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs @@ -23,9 +23,6 @@ public DotNetStandard () Language = XamarinAndroidProjectLanguage.CSharp; } - // NetStandard projects always need to restore - public override bool ShouldRestorePackageReferences => true; - public string PackageTargetFallback { get { return GetProperty ("PackageTargetFallback"); } set { SetProperty ("PackageTargetFallback", value); } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs index 6118fc6a0c8..702c3845cb7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs @@ -70,7 +70,7 @@ public bool Build (XamarinProject project, bool doNotCleanupOnUpdate = false, st project.NuGetRestore (Path.Combine (XABuildPaths.TestOutputDirectory, ProjectDirectory), PackagesDirectory); } - bool result = BuildInternal (Path.Combine (ProjectDirectory, project.ProjectFilePath), Target, parameters, environmentVariables, restore: project.ShouldRestorePackageReferences, binlogName: Path.GetFileNameWithoutExtension (BuildLogFile)); + bool result = BuildInternal (Path.Combine (ProjectDirectory, project.ProjectFilePath), Target, parameters, environmentVariables, binlogName: Path.GetFileNameWithoutExtension (BuildLogFile)); built_before = true; if (CleanupAfterSuccessfulBuild) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs index 6485a65c7b5..2bd2b8f7834 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs @@ -67,7 +67,7 @@ public void Save () public bool BuildProject(XamarinProject project, string target = "Build") { - BuildSucceeded = BuildInternal(Path.Combine (SolutionPath, project.ProjectName, project.ProjectFilePath), target, restore: project.ShouldRestorePackageReferences); + BuildSucceeded = BuildInternal(Path.Combine (SolutionPath, project.ProjectName, project.ProjectFilePath), target); return BuildSucceeded; } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs index 7ce6c520bfe..2a18c5d8f9f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs @@ -33,7 +33,6 @@ public abstract class XamarinProject public string GlobalPackagesFolder { get; set; } = FileSystemUtils.FindNugetGlobalPackageFolder (); public IList ExtraNuGetConfigSources { get; set; } = new List (); - public virtual bool ShouldRestorePackageReferences => PackageReferences?.Count > 0; /// /// If true, the ProjectDirectory will be deleted and populated on the first build ///