How-to install anbox from sources on Mint 20 without snap

Kallys
  1 week ago
  0

I. Introduction

The main purpose of this tutorial is to share my experience of building and running Anbox project from sources in Ulaya.

Anbox is a container-based approach to boot a full Android system on a regular GNU/Linux system.
Anbox is only officially deployed on the snap app store, and since snap store is disabled by default on linux Mint 20, this tutorial will try to help you to compile and run Anbox directly from sources. There is also a quite old version (2019-11-15) in apt.

Personnally, I am absolutely not an expert in compilation and I failed several times in past to build anbox, mainly due to a lack of documentation and some obscure black magic. I hope this tutorial will give you keys to make it working but I can’t guarantee you that this will work on your system.

    1. Tested environment

  • Source: master#170f1e0
  • Mint: 20 (Ulaya)
  • Kernel: 5.4.0-48-generic
  • C/CXX Compiler : GNU 9.3.0

I recommend you to configure your system to get as close as possible to this environment.

    2. Useful resources

II. Building anbox

    1. Prerequisites

          a) Kernel modules

As explained in official documentation, you need to load two kernel modules : ashmem_linux and binder_linux.

$ sudo modprobe ashmem_linux
$ sudo modprobe binder_linux
$ ls -1 /dev/{ashmem,binder}
/dev/ashmem
/dev/binder

If you experience issue with binder_linux, try this instructions. (Thanks to RogerWilco)

          b) Dependencies

$ sudo apt update
$ sudo apt install build-essential cmake cmake-data debhelper dbus google-mock \
    libboost-dev libboost-filesystem-dev libboost-log-dev libboost-iostreams-dev \
    libboost-program-options-dev libboost-system-dev libboost-test-dev \
    libboost-thread-dev libcap-dev libexpat1-dev libsystemd-dev libegl1-mesa-dev \
    libgles2-mesa-dev libglm-dev libgtest-dev liblxc1 \
    libproperties-cpp-dev libprotobuf-dev libsdl2-dev libsdl2-image-dev lxc-dev \
    pkg-config protobuf-compiler libgmock-dev git

    2. Compilation

1. Go where you want to build (assuming here "/usr/local/src/" directory)

$ cd /usr/local/src

2. Get sources

$ sudo git clone https://github.com/anbox/anbox.git --recurse-submodules

3. Adjust permissions and create a build directory

$ sudo chown -R $USER:$USER anbox/
$ mkdir anbox/build/
$ cd anbox/build/

4. Prepare for compilation

$ cmake ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- No build type selected, default to RelWithDebInfo
-- Treat warnings as errors
-- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake (found version "1.71.0") found components: filesystem log serialization system thread program_options 
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") 
-- Found Threads: TRUE  
-- Found EGL: /usr/lib/x86_64-linux-gnu/libEGL.so  
-- Found GLESv2: /usr/lib/x86_64-linux-gnu/libGLESv2.so  
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread (found version "3.6.1") 
-- Checking for module 'sdl2'
--   Found sdl2, version 2.0.10
-- Checking for module 'SDL2_image'
--   Found SDL2_image, version 2.0.5
-- Checking for module 'dbus-1'
--   Found dbus-1, version 1.12.16
-- Checking for module 'lxc'
--   Found lxc, version 4.0.2
-- Checking for module 'properties-cpp'
--   Found properties-cpp, version 0.0.1
-- Checking for module 'libsystemd'
--   Found libsystemd, version 245
-- Checking for module 'libcap'
--   Found libcap, version 2.32
-- LXC version: 4.0.2
-- Checking for module 'gtest'
--   Found gtest, version 1.10.0
-- Checking for module 'gtest_main'
--   Found gtest_main, version 1.10.0
-- Checking for module 'gmock'
--   Found gmock, version 1.10.0
-- Checking for module 'gmock_main'
--   Found gmock_main, version 1.10.0
-- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake (found version "1.71.0") found components: iostreams system 
-- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake (found version "1.71.0") found components: filesystem system unit_test_framework 
-- Found libdw: /usr/lib/x86_64-linux-gnu/libdw.so  
-- Found libbfd: /usr/lib/x86_64-linux-gnu/libbfd.so  
-- Found libdwarf: /usr/lib/x86_64-linux-gnu/libdwarf.so  
-- Found Backward: /usr/local/src/anbox/external/backward-cpp  
-- Looking for dlfcn.h
-- Looking for dlfcn.h - found
-- Looking for getauxval
-- Looking for getauxval - found
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/local/src/anbox/build

At this step, triple check everything is alright. If something went wrong here, you must fix it before continuing.

5. Cross fingers and compile!

$ make
[...]
Scanning dependencies of target buffer_queue_tests
[100%] Building CXX object tests/anbox/graphics/CMakeFiles/buffer_queue_tests.dir/buffer_queue_tests.cpp.o
[100%] Linking CXX executable buffer_queue_tests
[100%] Built target buffer_queue_tests
Scanning dependencies of target lxc_container_tests
[100%] Building CXX object tests/anbox/container/CMakeFiles/lxc_container_tests.dir/lxc_container_tests.cpp.o
[100%] Linking CXX executable lxc_container_tests
[100%] Built target lxc_container_tests

You surely will see some warnings, but you should not see any errors.

6. Install anbox For some reasons, “sudo make install” failed with insufficient permissions, so I went with “sudo -i”.

$ sudo -i
$ cd /usr/local/src/anbox/build/
$ make install
[  3%] Built target sdbus-cpp
[ 10%] Built target process-cpp
[ 12%] Built target emugen
[ 13%] Built target OpenglCodecCommon
[ 14%] Built target renderControl_dec
[ 17%] Built target GLESv2_dec
[ 19%] Built target GLESv1_dec
[ 25%] Built target emugl_common
[ 27%] Built target OpenGLESDispatch
[ 28%] Built target xdg
[ 29%] Built target xdg_test
[ 29%] Built target backward
[ 30%] Built target backward_object
[ 31%] Built target utils
[ 32%] Built target cpu_features
[ 34%] Built target list_cpu_features
[ 35%] Built target unix_based_hardware_detection
[ 38%] Built target anbox-protobuf
[ 88%] Built target anbox-core
[ 89%] Built target anbox
[ 90%] Built target intent_tests
[ 91%] Built target restricted_manager_tests
[ 92%] Built target at_parser_tests
[ 93%] Built target scope_ptr_tests
[ 93%] Built target binary_writer_tests
[ 94%] Built target type_traits_tests
[ 94%] Built target small_vector_tests
[ 95%] Built target message_channel_tests
[ 96%] Built target render_control_tests
[ 97%] Built target layer_composer_tests
[ 98%] Built target buffered_io_stream_tests
[100%] Built target buffer_queue_tests
[100%] Built target lxc_container_tests
Install the project...
-- Install configuration: "RelWithDebInfo"
-- Installing: /usr/local/share/anbox/ui/loading-screen.png
-- Installing: /usr/local/include/backward.hpp
-- Installing: /usr/local/lib/backward/BackwardConfig.cmake
-- Installing: /usr/local/lib/libcpu_features.a
-- Installing: /usr/local/include/cpu_features/cpu_features_macros.h
-- Installing: /usr/local/include/cpu_features/cpu_features_cache_info.h
-- Installing: /usr/local/include/cpu_features/cpuinfo_x86.h
-- Installing: /usr/local/bin/list_cpu_features
-- Installing: /usr/local/lib/cmake/CpuFeatures/CpuFeaturesTargets.cmake
-- Installing: /usr/local/lib/cmake/CpuFeatures/CpuFeaturesTargets-relwithdebinfo.cmake
-- Installing: /usr/local/lib/cmake/CpuFeatures/CpuFeaturesConfig.cmake
-- Installing: /usr/local/lib/cmake/CpuFeatures/CpuFeaturesConfigVersion.cmake
-- Installing: /usr/local/bin/anbox
-- Set runtime path of "/usr/local/bin/anbox" to ""
$ exit

7. Test

$ anbox
NAME:
    anbox - anbox

USAGE:
    anbox [command options] [arguments...]

COMMANDS:
    check-features                 Check that the host system supports all necessary features                                          
    wait-ready                     Wait until the Android system has successfully booted                                               
    system-info                    Print various information about the system we're running on                                         
    launch                         Launch an Activity by sending an intent                                                             
    session-manager                Run the the anbox session manager                                                                   
    version                        Print the version of the daemon                                                                     
    help                           Print a short help message

8. If you reach this step, you have successfully compiled Anbox! Congrats!

9. Additional checks : especially check that binder and ashmem are recognised.

$ anbox check-features
Your computer does meet all requirements to run Anbox
$ anbox system-info
version: local-170f1e0
cpu:
  arch:  x86
  brand: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  features: 
    - aes
    - sse4_1
    - sse4_2
    - avx
    - avx2
os:
  name: Linux Mint
  version: 20 (Ulyana)
  snap-based: false
kernel:
  version: Linux version 5.4.0-48-generic (buildd@lcy01-amd64-010) (gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)) #52-Ubuntu SMP Thu Sep 10 10:58:49 UTC 2020
  binder: true
  ashmem: true
graphics:
[...]

III. Running Anbox

    1. Introduction

As doc says, Anbox does not contain any android image and uses :

  • a container manager
  • a session manager

What doc does not say is what to do with those info when you know nothing about the project and virtualization.

Hopefully, sources of debian package of anbox took me to the right way:

  1. Session manager depends on Container manager to run
  2. Container manager depends on anbox-bridge.sh script and the famous android image to run
  3. anbox-bridge.sh appears to be on a scripts/ directory inside anbox sources ("/usr/local/src/anbox/scripts/")
  4. android image is… to build or find on the Internet

    2. Get an android image

This operation must be done once, but you need an android image to run container manager. You can download one from here, altought images are not really recent.

Alternatively you can build your own android image as explained here, but I have not tested it and this is not covered by this tutorial (maybe another one?).

1. Download image

$ wget https://build.anbox.io/android-images/2018/07/19/android_amd64.img

2. Check integrity

$ wget https://build.anbox.io/android-images/2018/07/19/android_amd64.img.sha256sum
$ sha256sum -c android_amd64.img.sha256sum

3. Create a directory for storing this image, let’s say "/var/lib/anbox"

$ sudo mkdir /var/lib/anbox

4. Move the android image to this directory

$ sudo mv android_amd64.img /var/lib/anbox/android.img

    3. Let's run it!

This process must be followed each time you want to run Anbox manually:

1. Assert kernel modules are loaded (required after each reboot)

$ ls -1 /dev/{ashmem,binder}
/dev/ashmem
/dev/binder

2. Start bridge script

$ sudo /usr/local/src/anbox/scripts/anbox-bridge.sh start

3. Manually start container manager

$ sudo anbox container-manager --daemon --privileged --data-path=/var/lib/anbox

This command will launch container as a daemon, do not expect any output and let it running (use CTRL+C if you want to stop it later)

4. Optionaly, if you are looking for logs, open another terminal and watch for logs

$ sudo tail -f /var/lib/anbox/logs/container.log

5. Open another terminal and finally, launch anbox app manager (will automatically start session manager)!

$ anbox launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity

IV. Going further

    1. Using a service for container

To simplify startup routine, we can use a systemd service:

1. Create a anbox-container-manager.service file with following content (adapt paths if needed)

$ sudo vim /lib/systemd/system/anbox-container-manager.service
[Unit]
Description=Anbox Container Manager
After=network.target
Wants=network.target
ConditionPathExists=/var/lib/anbox/android.img

[Service]
ExecStartPre=/sbin/modprobe ashmem_linux
ExecStartPre=/sbin/modprobe binder_linux
ExecStartPre=/usr/local/src/anbox/scripts/anbox-bridge.sh start
ExecStart=/usr/local/bin/anbox container-manager --daemon --privileged --data-path=/var/lib/anbox
ExecStopPost=/usr/local/src/anbox/scripts/anbox-bridge.sh stop

[Install]
WantedBy=multi-user.target

2. Symlink it

$ sudo ln -s /lib/systemd/system/anbox-container-manager.service /etc/systemd/system/

3. Reload daemons

$ sudo systemctl daemon-reload

4. Start it!

$ sudo systemctl start anbox-container-manager.service

5. Check status

$ sudo systemctl status anbox-container-manager.service

5. Optionally : start it with system

$ sudo systemctl enable anbox-container-manager.service

    V. Conclusion

I hope this tutorial has helped you making Anbox working on your system.
How to use anbox is beyond the scope of this tutorial and I think you can find other ressources on the Internet.
Do not hesitate to comment to tell me if this worked for you too, correct my mistakes or to provide additional content.

Comments
Kallys 1 week ago

Hi RogerWilco, I'm glad you succeed into making Anbox running on your system! :)
I've updated the tutorial to mention your issue.
Could you detail your impression about Anbox not successfully firing up?
Personnally I did not tried to enable the service container manager on my system and prefer start it manually, but perhaps I've missed something?


RogerWilco 1 week ago

Hi Kallys,

you hit the nail on the head, installing (all) "anbox-modules" did the trick for the missing linux_binder module. So obvious, yet still I managed to miss that.
- https://superuser.com/questions/1590707/ls-cannot-access-dev-binder-no-such-file-or-directory-in-anbox/1590708#1590708

I got it to run now but I'll be rolling back tomorrow evening to do it again to figure out whether the impression that I currently have that Anbox wouldn't entirely / successfully fire up after the steps from "IV". until I continued on and completed the steps in "V.".

After that I shall remove my superfluous comments here and leave a (hopefully) shorter summary with my findings.

I might include things such as
- the installation of "android-tools-adb"
- and maybe, after adding the Anbox network bridge interface according to https://docs.anbox.io/userguide/advanced/network_configuration.html, confirm that e.g. the side-loaded F-Droid store will work
- solution to "Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=133]." when attempting to install two browsers (Lightning & Vivaldi). I gave it a very brief look already and I believe there might be an easy fix.


RogerWilco 1 week ago

Okay, will take a look at the links provided and will give it another run on LM20. I might test it on LM19.3 as well, we'll see. Will post about results/findings.


Kallys 1 week ago

You may take a look at those links for your binder issue:
https://superuser.com/questions/1590707/ls-cannot-access-dev-binder-no-such-file-or-directory-in-anbox/1590708#1590708
https://github.com/anbox/anbox-modules/issues/20#issuecomment-570204411
https://github.com/anbox/anbox/issues/1262
https://github.com/anbox/anbox/issues/1387


Kallys 1 week ago

I'm not sure for binder, but I can tell you that your running error ("The name org.anbox was not provided by any .service files" + window hangs and closes) is due to the fact that container manager is not running. I've experienced it many times.
Try to launch container and take a look at logs as explained is III.3.4 step, it may help!


RogerWilco 2 weeks ago

Again, thank you very much for having put this together.

I tested it on:
Kernel: 5.4.0-47-generic x86_64 bits: 64 compiler: gcc v: 9.3.0
Desktop: Cinnamon 4.6.7 dm: LightDM 1.30.0 Distro: Linux Mint 20 Ulyana
base: Ubuntu 20.04 focal

Brief summary:
Good description of all steps. Unfortunately the "linux_binder" kernel module step wasn't successful.
How did you get that to work?

I read up some at
https://askubuntu.com/questions/1226098/running-bionic-beaver-and-not-able-to-get-sudo-modprobe-binder-linux-to-load
https://askubuntu.com/questions/1187253/anbox-on-19-10-claims-kernel-modules-are-missing/1206133#1206133
but am not sure what to make of it.

My output for:
$ lsmod | grep -e ashmem_linux -e binder_linux
ashmem_linux 20480 0
binder_linux 180224 0

-------------------------------------------

2. Compilation
5. Cross fingers and compile!

The warnings you mentioned "to be expected" I assume were these:

Running cpp protocol buffer compiler on anbox/protobuf/anbox_container.proto
[libprotobuf WARNING google/protobuf/compiler/parser.cc:562] No syntax specified for the proto file: anbox_container.proto. Please use 'syntax = "proto2";' or 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2 syntax.)
[ 35%] Running cpp protocol buffer compiler on anbox/protobuf/anbox_bridge.proto
[libprotobuf WARNING google/protobuf/compiler/parser.cc:562] No syntax specified for the proto file: anbox_bridge.proto. Please use 'syntax = "proto2";' or 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2 syntax.)
[ 36%] Running cpp protocol buffer compiler on anbox/protobuf/anbox_rpc.proto
[libprotobuf WARNING google/protobuf/compiler/parser.cc:562] No syntax specified for the proto file: anbox_rpc.proto. Please use 'syntax = "proto2";' or 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2 syntax.)

-------------------------------------------

2. Compilation
9. Additional checks : especially check that binder and ashmem are recognised.

Anbox System Info Check;
$ anbox system-info
[...]
kernel:
version: Linux version 5.4.0-47-generic (buildd@lcy01-amd64-014) (gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)) #51-Ubuntu SMP Fri Sep 4 19:50:52 UTC 2020
binder: false
ashmem: true
[...]

-------------------------------------------

3. Let's run it!
5. Open another terminal and finally, launch anbox app manager (will automatically start session manager)!

My output from running it:
$ anbox launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity
[ 2020-10-10 01:03:06] [daemon.cpp:61@Run] [org.freedesktop.DBus.Error.ServiceUnknown] The name org.anbox was not provided by any .service files

>> App manager screen shows but nothing happens and closes after a while.
>> My guess: the linux_binder module issue prohibits it from running properly.


Kallys 2 weeks ago

Thanks RogerWilco, let me know if it works!


RogerWilco 2 weeks ago

Thank you very much for investing the time and making it available here! I'll give this a 2nd try on the weekend.