Search code examples
javac#androidxamarin.androidsdl

How to implement the SDL2 library into Xamarin.Android?


What I need to do:

  • Compile the SDL2 source into an .so file for x86 and ARM64 architecture
  • Reference this file in Xamarin.Android
  • Call the SDL2 methods in my C# code.

Things I've learned so far:

  • SDL2 requires a Java Activity or JNI bindings to invoke the native code.
  • I cannot proceed without somehow integrating SDL2 libs and a JNI to the Xamarin.Android project.
  • I am incapable of solving this problem and my brain has fried in the process.

Things I've tried:

  • Outdated GitHub projects:

https://github.com/0x0ade/SDL2Droid-CS

https://github.com/fallahn/sdl2vs

  • This blog post that lets me create C++ code but not using Xamarin

https://trederia.blogspot.com/2017/03/building-sdl2-for-android-with-visual.html

  • Running SDL2 through Android Studio which works but doesn't help me as I need to invoke my C# code.

I don't have extensive Xamarin knowledge so I'm not sure how to do this, I can really use another pair of eyes right now. The SDL2Droid-CS GitHub project should theoretically work but I can't find a way to compile the SDL2 used in that project for the x86 emulator included in C#.

I tried compiling my code using armeabiv7 libsdl2.so and then running it directly on my phone. Unfortunately Visual Studio was unable to debug this thus making it difficult for me to implement my code.

Next I tried to debug the previously compiled app (using SDL2Droid-CS) through Android Studio and it gave me this error:

06-19 00:39:55.362 13143-13143/? I/zygote64: Late-enabling -Xcheck:jni
06-19 00:39:55.474 13143-13143/SDL2Droid_CS.SDL2Droid_CS W/ActivityThread: Application SDL2Droid_CS.SDL2Droid_CS can be debugged on port 8100...
06-19 00:39:55.514 13143-13143/? W/monodroid: Creating public update directory: `/data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__`
    Using override path: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__
    Using override path: /storage/emulated/0/Android/data/SDL2Droid_CS.SDL2Droid_CS/files/.__override__
    Trying to load sgen from: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/libmonosgen-2.0.so
    Trying to load sgen from: /storage/emulated/0/Android/data/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/libmonosgen-2.0.so
    Trying to load sgen from: /storage/emulated/0/../legacy/Android/data/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/libmonosgen-2.0.so
    Trying to load sgen from: /data/app/SDL2Droid_CS.SDL2Droid_CS-wmPu9Ce48QdJhvYc6bPRiA==/lib/arm64/libmonosgen-2.0.so
    Trying to load sgen from: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/links/libmonosgen-2.0.so
06-19 00:39:55.515 13143-13143/? W/monodroid: Trying to load sgen from: /system/lib/libmonosgen-2.0.so
06-19 00:39:55.515 13143-13143/? A/monodroid: cannot find libmonosgen-2.0.so in override_dir: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__, app_libdir: /data/app/SDL2Droid_CS.SDL2Droid_CS-wmPu9Ce48QdJhvYc6bPRiA==/lib/arm64 nor in previously printed locations.
    Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported.
    Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration).

The Min SDK was 19 so the error it gives is weird.

I'm assuming that SDL2 was not implemented properly which is leading to all these problems. The GitHub code has some holes and the person who uploaded it hasn't been active.

Resources:


Solution

  • TL;DR: Working files are here: https://github.com/MananAdhvaryu/Android-SDL2-Libraries

    So I figured out the crash, it was cause due to the shared runtime that is implemented for debugging by Visual Studio. It was fixed by disabling Shared Runtime in the project settings.

    Project Settings -> Android Options -> Untick "Use Shared Runtime"

    1. As to why the GitHub Code didn't work:

    It was due to broken .jar file in the "bindings" project. I was able to fix it by compiling the .jar file myself from the SDL2 source code. The .java file you need to compile are here, or you can get it from the source code.

    Once you have the working .jar simply remove the existing .jar from the Jars folder and replace it with the new one.

    If you can't generate the .jar file you can use the one in the GitHub project linked above

    2. To create the .so files:

    After that the necessary .so file for the processor architecture needs to be compiled. It is done using the Android NDK and a make script. The make script from the SDL2Droid GitHub works fine so I simply changed a few parameters to increase the android minSdkVersion to 19 and got the .so files for all the architectures (x86, x86_64, ARM, ARM64)

    #!/bin/bash
    NATIVEDIR=$(dirname "$0")
    ndk-build -j 4 NDK_PROJECT_PATH="$NATIVEDIR/../SDL2Droid-CS" NDK_APPLICATION_MK="$NATIVEDIR/Application.mk"
    

    This is the bash code to generate the .so files. If you are using Command prompt simply change the "$NATIVEDIR" to the absolute path of your project.

    If you cannot generate these native libraries then you can use the one's from the above linked GitHub repository.

    they require minimum sdk android-19 and are available for all supported architectures.

    To use them simply place the libs folder in your Xamarin.Android project directory.