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

[.NET 6] Deploy fails on x86_64 API 31 emulator #6353

Closed
jonathanpeppers opened this issue Sep 30, 2021 · 2 comments · Fixed by #6398
Closed

[.NET 6] Deploy fails on x86_64 API 31 emulator #6353

jonathanpeppers opened this issue Sep 30, 2021 · 2 comments · Fixed by #6398
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Milestone

Comments

@jonathanpeppers
Copy link
Member

Steps to Reproduce

  1. Setup x86_64 API 31 emulator
  2. dotnet new android
  3. dotnet build -t:Install

Fails with:

C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\31.0.101-preview.9.16\tools\Xamarin.Android.Common.Debugging.targets(611,5): error ADB0020: Mono.AndroidTools.IncompatibleCpuAbiExceptiopn: The package does not support the CPU architecture of this device.
   at Mono.AndroidTools.Internal.AdbOutputParsing.CheckInstallSuccess(String output, String packageName) in /Users/builder/azdo/_work/1/s/xamarin-android/external/monodroid/tools/msbuild/external/androidtools/Mono.AndroidTools/Internal/AdbOutputParsing.cs:line 349
   at Mono.AndroidTools.AndroidDevice.<>c__DisplayClass104_0.<InstallPackage>b__0(Task`1 t) in /Users/builder/azdo/_work/1/s/xamarin-android/external/monodroid/tools/msbuild/external/androidtools/Mono.AndroidTools/AndroidDevice.cs:line 804
   at System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__271_0(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) in /Users/builder/azdo/_work/1/s/xamarin-android/external/monodroid/tools/msbuild/external/androidtools/Xamarin.AndroidTools/Devices/AndroidDeviceExtensions.cs:line 206
   at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) in /Users/builder/azdo/_work/1/s/xamarin-android/external/monodroid/tools/msbuild/external/androidtools/Xamarin.AndroidTools/Devices/AndroidDeviceExtensions.cs:line 223
   at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) in /Users/builder/azdo/_work/1/s/xamarin-android/external/monodroid/tools/msbuild/Tasks/FastDeploy.cs:line 339
   at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) in /Users/builder/azdo/_work/1/s/xamarin-android/external/monodroid/tools/msbuild/Tasks/FastDeploy.cs:line 356
   at Xamarin.Android.Tasks.FastDeploy.RunTaskAsync() in /Users/builder/azdo/_work/1/s/xamarin-android/external/monodroid/tools/msbuild/Tasks/FastDeploy.cs:line 213 [C:\src\foo\foo.csproj]

Same thing works with:

dotnet build -t:Install -c Release -p:AndroidPackageFormat=apk

It also works fine in legacy Xamarin.Android

Version Information

Latest .NET 6 rc 2 bits.

@jonathanpeppers jonathanpeppers added Area: App+Library Build Issues when building Library projects or Application projects. needs-triage Issues that need to be assigned. labels Sep 30, 2021
@jonathanpeppers jonathanpeppers added this to the .NET 6 milestone Sep 30, 2021
@jonathanpeppers jonathanpeppers removed the needs-triage Issues that need to be assigned. label Sep 30, 2021
@jonathanpeppers
Copy link
Member Author

So the issue seems to be the API 31 emulator dropped x86?

> adb shell getprop | grep cpu
[ro.product.cpu.abi]: [x86_64]
[ro.product.cpu.abilist]: [x86_64,arm64-v8a]
[ro.product.cpu.abilist32]: []
[ro.product.cpu.abilist64]: [x86_64,arm64-v8a]
[ro.system.product.cpu.abilist]: [x86_64,arm64-v8a]
[ro.system.product.cpu.abilist32]: []
[ro.system.product.cpu.abilist64]: [x86_64,arm64-v8a]
[ro.vendor.product.cpu.abilist]: [x86_64,arm64-v8a]
[ro.vendor.product.cpu.abilist32]: []
[ro.vendor.product.cpu.abilist64]: [x86_64,arm64-v8a]

But the API 30 emulator shows:

> adb shell getprop | grep cpu
[ro.product.cpu.abi]: [x86_64]
[ro.product.cpu.abilist]: [x86_64,x86,arm64-v8a,armeabi-v7a,armeabi]
[ro.product.cpu.abilist32]: [x86,armeabi-v7a,armeabi]
[ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

So even classic Xamarin.Android projects fail on my API 31 emulator if I use <AndroidSupportedAbis>x86</AndroidSupportedAbis>.

@akoeplinger
Copy link
Member

Yeah this is mentioned in https://developer.android.com/about/versions/12/get?hl=en-US#on_emulator

Note that 32-bit Android emulator system images are not supported in Android 12.

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 18, 2021
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1413756
Fixes: dotnet#6353

The API 31 emulator no longer has 32-bit images and the x86_64 image
has dropped support for 32-bit architectures:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,arm64-v8a]
    [ro.product.cpu.abilist32]: []
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

Compared to an API 30 x86_64 emulator:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,x86,arm64-v8a,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist32]: [x86,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

The problem is our default RIDs are:

    <RuntimeIdentifiers Condition=" '$(RuntimeIdentifier)' == '' And '$(RuntimeIdentifiers)' == '' ">android-arm64;android-x86</RuntimeIdentifiers>

And so you hit this error when trying to deploy a `dotnet new android`
app on an API 31 x86_64 emulator:

    error ADB0020: Mono.AndroidTools.IncompatibleCpuAbiExceptiopn: The package does not support the CPU architecture of this device.

To workaround this, you can add `android-x64` to your list of
`$(RuntimeIdentifiers)`.

To solve this issue, we can default `$(RuntimeIdentifiers)` to all 4
architectures. We have code that will select a single architecture for
Debug builds using "Fast Deployment". It seems better to have a
default here that will always work, and the only drawback would be the
additional architectures for Release builds.
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 18, 2021
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1413756
Fixes: dotnet#6353

The API 31 emulator no longer has 32-bit images and the x86_64 image
has dropped support for 32-bit architectures:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,arm64-v8a]
    [ro.product.cpu.abilist32]: []
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

Compared to an API 30 x86_64 emulator:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,x86,arm64-v8a,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist32]: [x86,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

The problem is our default RIDs are:

    <RuntimeIdentifiers Condition=" '$(RuntimeIdentifier)' == '' And '$(RuntimeIdentifiers)' == '' ">android-arm64;android-x86</RuntimeIdentifiers>

And so you hit this error when trying to deploy a `dotnet new android`
app on an API 31 x86_64 emulator:

    error ADB0020: Mono.AndroidTools.IncompatibleCpuAbiExceptiopn: The package does not support the CPU architecture of this device.

To workaround this, you can add `android-x64` to your list of
`$(RuntimeIdentifiers)`.

To solve this issue, we can default `$(RuntimeIdentifiers)` to all 4
architectures. We have code that will select a single architecture for
Debug builds using "Fast Deployment". It seems better to have a
default here that will always work, and the only drawback would be the
additional architectures for Release builds.

After this change, I discovered an issue introduced in 33a6d1e:

    ILLink error IL1012: IL Linker has encountered an unexpected error. Please report the issue at https://github.com/mono/linker/issues [C:\a\_work\1\s\bin\TestRelease\temp\BuildProguard Enabled Project(1)Trued8r8\UnnamedProject.csproj]
    ...
    Unhandled exception. System.IO.IOException: The process cannot access the file 'C:\a\_work\1\s\bin\TestRelease\temp\BuildProguard Enabled Project(1)Trued8r8\obj\Release\proguard\proguard_project_references.cfg' because it is being used by another process.

When we build each RID in parallel, each inner build was attempting to
write to the same file. I changed the path for this file to be:

    $(IntermediateOutputPath)%(_RIDs.Identity)\proguard\proguard_project_references.cfg

And then set `$(_ProguardProjectConfiguration)` appropriately after
the inner builds complete. This also needs to actually be a file path,
I don't see how the value was working before:

    <_ProguardProjectConfiguration Condition=" '$(AndroidLinkTool)' != '' ">;_ProguardProjectConfiguration=$(IntermediateOutputPath)proguard\proguard_project_references.cfg</_ProguardProjectConfiguration>
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 19, 2021
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1413756
Fixes: dotnet#6353

The API 31 emulator no longer has 32-bit images and the x86_64 image
has dropped support for 32-bit architectures:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,arm64-v8a]
    [ro.product.cpu.abilist32]: []
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

Compared to an API 30 x86_64 emulator:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,x86,arm64-v8a,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist32]: [x86,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

The problem is our default RIDs are:

    <RuntimeIdentifiers Condition=" '$(RuntimeIdentifier)' == '' And '$(RuntimeIdentifiers)' == '' ">android-arm64;android-x86</RuntimeIdentifiers>

And so you hit this error when trying to deploy a `dotnet new android`
app on an API 31 x86_64 emulator:

    error ADB0020: Mono.AndroidTools.IncompatibleCpuAbiExceptiopn: The package does not support the CPU architecture of this device.

To workaround this, you can add `android-x64` to your list of
`$(RuntimeIdentifiers)`.

To solve this issue, we can default `$(RuntimeIdentifiers)` to all 4
architectures. We have code that will select a single architecture for
Debug builds using "Fast Deployment". It seems better to have a
default here that will always work, and the only drawback would be the
additional architectures for Release builds.

After this change, I discovered an issue introduced in 33a6d1e:

    ILLink error IL1012: IL Linker has encountered an unexpected error. Please report the issue at https://github.com/mono/linker/issues [C:\a\_work\1\s\bin\TestRelease\temp\BuildProguard Enabled Project(1)Trued8r8\UnnamedProject.csproj]
    ...
    Unhandled exception. System.IO.IOException: The process cannot access the file 'C:\a\_work\1\s\bin\TestRelease\temp\BuildProguard Enabled Project(1)Trued8r8\obj\Release\proguard\proguard_project_references.cfg' because it is being used by another process.

When we build each RID in parallel, each inner build was attempting to
write to the same file. I changed the path for this file to be:

    $(IntermediateOutputPath)%(_RIDs.Identity)\proguard\proguard_project_references.cfg

And then set `$(_ProguardProjectConfiguration)` appropriately after
the inner builds complete. This also needs to actually be a file path,
I don't see how the value was working before:

    <_ProguardProjectConfiguration Condition=" '$(AndroidLinkTool)' != '' ">;_ProguardProjectConfiguration=$(IntermediateOutputPath)proguard\proguard_project_references.cfg</_ProguardProjectConfiguration>

Then another related issue:

    (_TouchAndroidLinkFlag target) ->
    Microsoft.Android.Sdk.ILLink.targets(114,5): error MSB3371: The file "obj\Release\net6.0-android\link.flag" cannot be created. The process cannot access the file 'C:\a\_work\2\s\bin\TestRelease\temp\DotNetBuildandroid-armandroid-arm64android-x86android-x64TrueTrue\obj\Release\net6.0-android\link.flag' because it is being used by another process.

I setup `$(_AndroidLinkFlag)` the same as
`$(_ProguardProjectConfiguration)` to solve this issue.
jonathanpeppers added a commit that referenced this issue Oct 19, 2021
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1413756
Fixes: #6353

The API 31 emulator no longer has 32-bit images and the x86_64 image
has dropped support for 32-bit architectures:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,arm64-v8a]
    [ro.product.cpu.abilist32]: []
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

Compared to an API 30 x86_64 emulator:

    > adb shell getprop | grep cpu
    [ro.product.cpu.abi]: [x86_64]
    [ro.product.cpu.abilist]: [x86_64,x86,arm64-v8a,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist32]: [x86,armeabi-v7a,armeabi]
    [ro.product.cpu.abilist64]: [x86_64,arm64-v8a]

The problem is our default RIDs are:

    <RuntimeIdentifiers Condition=" '$(RuntimeIdentifier)' == '' And '$(RuntimeIdentifiers)' == '' ">android-arm64;android-x86</RuntimeIdentifiers>

And so you hit this error when trying to deploy a `dotnet new android`
app on an API 31 x86_64 emulator:

    error ADB0020: Mono.AndroidTools.IncompatibleCpuAbiExceptiopn: The package does not support the CPU architecture of this device.

To workaround this, you can add `android-x64` to your list of
`$(RuntimeIdentifiers)`.

To solve this issue, we can default `$(RuntimeIdentifiers)` to all 4
architectures. We have code that will select a single architecture for
Debug builds using "Fast Deployment". It seems better to have a
default here that will always work, and the only drawback would be the
additional architectures for Release builds.

After this change, I discovered an issue introduced in 33a6d1e:

    ILLink error IL1012: IL Linker has encountered an unexpected error. Please report the issue at https://github.com/mono/linker/issues [C:\a\_work\1\s\bin\TestRelease\temp\BuildProguard Enabled Project(1)Trued8r8\UnnamedProject.csproj]
    ...
    Unhandled exception. System.IO.IOException: The process cannot access the file 'C:\a\_work\1\s\bin\TestRelease\temp\BuildProguard Enabled Project(1)Trued8r8\obj\Release\proguard\proguard_project_references.cfg' because it is being used by another process.

When we build each RID in parallel, each inner build was attempting to
write to the same file. I changed the path for this file to be:

    $(IntermediateOutputPath)%(_RIDs.Identity)\proguard\proguard_project_references.cfg

And then set `$(_ProguardProjectConfiguration)` appropriately after
the inner builds complete. This also needs to actually be a file path,
I don't see how the value was working before:

    <_ProguardProjectConfiguration Condition=" '$(AndroidLinkTool)' != '' ">;_ProguardProjectConfiguration=$(IntermediateOutputPath)proguard\proguard_project_references.cfg</_ProguardProjectConfiguration>

Then another related issue:

    (_TouchAndroidLinkFlag target) ->
    Microsoft.Android.Sdk.ILLink.targets(114,5): error MSB3371: The file "obj\Release\net6.0-android\link.flag" cannot be created. The process cannot access the file 'C:\a\_work\2\s\bin\TestRelease\temp\DotNetBuildandroid-armandroid-arm64android-x86android-x64TrueTrue\obj\Release\net6.0-android\link.flag' because it is being used by another process.

I setup `$(_AndroidLinkFlag)` the same as
`$(_ProguardProjectConfiguration)` to solve this issue.
jonpryor pushed a commit that referenced this issue Oct 22, 2021
Context: #6353

Changes: xamarin/monodroid@07a99d7...9b3a37a

  * xamarin/monodroid@9b3a37af1: [tools/msbuild] <GetPrimaryCpuAbi/> should not select 32-bit ABIs (#1228)

Update `MonoAndroidExportTest.MonoAndroidExportReferencedAppStarts()`
under .NET 6 to add `x86_64`, e.g.
`$(AndroidSupportedAbis)`=`armeabi-v7a;x86;x86_64`.  This is needed
because the API-31 emulator only supports x86_64, not x86.
jonathanpeppers added a commit that referenced this issue Oct 22, 2021
Context: #6353

Changes: xamarin/monodroid@07a99d7...9b3a37a

  * xamarin/monodroid@9b3a37af1: [tools/msbuild] <GetPrimaryCpuAbi/> should not select 32-bit ABIs (#1228)

Update `MonoAndroidExportTest.MonoAndroidExportReferencedAppStarts()`
under .NET 6 to add `x86_64`, e.g.
`$(AndroidSupportedAbis)`=`armeabi-v7a;x86;x86_64`.  This is needed
because the API-31 emulator only supports x86_64, not x86.
@ghost ghost locked as resolved and limited conversation to collaborators Jun 2, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants