see the other post on headless monogame as well.

headless sdl2

we want to be able to automatically enable headless compatibility using SDL2's video driver override feature (see the section on SDL_VIDEODRIVER in the docs for envvar). the dummy driver seems to do what we need. and on the C# side, we prevent calling to any functionality that would fail when using the dummy driver.

problem description

also, if you avoid initializing the graphicsdevicemanager, at least with DesktopGL you can run headless by setting SDL_VIDEODRIVER=dummy. For some reason it doesn't work when I use: Environment.SetEnvironmentVariable("SDL_VIDEODRIVER", "dummy", EnvironmentVariableTarget.Process); at the start of the program.

However, it works when i run from the shell as SDL_VIDEODRIVER=dummy ./program

anyone have any idea why?

links

solution

after doing some further work and messing around with P/Invoke, I finally solved the issue. I started off trying to bind SDL's native functions by using reflection to extract the MonoGame types that handle this (see the SDL2 method binder)

unfortunately, the function i wanted to use to set the environment variable, SDL_putenv, appeared not to be available to bind for some reason. according to objdump however, the symbols were exported:

objdump of SDL2 env

the eventual fix that ended up working was using the abstract native interface to call the system setenv and getenv functions. i initially had quite a bit of trouble getting the P/Invoke bindings to cooperate, but it turns out I had been using them wrong. by looking at Mono.Posix's source, i was able to get the correct signature to P/Invoke.

revisit [day 2020-05-02]

it appears that i am dumb. i was looking to bind SDL_putenv when objdump clearly shows that the two functions exported are SDL_setenv and SDL_getenv. which means that i should in theory be able to bind the function that actually exists, SDL_setenv.

and just like that, we are able to bind those two functions (after updating the SDL_setenv signature)