I have a MonoGame application built using the Linux Game template in Visual Studio. It runs on Windows using either .NET or Mono, but it fails on Linux.
The error is a DllNotFoundException
concerning SDL.dll but the SDL.dll is always in the binary's directory. The file is not a CLR assembly, so it's not in the References. Instead, I have it copied during build from MonoGame's Assemblies/Linux directory (and all related CLR assemblies are copied from that folder as well). The error appears regardless of whether I've built the project under Windows in Visual Studio or Xamarin Studio or under Linux in MonoDevelop. There are no build errors.
Here's the relevant stack trace:
System.DllNotFoundException: SDL.dll
at (wrapper managed-to-native) Tao.Sdl.Sdl:__SDL_InitSubSystem (int)
at Tao.Sdl.Sdl.SDL_InitSubSystem (Int32 flags) [0x00000] in <filename unknown>:0
at Microsoft.Xna.Framework.OpenTKGamePlatform..ctor (Microsoft.Xna.Framework.Game game) [0x00000] in <filename unknown>:0
at Microsoft.Xna.Framework.GamePlatform.Create (Microsoft.Xna.Framework.Game game) [0x00000] in <filename unknown>:0
at Microsoft.Xna.Framework.Game..ctor () [0x00000] in <filename unknown>:0
(I haven't included code because this doesn't have to do with my code - it happens even if I build a fresh project from the template. I've already been googling for hours about this and have tried all combinations of what's proposed in various forums, but I haven't found a solution yet.)
What can I do to fix this?
Addendum: With MONO_LOG_LEVEL=debug
, I can see the runtime's attempts to locate the DLL and they all say that the file was not found. When I try to "help" the runtime by renaming the file to libSDL.dll
(or anything else it's looking for) it says "invalid ELF header" and ignores it. Which is probably to be expected, since it looks like a Win32 binary (not a CLR assembly).
Context:
Indeed, SDL.dll (from Assemblies/Linux) is a Win32 binary. The reason it's included in the "MonoGame for Linux" template is so that the game can run under Windows too. Under Linux, the DLL is not touched. Instead, Mono searches for a native Linux version of the SDL library. For some reason, however, it fails to map.
Solution:
Tao.Sdl.dll.config
. This is because we want to write an application configuration file for the Tao.Sdl.dll
assembly (because the call to SDL happens from inside Tao.Sdl.dll
).Write the following in the new file (applicable for libSDL 1.2 - other versions may require different names):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<dllmap dll="SDL.dll" target="libSDL-1.2.so.0" />
<dllmap dll="SDL_image.dll" target="libSDL_image-1.2.so.0" />
<dllmap dll="SDL_mixer.dll" target="libSDL_mixer-1.2.so.0" />
<dllmap dll="SDL_ttf.dll" target="libSDL_ttf-2.0.so.0" />
<dllmap dll="SDL_net.dll" target="libSDL_net-1.2.so.0" />
<dllmap dll="smpeg.dll" target="libsmpeg-0.4.so.0" />
<dllmap dll="SDL_gfx.dll" target="libSDL_gfx.so.4" />
</configuration>
Clean and build.
Now Mono should have enough information to find libSDL on your system.