tadfisher / android-nixpkgs

Nix-packaged Android SDK
MIT License
294 stars 44 forks source link

Problem with the environment when using Gradle-managed devices on MacOS x86 #93

Open Dolfik1 opened 7 months ago

Dolfik1 commented 7 months ago

Encountered an issue with gradle managed devices on MacOS x86. A sample project demonstrating the problem can be found here.

Reproduction Steps:

To replicate the issue, execute the following command: nix develop -c ./test.sh

This command executes successfully on a Mac M2 but fails on a Mac Pro x86, resulting in the following Gradle error:

FAILURE: Build failed with an exception.

[org.gradle.internal.buildevents.BuildExceptionReporter]

* What went wrong:

Execution failed for task ':app:pixel4api33Setup'.

> A failure occurred while executing com.android.build.gradle.internal.tasks.ManagedDeviceSetupTask$ManagedDeviceSetupRunnable

   > java.lang.IllegalStateException: Gradle was not able to complete device setup for: dev33_google_atd_x86_64_Pixel_4

     The emulator failed to open the managed device to generate the snapshot.

     This is because the emulator closed unexpectedly, try updating the emulator and

     ensure a device can be run from Android Studio.

The full log file is attached to this issue. Here is some key highlights:

[INFO] [com.android.build.gradle.internal.AvdManager] qemu: could not load PC BIOS 'bios-256k.bin'
[INFO] [com.android.build.gradle.internal.AvdManager] libc++abi: terminating due to uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
[INFO] [com.android.build.gradle.internal.AvdManager] [48197:116410850:20240413,105527.346458:WARNING crash_report_exception_handler.cc:235] UniversalExceptionRaise: (os/kern) failure (5)

Within the logs, a command used to run qemu:

/nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/qemu/darwin-x86_64/qemu-system-x86_64-headless -dns-server 192.168.0.1 -no-audio -serial stdio -device goldfish_pstore,addr=0xff018000,size=0x10000,file=/tmp/.android/.android/avd/gradle-managed/dev33_google_atd_x86_64_Pixel_4.avd/data/misc/pstore/pstore.bin -cpu android64-xts -enable-hvf -smp cores=2 -m 2048 -lcd-density 440 -nodefaults -kernel /nix/store/vg5yy6lsrli9dk8bba839nrzq0bllkwy-android-sdk-env/share/android-sdk/system-images/android-33/google_atd/x86_64//kernel-ranchu -initrd /tmp/.android/.android/avd/gradle-managed/dev33_google_atd_x86_64_Pixel_4.avd/initrd -drive if=none,index=0,id=system,if=none,file=/nix/store/vg5yy6lsrli9dk8bba839nrzq0bllkwy-android-sdk-env/share/android-sdk/system-images/android-33/google_atd/x86_64//system.img,read-only -device virtio-blk-pci,drive=system,modern-pio-notify -drive if=none,index=1,id=cache,if=none,file=/tmp/.android/.android/avd/gradle-managed/dev33_google_atd_x86_64_Pixel_4.avd/cache.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576 -device virtio-blk-pci,drive=cache,modern-pio-notify -drive if=none,index=2,id=userdata,if=none,file=/tmp/.android/.android/avd/gradle-managed/dev33_google_atd_x86_64_Pixel_4.avd/userdata-qemu.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576 -device virtio-blk-pci,drive=userdata,modern-pio-notify -drive if=none,index=3,id=encrypt,if=none,file=/tmp/.android/.android/avd/gradle-managed/dev33_google_atd_x86_64_Pixel_4.avd/encryptionkey.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576 -device virtio-blk-pci,drive=encrypt,modern-pio-notify -drive if=none,index=4,id=vendor,if=none,file=/nix/store/vg5yy6lsrli9dk8bba839nrzq0bllkwy-android-sdk-env/share/android-sdk/system-images/android-33/google_atd/x86_64//vendor.img,read-only -device virtio-blk-pci,drive=vendor,modern-pio-notify -netdev user,id=mynet -device virtio-net-pci,netdev=mynet -chardev null,id=forhvc0 -chardev null,id=forhvc1 -device virtio-serial-pci,ioeventfd=off -device virtconsole,chardev=forhvc0 -device virtconsole,chardev=forhvc1 -chardev netsim,id=bluetooth -device virtserialport,chardev=bluetooth,name=bluetooth -device virtio-serial,ioeventfd=off -chardev socket,port=53196,host=::1,nowait,nodelay,reconnect=10,ipv6,id=modem -device virtserialport,chardev=modem,name=modem -device virtio-rng-pci -show-cursor -device virtio_input_multi_touch_pci_1 -device virtio_input_multi_touch_pci_2 -device virtio_input_multi_touch_pci_3 -device virtio_input_multi_touch_pci_4 -device virtio_input_multi_touch_pci_5 -device virtio_input_multi_touch_pci_6 -device virtio_input_multi_touch_pci_7 -device virtio_input_multi_touch_pci_8 -device virtio_input_multi_touch_pci_9 -device virtio_input_multi_touch_pci_10 -device virtio_input_multi_touch_pci_11 -netdev user,id=virtio-wifi,dhcpstart=10.0.2.16 -device virtio-wifi-pci,netdev=virtio-wifi -device virtio-vsock-pci,guest-cid=77 -L /nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/lib/pc-bios -soundhw virtio-snd-pci -vga none -append 'no_timer_check 8250.nr_uarts=1 clocksource=pit console=ttyS0,38400 cma=294M@0-4G loop.max_part=7 ramoops.mem_address=0xff018000 ramoops.mem_size=0x10000 memmap=0x10000$0xff018000 printk.devkmsg=on bootconfig' -android-hw /tmp/.android/.android/avd/gradle-managed/dev33_google_atd_x86_64_Pixel_4.avd/hardware-qemu.ini

Troubleshooting Attempts

While unsure about the appropriateness of manually invoking this command (because Gradle can add some stuff to env), it was attempted. However, the following error was encountered:

dyld[48655]: Library not loaded: @rpath/libemugl_common.dylib
  Referenced from: <4C4C44A4-5555-3144-A129-31904C046B48> /nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/qemu/darwin-x86_64/qemu-system-x86_64-headless
  Reason: tried: '/nix/store/lib64/qt/lib/libemugl_common.dylib' (no such file), '/nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/qemu/darwin-x86_64/libemugl_common.dylib' (no such file), '/nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/qemu/darwin-x86_64/lib64/libemugl_common.dylib' (no such file), '/nix/store/lib64/qt/lib/libemugl_common.dylib' (no such file), '/nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/qemu/darwin-x86_64/libemugl_common.dylib' (no such file), '/nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/qemu/darwin-x86_64/lib64/libemugl_common.dylib' (no such file), '/usr/lib/libemugl_common.dylib' (no such file, not in dyld cache)

Upon investigation, libemugl_common.dylib was found at the following location: /nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/lib

As a workaround, the directory containing libemugl_common.dylib was added to the DYLD_LIBRARY_PATH environment variable using the following script: export DYLD_LIBRARY_PATH="/nix/store/a9h0g1pmp2hsyqkv23v0q3s40dhrr5rs-emulator-35.1.2/lib:$DYLD_LIBRARY_PATH"

This action resolved the previous error, but resulted in a new message:

INFO    | Duplicate loglines will be removed, if you wish to see each individual line launch with the -log-nofilter flag.
unknown option: -serial
please use -help for a list of valid options
Dolfik1 commented 7 months ago

I found out that the crash is related to the headless mode. It can be reproduced as follows:

nix develop -c avdmanager create avd -n test -k 'system-images;android-33;google_atd;x86_64'

Then, if you try to launch the created emulator in headless mode:

nix develop -c emulator -avd test -no-window -verbose

You'll encounter the following error:

qemu: could not load PC BIOS 'bios-256k.bin'
libc++abi: terminating due to uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
[59201:119788773:20240415,113627.963893:WARNING crash_report_exception_handler.cc:235] UniversalExceptionRaise: (os/kern) failure (5)

However, if you omit the -no-window parameter:

nix develop -c emulator -avd test -verbose

everything will start successfully without errors.

Dolfik1 commented 7 months ago

After a detailed examination of the issue, I found that the problem was at the strip stage. I resolved this issue as follows (by dontStrip flag):

system = if system == "aarch64-darwin" then "x86_64-darwin" else system;
overlays = [
(self: super: {
  androidsdk = android.sdk.${system} (sdkPkgs: with sdkPkgs; [
    build-tools-33-0-0
    cmdline-tools-latest
    (emulator.overrideAttrs (_: { dontStrip = isDarwin64; }))

Ideally, this requires further investigation into the reasons for such behavior, but this solution can be used as a hotfix.