Skip to content
Closed
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
6 changes: 6 additions & 0 deletions Documentation/release-notes/fix-4677.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#### Application and library build and deployment

- [GitHub 4677](https://github.com/xamarin/xamarin-android/issues/4677):
On Windows, the `InstallAndroidDependencies` MSBuild target would not yet
install the expected Android SDK Platform or Android SDK Build-Tools
components in a newly configured command line build environment.
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public override bool RunTask ()
manifestApiLevel = manifest.TargetSdkVersion ?? manifest.MinSdkVersion ?? DefaultMinSDKVersion;
}
var sdkVersion = Math.Max (targetApiLevel.Value, manifestApiLevel);
dependencies.Add (CreateAndroidDependency ($"platforms/android-{sdkVersion}", $""));
dependencies.Add (CreateAndroidDependency ($"build-tools/{BuildToolsVersion}", BuildToolsVersion));
dependencies.Add (CreateAndroidDependency (Path.Combine ("platforms", $"android-{sdkVersion}"), $""));
Copy link
Contributor

Choose a reason for hiding this comment

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

This must have changed behaviour in the sdk installer. I seem to remember the spec required the system to use / as a separator :/

Copy link
Contributor

Choose a reason for hiding this comment

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

Relevant spec: https://microsoft-my.sharepoint.com/:w:/p/mhutch/ETjdNgT_yfJMszzuRRW2hUYB133Goo831A5U2rAFwgI8bA?e=77b68c4ccf5841139a242a0d99cd0368

Forward slash / is explicitly mentioned in the spec:

For items in the main Android repository manifest, the ID shall be the path formatted in *nix format, e.g. “platforms/android-25” or “ndk-bundle”. For add-ons, the ID shall be the add-on’s “name-id” property. We will also have our own manifest format where the fileSystemPath will be exposed directly.

We do not want to use Path.Combine() here.

Copy link
Contributor

Choose a reason for hiding this comment

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

So in that case the issue must be in the task which calls the SDK Manager or the SDK Manager code itself I guess.

dependencies.Add (CreateAndroidDependency (Path.Combine ("build-tools", BuildToolsVersion), BuildToolsVersion));
if (!string.IsNullOrEmpty (PlatformToolsVersion)) {
dependencies.Add (CreateAndroidDependency ("platform-tools", PlatformToolsVersion));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
using Xamarin.ProjectTools;

Expand All @@ -13,19 +15,42 @@ public class AndroidDependenciesTests : BaseTest
[Test]
public void InstallAndroidDependenciesTest ()
{
var path = Path.Combine (Root, "temp", TestName);
TestOutputDirectories [TestContext.CurrentContext.Test.ID] = path;
if (!CommercialBuildAvailable)
Assert.Ignore ("Not required on Open Source Builds");
var old = Environment.GetEnvironmentVariable ("ANDROID_SDK_PATH");
try {
string sdkPath = Path.Combine (Root, "temp", TestName, "android-sdk");
string sdkPath = Path.Combine (path, "android-sdk");
CreateFauxAndroidSdkDirectory (sdkPath, buildToolsVersion: "23.0.0");
// Provide mock version info so the `tools` component won't be downloaded.
File.WriteAllText (Path.Combine (sdkPath, "tools", "source.properties"), "Pkg.Revision=99.99.99");
Environment.SetEnvironmentVariable ("ANDROID_SDK_PATH", sdkPath);
var proj = new XamarinAndroidApplicationProject ();
using (var b = CreateApkBuilder ()) {
// Use `BuildHelper.CreateApkBuilder()` instead of `BaseTest.CreateApkBuilder()` so
// `android-sdk` can be placed beside the project directory rather than within it.
using (var b = BuildHelper.CreateApkBuilder (Path.Combine (path, "Project"))) {
string defaultTarget = b.Target;
b.Target = "InstallAndroidDependencies";
b.ThrowOnBuildFailure = false;
Assert.IsFalse (b.Build (proj, parameters: new string [] { "AcceptAndroidSDKLicenses=false" }), "InstallAndroidDependencies should have failed.");
IEnumerable<string> taskOutput = b.LastBuildOutput
.SkipWhile (x => !(x.StartsWith (" Detecting Android SDK in") && x.Contains (sdkPath)))
.TakeWhile (x => !x.StartsWith ("Done executing task \"InstallAndroidDependencies\""))
.Where (x => x.StartsWith (" Dependency to be installed:"));
Assert.AreEqual (2, taskOutput.Count (), "Exactly two dependencies should be identified to be installed.");
StringAssertEx.Contains ("Dependency to be installed: Android SDK Platform", taskOutput);
StringAssertEx.Contains ("Dependency to be installed: Android SDK Build-Tools", taskOutput);
b.ThrowOnBuildFailure = true;
Assert.IsTrue (b.Build (proj, parameters: new string [] { "AcceptAndroidSDKLicenses=true" }), "InstallAndroidDependencies should have succeeded.");
Assert.IsTrue (Directory.Exists (Path.Combine (sdkPath, "platforms")), "At least one platform should have been installed");
Assert.IsTrue (Directory.Exists (Path.Combine (sdkPath, "build-tools")), "At least one Build Tools version should have been installed");
b.Target = defaultTarget;
Assert.IsTrue (b.Build (proj), "build should have succeeded.");
taskOutput = b.LastBuildOutput
.SkipWhile (x => !x.StartsWith (" ResolveSdks Outputs:"))
.TakeWhile (x => !x.StartsWith ("Done executing task \"ResolveSdks\""));
StringAssert.Contains (sdkPath, taskOutput.First (x => x.StartsWith (" AndroidSdkPath:")));
}
} finally {
Environment.SetEnvironmentVariable ("ANDROID_SDK_PATH", old);
Expand Down