Run Steam in Android phone
I'm trying to run steam using box86 on Android using Termux. For this I managed to port docker for Android. Then, I started a 32 bit Ubuntu container with X11 forwarded, so I could run GUI programs inside it with VNC. From within this container I compiled box86 and downloaded the steam.deb for Linux from the official site. Next, I extracted the files from the .deb, patched the bin_steam.sh so I could run it as the root user and executed it. This caused the steam files to be installed in ~/.local/share/Steam. Finally I exported some variables with
export BOX86_LD_LIBRARY_PATH=~/.local/share/Steam/ubuntu12_32/steam-runtime/usr/lib/i386-linux-gnu:~/.local/share/Steam/ubuntu12_32
and ran the steam binary with box86:
cd ~/.local/share/Steam/ubuntu12_32
box86 ./steam
The first time I executed this, everything worked fine and it was able to download and install the updates.

But, when I executed it again it started to fail with
Failed to load steamui.so - dlerror(): Cannot dlopen("steamui.so"/0x639b1b30, 2)

I googled this issue a lot but couldn't find a solution. I thought it could be related to OpenGL, but I already have libGL.so in my container from libgl-dev package. I've also already installed libappindicator1, libnm0 and libdbusmenu-gtk4 packages.
I've also tried using https://github.com/ptitSeb/gl4es, but the problem persisted. It was successfully able to load it

but I still get the Failed to load steamui.so - dlerror(): Cannot dlopen("steamui.so"/0x639b1b30, 2) error
I gave it more testing and realized gl4es isn't working as expected. After trying to run glxgears I got the following error: undefined symbol: glXMakeCurrent
@ptitSeb Do you know what may be causing this? Also, does gl4es need the kernel to support framebuffer?
You built gl4es for Android or for Linux? to get glXMakeCurrent, you need a Linux build, this symbol doesn't exist on Android build.
Despite using an Android phone, I'm trying to build gl4es for linux inside an Ubuntu container. Running uname inside the container gives me GNU/Linux. I've tried many different flags combinations for the cmake, but I can't manage to get glXMakeCurrent exported. Am I missing something?
You need to build with X11 also, and EGL.
Oh, cool. Now it worked! glxgears runs nicely, but unfortunately I'm still getting the Failed to load steamui.io error when running steam 😢
Use BOX86_LOG=1 to see what is happening on the loading libs side of things
Hmm, running with BOX86_LOG=2 I got this:
Not an i386 ELF (40)
Error: reading elf header of /usr/lib/arm-linux-gnueabihf/libvdpau.so.1
Not an i386 ELF (40)
Error: reading elf header of /lib/i386-linux-gnu/libvdpau.so.1
Not an i386 ELF (40)
Error: reading elf header of /lib/i386-linux-gnu/libvdpau.so.1
Not an i386 ELF (40)
Error: reading elf header of /usr/lib/i386-linux-gnu/libvdpau.so.1
Faillure to create lib => fail
Error loading needed lib: "libvdpau.so.1"
Failure to Add dependant lib => fail
Error loading needed lib: "libavutil.so.55"
Failure to Add dependant lib => fail
Error loading needed lib: "libavcodec.so.57"
Failure to Add dependant lib => fail
Error loading needed lib: "libvideo.so"
Failure to Add dependant lib => fail
Warning: Cannot dlopen("steamui.so"/0x64103a40, 2)
return 0x00000000
Looks like it's trying to load this libvdpau.so.1 as dependence but failing with Not an i386 ELF. I got this lib by apt install libvdpau1.
So, I uninstalled my libvdpau1, downloaded the i386.deb from packages.ubuntu.com and extracted the libvdpau.so.1 from this package into /usr/lib/i386-linux-gnu and now steam can correctly load this lib. Now, I'm fixing other libs dependencies.
Anyway, why was I getting Not an i386 ELF error? Wasn't box86 supposed to translate arm libs to i386?
Sorry if this may sound a stupid question, I really don't understand the inner works of box86
it does, but it's not automatic. All functions ignature has to be declared first (that's what all inside src/wrapped is doing.
Also, you don't need to add dependancy yourself, you can find them in steam-runtime folder. Also, running with steam with STEAMOS=1 and STEAM_RUNTIME=1 env. var. help.
Indeed there are a lot of .so inside steam-runtime subfolders, but some wasn't presented and I had to download manually, like libvdpau1, libva2 and libva-x11-2.
You can simply apt install these packages, but then you'll get the Not an i386 ELF error, so I had to download the i386 deb for them.
Is there a way to make box86 use the native ARM version of these libs?
Yes, there is a way; wrap them. But I'm unsure if it's interresting or easy for now. I may look at them later, to see if it can be a quick win...
Also, I had some progress! Now Steam doesn't fail anymore when opening, but it opens a transparent window:

That's the login window. I can even write my username and passwd, but I can't see anything that's going on.
The errors that box86 reports are:
Assertion Failed: Is64BitOS()
LIBGL: ERROR: EGL Error detected: EGL_BAD_ALLOC
sh: 1: /root/.local/share/Steam/ubuntu12_32/../ubuntu12_64/vulkandriverquery: Exec format error
These errors keep looping. I straced the execution, but not sure if there's anything interesting in the outputed log. Any ideas?
You have an opengl issue. Steam use OpenGL to render, and that EGL error is not good! That means you don't have a correct glXContext. (you can ignore the vulkan error, it's just steam trying to launch a 64bits program).
But I'm unsure if it's interresting or easy for now.
That's OK, downloading the i386 deb and extracting its files isn't a complicated process anyway.
Steam use OpenGL to render, and that EGL error is not good! That means you don't have a correct glXContext
Ooh, 😕 Do you think recompiling gl4es with some magic flag can fix this?
Magic flag for build I don't think so. You can try with LIBGL_FB=3 env. var. first, to see if this (slow) method works...
Unfortunately, it didn't work. The behavior is still the same. But now I get the following errors instead:
LIBGL: Cannot use eglCopyBuffers, disabling it's use: LIBGL: ERROR: EGL Error detected: EGL_BAD_NATIVE_PIXMAP
LIBGL: ERROR: EGL Error detected: EGL_BAD_CONTEXT
Does this method require the kernel to support framebuffer? Because if so, I have to recompile Android kernel first. I don't even have /dev/fb0 file present.
LIBGL_FB alow to switch different method to create the context. default is 0. /dev/fb0 access is 1 and 2. Method 3 is using PBuffer. If even that doesn't work; that means nothing will. There is no GLES available to gl4es I'm afraid.
Oh, that's sad :(
Sorry for the dumb question, but why gl4es and all this OpenGL stuff works fine in ARM running on a Raspberry, but aren't work in ARM running on a mobile phone? Does it have to do with the GPU chip used?
Because the Linux that run under Android is not a full linux. Hardware drivers are missing mainly (or not accessible at least)
Hmm, ok, so it's a software issue, not a hardware. I realized that gl4es compiled for Raspberry and ODROID doesn't have the glXMakeCurrent symbol exported. That means somebody else creates the context. Who exactly? Can't I also use an auxiliar program in Android to create the context correctly?
EDIT: not compiled for Rasp and ODROID. Compiled for Android itself. Which enforces my question, how it is supposed to run without creating a context?
You are in a Linux environement, so you need to build gl4es for linux, not android. With X11 and EGL enabled. On Android, context is already created (in the java part), that why this part (most glX function that handle Context creation) is not there.
You could try some GOG games or SteamCMD to see if the principles hold up with or without Steam.
I don't even have
/dev/fb0file present.
On Android, it's located on /dev/graphics/fb0. Simply do a symlink to /dev/fb0 as workaround.
(It requires root)
@FreddieOliveira install Xephyr and use it as display with llvmpipe instead of gl4es so you have X server and more OpenGL version supported (I think that you are using software renderer anyway). I was able to run some games on Android this way with Linux Deploy. Also I recommend to use taskset -c command to target big cores.
@Heasterian Can you go into deets, as even if the Steam Client isn't cooperating, we could probably get some of those games working on phones.
@moocow1452 Easy way for rooted phones. Install Linux Deploy > choose armhf as architecture and Debian Testing as OS in settings, also enable SSH as it's easy to set up drivers etc. form PC/SSH client on phone itself. Enable GUI and change it to X11, later you need to change Pulse Audio port to one that Xserver XSDL will give you. Now you can install os using Linux Deploy, after installation ends, install Xserver XSDL and launch system. I also recommend to use Termux as SSH or PC for rest, as you can just copy-paste commands this way.
After installation you need: sudo apt install xserver-xephyr libxcb-shm0-dev build-essential cmake wget gcc && sudo apt build-dep mesa. Now you need to compile mesa form source, same with box86, for wine, just use instruction from their sites. Keep in mind that you need i386 version of wine. I think that you will need install one package to add wine repo, but error itself will show you name of it. Before you start any app, start Xephyr with Xephyr :1 command.
As I didn't figure out how to restart systemd-binfmt in chroot, you need to run games with wull command like BOX86_NOSIGSEV=1 DISPLAY=:1 LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=llvmpipe BOX86_LOG=1 box86 /opt/wine-devel/bin/wine wow/Wow.exe. You need to chage wine-develto wine version that you are using. export command can reset for Termux SSH client, so I'm not using it on phone.
For now, DirectX 9 games are corrupting memory when using dynarec for me. If you will have same issues, try to compile box86 without dynarec. Also, as Dynarec is using less threads on phone, you can use taskset -c 4,5,6,7 before box86 in your command to use big cores. OpenGL games are fine.
Sometimes Xephyr like to hang so you need to restart it.
Probably compiling whole https://android.googlesource.com/platform/external/virglrenderer/ repo, including vtest using bionic C library and running virgl_test_server from Android terminal could make GPU acceleration possible, but it needs 100 GB of AOSP source to compile and setting it up won't be easy anyway.
@Heasterian We could, or we can go directly to the good stuff.
https://chromium.googlesource.com/angle/angle/+/master/doc/DevSetup.md
I'm not sure how it would work as I first see this project... Could we use it to render image from chroot using Android app? @moocow1452
I'm not sure how it would work as I first see this project... Could we use it to render image from chroot using Android app? @moocow1452
Android 10+ allows you to roll your own drivers in Developer Mode, and ANGLE is the Google GLES/Vulkan solution that can be built to a chip, loaded in as an APK and can be assigned apps that use those drivers to run as opposed to the system standard. If I am understanding it correctly, community drivers could be developed that focus on Games and Graphics APIs that don't have to support the rest of Android, without even having to root.