Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] %(AndroidApiInfo.Stable)=False (#1499)
Browse files Browse the repository at this point in the history
* [Xamarin.Android.Build.Tasks] %(AndroidApiInfo.Stable)=False

Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/592736
Fixes: #1498

Context: 0780e27
Context: #1439

What does it take to *use* a new (and unstable!) API level?

Commit 8942eca tried to lay some of this out, but *in principal* the
current process should be:

 1. Bind the new API level.
 2. Add a new `@(AndroidApiInfo)` entry for the new API level.
 3. Specify the `$(TargetFrameworkVersion)` of the new API level when
    building a project.

Commit 8ce2537 bound API-P as v8.1.99, finishing steps (1) and (2).
Therefore, step (3) should just work, right?

	$ cd samples/HelloWorld
	$ ../../bin/Debug/bin/xabuild /p:TargetFrameworkVersion=v8.1.99
	# no errors

Success!

Except, when reading the diagnostic log file, we see:

	ResolveSdksTask Outputs:
	  AndroidApiLevel: 27
	  AndroidApiLevelName: 27
	  ...
	  TargetFrameworkVersion: v8.1.99

We're using the correct v8.1.99 *binding assembly*, but we're *not*
using the API-P `android.jar`, because the `<ResolveSdks>` task is
treating v8.1.99 (API-P/API-28) as API-27.

Oops.

---

There are three msbuild invocations of consequence here:

 1. `xabuild /p:AndroidUseLatestPlatformSdk=True`
 2. `xabuild /p:AndroidUseLatestPlatformSdk=True  /p:TargetFrameworkVersion=v8.1.99`
 3. `xabuild /p:AndroidUseLatestPlatformSdk=False /p:TargetFrameworkVersion=v8.1.99`

(1) is the "default build" scenario (at least so long as our default
project templates specify `$(AndroidUseLatestPlatformSdk)`=True).
This should build the project against the latest *stable* API level
and `$(TargetFrameworkVersion)`, as per 0780e27. This works. (Yay!)

If you want to build an *unstable* API level, then the
`$(TargetFrameworkVersion)` value must be set explicitly, either on
the command-line (as shown here) or by editing the `.csproj`.

(2) and (3) are variations to build using the unstable API-P binding;
they *should* be identical, but due to code-path differences in
`<ResolveSdks>`, they are not necessarily the same.

Both (2) and (3) *should* work; they don't, with different behaviors.

(2) *builds*, but uses the wrong `android.jar` during compilation, as
described above with the `samples/HelloWorld` example.

Fix (2) by setting `ResolveSdks.AndroidApiLevel` to
`ResolveSdks.SupportedApiLevel`, so that it overrides the default
behavior of using the latest *stable* API level value when
`$(AndroidUseLatestPlatformSdk)`=True.

(3) does *not* build:

	  ResolveSdksTask Outputs:
	    AndroidApiLevel: P
	    AndroidApiLevelName: P
	...
	Task "GetAndroidDefineConstants"
	…\Xamarin\Android\Xamarin.Android.Common.targets(910,29):
	error MSB4030: "P" is an invalid value for the "AndroidApiLevel" parameter of the "GetAndroidDefineConstants" task. The "AndroidApiLevel" parameter is of type "System.Int32".
	Done executing task "GetAndroidDefineConstants" -- FAILED.

(3) doesn't build because the `<GetAndroidDefineConstants/>` task
invocation is provided `$(_SupportedApiLevel)`, which is the above
`AndroidApiLevel` output, and thus contains a value of `P`.

Fix (3) by using `AndroidVersions.GetApiLevelFromId()` to lookup the
correct API level based on the id derived from
`$(TargetFrameworkVersion)` value.

This in turn raises a *different* bug: `aapt package` doesn't like
to use id values, it wants *just* numbers. Fixing *just*
`<ResolveSdks>` results in a build error:

	Aapt Task
	  ...
	Executing package -f -m -M obj/Debug/android/manifest/AndroidManifest.xml -J /var/folders/1y/wwmg3hv5685ft661f5q2w2100000gn/T/7464w5of.vfk --custom-package com.xamarin.android.helloworld -F obj/Debug/android/bin/packaged_resources.bk -S obj/Debug/res/ -I …/android-toolchain/sdk/platforms/android-P/android.jar --auto-add-overlay --max-res-version P
	aapt: error APT0000: max res 0, skipping mipmap-hdpi "max res 0, skipping mipmap-hdpi".
	aapt: error APT0000: max res 0, skipping mipmap-mdpi "max res 0, skipping mipmap-mdpi".
	aapt: error APT0000: max res 0, skipping mipmap-xhdpi "max res 0, skipping mipmap-xhdpi".
	aapt: error APT0000: max res 0, skipping mipmap-xxhdpi "max res 0, skipping mipmap-xxhdpi".
	aapt: error APT0000: max res 0, skipping mipmap-xxxhdpi "max res 0, skipping mipmap-xxxhdpi".
	obj/Debug/android/manifest/AndroidManifest.xml(7): error APT0000: No resource found that matches the given name (at 'icon' with value '@mipmap/icon').
	obj/Debug/android/manifest/AndroidManifest.xml(8): error APT0000: No resource found that matches the given name (at 'icon' with value '@mipmap/icon').

Fix this by updating the `<GetJavaPlatformJar/>` task so that
`GetJavaPlatformJar.TargetSdkVersion` contains an integer API level
value, not the API id. This fixes the `<Aapt/>` error.

* Add  to LibraryResources.csproj
  • Loading branch information
jonpryor authored and dellis1972 committed Apr 4, 2018
1 parent aee709d commit 33822ad
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override bool Execute ()
if (JavaPlatformJarPath == null)
return !Log.HasLoggedErrors;

TargetSdkVersion = platform;
TargetSdkVersion = MonoAndroidHelper.SupportedVersions.GetApiLevelFromId (platform).ToString ();

Log.LogDebugMessage (" [Output] JavaPlatformJarPath: {0}", JavaPlatformJarPath);
Log.LogDebugMessage (" [Output] TargetSdkVersion: {0}", TargetSdkVersion);
Expand Down
24 changes: 13 additions & 11 deletions src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -435,33 +435,35 @@ bool ValidateApiLevels ()
// overwrite using user version only if it is
// above the maxStableApi and a valid apiLevel.
if (userSelected != null && userSelected > maxSupported && userSelected <= maxInstalled) {
AndroidApiLevel = userSelected.ToString ();
SupportedApiLevel = userSelected.ToString ();
}
}
TargetFrameworkVersion = GetTargetFrameworkVersionFromApiLevel ();
return TargetFrameworkVersion != null;
}

if (!string.IsNullOrWhiteSpace (AndroidApiLevel)) {
AndroidApiLevel = AndroidApiLevel.Trim ();
SupportedApiLevel = GetMaxSupportedApiLevel (AndroidApiLevel);
TargetFrameworkVersion = GetTargetFrameworkVersionFromApiLevel ();
return TargetFrameworkVersion != null;
}

if (!string.IsNullOrWhiteSpace (TargetFrameworkVersion)) {
TargetFrameworkVersion = TargetFrameworkVersion.Trim ();
string apiLevel = MonoAndroidHelper.SupportedVersions.GetIdFromFrameworkVersion (TargetFrameworkVersion);
if (apiLevel == null) {
string id = MonoAndroidHelper.SupportedVersions.GetIdFromFrameworkVersion (TargetFrameworkVersion);
if (id == null) {
Log.LogCodedError ("XA0000",
"Could not determine API level for $(TargetFrameworkVersion) of '{0}'.",
TargetFrameworkVersion);
return false;
}
AndroidApiLevel = apiLevel;
SupportedApiLevel = apiLevel;
AndroidApiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromId (id).ToString ();
SupportedApiLevel = AndroidApiLevel;
return true;
}

if (!string.IsNullOrWhiteSpace (AndroidApiLevel)) {
AndroidApiLevel = AndroidApiLevel.Trim ();
SupportedApiLevel = GetMaxSupportedApiLevel (AndroidApiLevel);
TargetFrameworkVersion = GetTargetFrameworkVersionFromApiLevel ();
return TargetFrameworkVersion != null;
}

Log.LogCodedError ("XA0000", "Could not determine $(AndroidApiLevel) or $(TargetFrameworkVersion); SHOULD NOT BE REACHED.");
return false;
}
Expand Down
3 changes: 3 additions & 0 deletions tests/locales/LibraryResources/LibraryResources.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<AssemblyName>LibraryResources</AssemblyName>
</PropertyGroup>
<Import Project="..\..\..\Configuration.props" />
<PropertyGroup>
<TargetFrameworkVersion>$(AndroidFrameworkVersion)</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
Expand Down

0 comments on commit 33822ad

Please sign in to comment.