Running android studio on Guix
by Julien Lepiller — Wed 10 June 2020
One of my motivation in my work towards better Java support in Guix is that one day, I will have a proper environment for building Android applications. In particular, I have create nani, an offline dictonary application for Japanese learners like me. This post is about my current setup and how I am able to run Android studio despite all its weirdness and embedded FHS paths.
The version of Android studio you can download from google is bundled with a lot
of binary packages, so its dependencies are actually fairly small. The following
manifest file (save it as
studio-manifest.scm) contains all you need to run
(use-package-modules base bash compression gcc gl glib linux nss pulseaudio version-control virtualization xml xorg) (packages->manifest (list bash git which dbus (list gcc "lib") ;; for running the android virtual devices (AVD): e2fsprogs qemu-minimal alsa-lib expat libxcomposite libxcursor libxi libxtst mesa nss pulseaudio (list util-linux "lib") libx11 zlib))
Download the android studio from google and decompress it in some directory
(I did it on
/mnt/hdd/android because my main disk doesn't have enough space
for all that).
I also created symlinks in my home directory to prevent it from being filled
with android's junk:
ln -sv /mnt/hdd/android/home/android ~/.android and
ln -sv /mnt/hdd/android/home/AndroidStudio4.0 ~/.AndroidStudio4.0.
Launching in a Container
Android studio is composed of many different programs that would each need to be patchelf'd in order to run properly on Guix. However, this is not really an option for three reasons:
- We would need to keep track of what we patched them with (keeping them as a gc root),
- We would have to do it all again on every update of Android studio,
- Some tools are downloaded by gradle and modifying them will result in gradle reinstating the broken version, preventing your application from being buildable.
Instead, I am going to use Guix containers and expose libraries at the expected FHS paths: no patchelf involved!
Android studio comes with its own Java version, but I found that it was somewhat broken, so I replace it with guix' own version:
guix build icedtea ln -sv /gnu/store/...-icedtea-3.7.0-jdk /var/guix/gcroots rm -rf android-studio/jre ln -sv /var/guix/gcroot/...-icedtea-3.7.0-jdk android-studio/jre
Note that even though the directory is named jre, you need a jdk.
Creating the Environment
First of all, I need to know where in the store the profile is created for my
environment, so I create the environment and check the value of the
variable. I then copy that value to the
$PROFILE variable, outside the environment:
export PROFILE=$(guix environment -C -N -m studio-manifest.scm \ -- bash -c 'echo $GUIX_ENVIRONMENT')
Note that you will need to run that command every time you want to enter the environment, as a new version of guix will create a new profile. You may also consider using time-machine
Entering the Container
Now it is time to build and enter the container itself:
guix environment -C -N --share=$XAUTHORITY --share=/tmp/.X11-unix \ --share=/dev/shm --expose=/etc/machine-id --expose=~ \ --expose=$PROFILE/lib=/lib --expose=$PROFILE/lib=/lib64 --share=/dev/kvm \ -m studio-manifest.scm -- env XAUTHORITY=$XAUTHORITY DISPLAY=$DISPLAY bash
Let's decompose this command a bit:
-C -Ncreates a container with network access.
--share=$XAUTHORITY --share=/tmp/.X11-unix --share=/dev/shm: this is required to run any graphical application.
--expose=/etc/machine-id: this is used by dbus which many graphical applications require, including studio.
--expose=~: studio needs to access at least some parts of your home directory. Here, we give it read-only access to your home. This works because this is enough to read symlinks that point to a location that is writable inside the container. If you didn't symlink
~/.androidand co., you should share them instead.
--expose=$PROFILE/lib=/lib --expose=$PROFILE/lib=/lib64: this will allow studio to find its libraries in the location it expects (
--share=/dev/kvm: this is required for running an AVD. Note that your user must also be in the kvm group to be able to run an AVD. Omit if you don't want to run any.
env XAUTHORITY=$XAUTHORITY DISPLAY=$DISPLAY: this ensure that required environment variables for Xorg are set in the container.
It is now time to run Android studio inside the container. Open it with this:
or if you want to be able to run an AVD from studio, open it like this:
Note that the
Android directory can be installed elsewhere, so you will have
to adapt that command for your situation. If you installed it in the same
directory as I, that would instead be:
LD_LIBRARY_PATH=/lib:/lib/nss:/mnt/hdd/android/home/Android/Sdk/emulator/lib64/qt/lib:/mnt/hdd/android/home/Android/Sdk/emulator/lib64 \ ./android-studio/bin/studio.sh
This is terrible, but it is the only way I found to run it somewhat properly. Running it in an environment also isolates it from the system and prevents it from doing any damage to my home directory or my personal data. I hope this is useful to you!