Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Xamarin.Android.Build.Tasks] %(AndroidApiInfo.Stable)=False #1499

Merged
merged 2 commits into from Apr 4, 2018

Conversation

jonpryor
Copy link
Member

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.

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.
@jonpryor
Copy link
Member Author

@dellis1972: We'd like to get this into d15-7. In the event that this needs additional work, could you please "take it over" and finish things?

This probably also deserves additional MSBuild unit tests.

@jonpryor jonpryor added this to the d15-7 milestone Mar 30, 2018
@jonathanpeppers
Copy link
Member

@dellis1972 when you look at this next week, specifically one of the tests projects is failing to build (on Windows) on this PR: https://devdiv.visualstudio.com/DevDiv/_build/index?buildId=1539895

Message is something related to:

2018-03-30T17:50:58.1741798Z _SetLatestTargetFrameworkVersion:
2018-03-30T17:50:58.1784610Z E:\A\_work\2\s\tests\locales\LibraryResources\LibraryResources.csproj : error XA0001: Unsupported or invalid $(TargetFrameworkVersion) value of 'v2.3'. Please update your Project Options.

Every other project in the test sln seems to print TargetFrameworkVersion=v8.1 in the log.

@dellis1972 dellis1972 self-assigned this Apr 3, 2018
@dellis1972
Copy link
Contributor

build

Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

I think this is good, assuming the Windows PR build will pass. It's already past the point it failed last time.

@dellis1972 dellis1972 merged commit 33822ad into master Apr 4, 2018
@dellis1972
Copy link
Contributor

@jonathanpeppers Merged.

@pjcollins
Copy link
Member

@dellis1972 @jonpryor this works for the scenario described in issue #1498, I think we would like to also apply this to d15-7 when possible.

dellis1972 pushed a commit that referenced this pull request Apr 5, 2018
* [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
@jonpryor jonpryor deleted the jonp-unstable-tfn branch July 27, 2018 21:05
@github-actions github-actions bot locked and limited conversation to collaborators Feb 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to build against preview Android API levels
4 participants