So recently, I bought Mini Metro. It has official Linux support on Steam, so it should work fine, right? Well, starting up the game, I was greeted by a black screen. Time to figure out what’s wrong!
Digging around a bit, I found the game’s log file at ~/.config/unity3d/Dinosaur Polo Club/Mini Metro/Player.log
. In the logs, you could see an exception like this being repeated:
DllNotFoundException: minimetrox
at (wrapper managed-to-native) NativeExtensions.getDisplayCount()
at Bootstrap.SelectResolution () [0x001bd] in <b5705b2105bc44d5a8bd0d768be49884>:0
at Bootstrap.Update () [0x00020] in <b5705b2105bc44d5a8bd0d768be49884>:0
and also:
Unable to preload the following plugins:
libminimetrox.so
So… maybe the game just can’t find libminimetrox.so
? But looking in the game files, there is libminimetrox.so
in Mini Metro_Data/Plugins
.
Next idea, maybe the game can’t load libminimetrox.so
for some other reason? Using ldd libminimetrox.so
you could see that it uses /usr/lib64/ld-linux-x86-64.so.2
as the linker:
$ ldd libminimetrox.so
linux-vdso.so.1 (0x00007fff029cc000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f3362118000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f33627a1000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f3361f31000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f3362807000)
I found out that you can actually invoke the linker directly from command line, so let’s try that out:
$ /usr/lib64/ld-linux-x86-64.so.2 ./libminimetrox.so
./libminimetrox.so: symbol lookup error: ./libminimetrox.so: undefined symbol: __gxx_personality_v0
I guess it means that libminimetrox.so
is linked to a symbol named __gxx_personality_v0
, but the symbol is not found in any of the linked libraries. Searching for __gxx_personality_v0
on the internet, I found that it should actually be implemented by libstdc++.so
.
We can use patchelf to add a new dependency to an existing ELF file:
patchelf --add-needed libstdc++.so.6 libminimetrox.so
We can verify our change with ldd
:
$ ldd libminimetrox.so
linux-vdso.so.1 (0x00007ffe20ddb000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f51e8600000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f51e8f93000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f51e89e0000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f51e8419000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f51e90c1000)
See the new line for libstdc++.so.6
?
Anyway, trying to open the game now, it booted up fine. Yay!