README-android.md
Android
Matt Styles wrote a tutorial on building SDL for Android with Visual Studio: http://trederia.blogspot.de/2017/03/building-sdl2-for-android-with-visual.html
The rest of this README covers the Android gradle style build process.
If you are using the older ant build process, it is no longer officially supported, but you can use the "android-project-ant" directory as a template.
Requirements
Android SDK (version 34 or later) https://developer.android.com/sdk/index.html
Android NDK r15c or later https://developer.android.com/tools/sdk/ndk/index.html
Minimum API level supported by SDL: 19 (Android 4.4)
How the port works
- Android applications are Java-based, optionally with parts written in C
- As SDL apps are C-based, we use a small Java shim that uses JNI to talk to the SDL library
- This means that your application C code must be placed inside an Android Java project, along with some C support code that communicates with Java
- This eventually produces a standard Android .apk package
The Android Java code implements an "Activity" and can be found in: android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
The Java code loads your game code, the SDL shared library, and dispatches to native functions implemented in the SDL library: src/core/android/SDL_android.c
Building an app
For simple projects you can use the script located at build-scripts/androidbuild.sh
There's two ways of using it:
androidbuild.sh com.yourcompany.yourapp < sources.list
androidbuild.sh com.yourcompany.yourapp source1.c source2.c ...sourceN.c
sources.list should be a text file with a source file name in each line Filenames should be specified relative to the current directory, for example if you are in the build-scripts directory and want to create the testgles.c test, you'll run:
./androidbuild.sh org.libsdl.testgles ../test/testgles.c
One limitation of this script is that all sources provided will be aggregated into a single directory, thus all your source files should have a unique name.
Once the project is complete the script will tell you where the debug APK is located. If you want to create a signed release APK, you can use the project created by this utility to generate it.
Finally, a word of caution: re running androidbuild.sh wipes any changes you may have done in the build directory for the app!
For more complex projects, follow these instructions:
-
Get the source code for SDL and copy the 'android-project' directory located at SDL/android-project to a suitable location. Also make sure to rename it to your project name (In these examples: YOURPROJECT).
(The 'android-project' directory can basically be seen as a sort of starting point for the android-port of your project. It contains the glue code between the Android Java 'frontend' and the SDL code 'backend'. It also contains some standard behaviour, like how events should be handled, which you will be able to change.)
-
Move or symlink the SDL directory into the "YOURPROJECT/app/jni" directory
(This is needed as the source of SDL has to be compiled by the Android compiler)
- Edit "YOURPROJECT/app/jni/src/Android.mk" to include your source files.
(They should be separated by spaces after the "LOCAL_SRC_FILES := " declaration)
4a. If you want to use Android Studio, simply open your 'YOURPROJECT' directory and start building.
4b. If you want to build manually, run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device
If you already have a project that uses CMake, the instructions change somewhat:
- Do points 1 and 2 from the instruction above.
- Edit "YOURPROJECT/app/build.gradle" to comment out or remove sections containing ndk-build and uncomment the cmake sections. Add arguments to the CMake invocation as needed.
- Edit "YOURPROJECT/app/jni/CMakeLists.txt" to include your project (it defaults to adding the "src" subdirectory). Note that you'll have SDL2, SDL2main and SDL2-static as targets in your project, so you should have "target_link_libraries(yourgame SDL2 SDL2main)" in your CMakeLists.txt file. Also be aware that you should use add_library() instead of add_executable() for the target containing your "main" function.
If you wish to use Android Studio, you can skip the last step.
- Run './gradlew installDebug' or './gradlew installRelease' in the project directory. It will build and install your .apk on any connected Android device
Here's an explanation of the files in the Android project, so you can customize them:
android-project/app
build.gradle - build info including the application version and SDK
src/main/AndroidManifest.xml - package manifest. Among others, it contains the class name of the main Activity and the package name of the application.
jni/ - directory holding native code
jni/Application.mk - Application JNI settings, including target platform and STL library
jni/Android.mk - Android makefile that can call recursively the Android.mk files in all subdirectories
jni/CMakeLists.txt - Top-level CMake project that adds SDL as a subproject
jni/SDL/ - (symlink to) directory holding the SDL library files
jni/SDL/Android.mk - Android makefile for creating the SDL shared library
jni/src/ - directory holding your C/C++ source
jni/src/Android.mk - Android makefile that you should customize to include your source code and any library references
jni/src/CMakeLists.txt - CMake file that you may customize to include your source code and any library references
src/main/assets/ - directory holding asset files for your application
src/main/res/ - directory holding resources for your application
src/main/res/mipmap-* - directories holding icons for different phone hardware
src/main/res/values/strings.xml - strings used in your application, including the application name
src/main/java/org/libsdl/app/SDLActivity.java - the Java class handling the initialization and binding to SDL. Be very careful changing this, as the SDL library relies on this implementation. You should instead subclass this for your application.
Customizing your application name
To customize your application name, edit AndroidManifest.xml and replace "org.libsdl.app" with an identifier for your product package.
Then create a Java class extending SDLActivity and place it in a directory under src matching your package, e.g.
src/com/gamemaker/game/MyGame.java
Here's an example of a minimal class file:
--- MyGame.java --------------------------
package com.gamemaker.game;
import org.libsdl.app.SDLActivity;
/**
* A sample wrapper class that just calls SDLActivity
*/
public class MyGame extends SDLActivity { }
------------------------------------------