Mac and Linux SDL2 binary snapshots
Edward Rudd
2020-05-02 03f8528315fa46c95991a34f3325d7b33ae5538c
source/docs/README-android.md
@@ -1,16 +1,27 @@
Android
================================================================================
Requirements:
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
Android SDK (version 12 or later)
http://developer.android.com/sdk/index.html
The rest of this README covers the Android gradle style build process.
Android NDK r7 or later
http://developer.android.com/tools/sdk/ndk/index.html
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.
Minimum API level supported by SDL: 10 (Android 2.3.3)
Joystick support is available for API level >=12 devices.
================================================================================
 Requirements
================================================================================
Android SDK (version 26 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: 16 (Android 4.1)
================================================================================
 How the port works
@@ -24,14 +35,11 @@
- This eventually produces a standard Android .apk package
The Android Java code implements an "Activity" and can be found in:
android-project/src/org/libsdl/app/SDLActivity.java
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
Your project must include some glue code that starts your main() routine:
src/main/android/SDL_android_main.c
================================================================================
@@ -67,71 +75,49 @@
    
1. Copy the android-project directory wherever you want to keep your projects
   and rename it to the name of your project.
2. Move or symlink this SDL directory into the "<project>/jni" directory
3. Edit "<project>/jni/src/Android.mk" to include your source files
4. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
2. Move or symlink this SDL directory into the "<project>/app/jni" directory
3. Edit "<project>/app/jni/src/Android.mk" to include your source files
If you want to use the Eclipse IDE, skip to the Eclipse section below.
4a. If you want to use Android Studio, simply open your <project> directory and start building.
5. Create "<project>/local.properties" and use that to point to the Android SDK directory, by writing a line with the following form:
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
       sdk.dir=PATH_TO_ANDROID_SDK
6. Run 'ant debug' in android/project. This compiles the .java and eventually
   creates a .apk with the native code embedded
7. 'ant debug install' will push the apk to the device or emulator (if connected)
If you already have a project that uses CMake, the instructions change somewhat:
1. Do points 1 and 2 from the instruction above.
2. Edit "<project>/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.
3. Edit "<project>/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.
4. 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/
        AndroidManifest.xml   - package manifest. Among others, it contains the class name
                   of the main Activity and the package name of the application.
        build.properties   - empty
        build.xml      - build description file, used by ant. The actual application name
                   is specified here.
        default.properties   - holds the target ABI for the application, android-10 and up
        project.properties   - holds the target ABI for the application, android-10 and up
        local.properties   - holds the SDK path, you should change this to the path to your SDK
    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/Android.mk      - Android makefile that can call recursively the Android.mk files
                   in all subdirectories
        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
        res/         - directory holding resources for your application
        res/drawable-*      - directories holding icons for different phone hardware. Could be
                   one dir called "drawable".
        res/layout/main.xml   - Usually contains a file main.xml, which declares the screen layout.
                   We don't need it because we use the SDL video output.
        res/values/strings.xml   - strings used in your application, including the application name
                   shown on the phone.
        src/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.
================================================================================
 Build an app with static linking of libSDL
================================================================================
This build uses the Android NDK module system.
Instructions:
1. Copy the android-project directory wherever you want to keep your projects
   and rename it to the name of your project.
2. Rename "<project>/jni/src/Android_static.mk" to "<project>/jni/src/Android.mk"
   (overwrite the existing one)
3. Edit "<project>/jni/src/Android.mk" to include your source files
4. create and export an environment variable named NDK_MODULE_PATH that points
   to the parent directory of this SDL directory. e.g.:
       export NDK_MODULE_PATH="$PWD"/..
5. Edit "<project>/src/org/libsdl/app/SDLActivity.java" and remove the call to
   System.loadLibrary("SDL2").
6. Run 'ndk-build' (a script provided by the NDK). This compiles the 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.
================================================================================
@@ -164,25 +150,23 @@
Then replace "SDLActivity" in AndroidManifest.xml with the name of your
class, .e.g. "MyGame"
================================================================================
 Customizing your application icon
================================================================================
Conceptually changing your icon is just replacing the "ic_launcher.png" files in
the drawable directories under the res directory. There are four directories for
different screen sizes. These can be replaced with one dir called "drawable",
containing an icon file "ic_launcher.png" with dimensions 48x48 or 72x72.
the drawable directories under the res directory. There are several directories
for different screen sizes.
You may need to change the name of your icon in AndroidManifest.xml to match
this icon filename.
================================================================================
 Loading assets
================================================================================
Any files you put in the "assets" directory of your android-project directory
will get bundled into the application package and you can load them using the
standard functions in SDL_rwops.h.
Any files you put in the "app/src/main/assets" directory of your project
directory will get bundled into the application package and you can load
them using the standard functions in SDL_rwops.h.
There are also a few Android specific functions that allow you to get other
useful paths for saving and loading data:
@@ -204,11 +188,12 @@
    
http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/
================================================================================
 Pause / Resume behaviour
================================================================================
If SDL is compiled with SDL_ANDROID_BLOCK_ON_PAUSE defined (the default),
If SDL_HINT_ANDROID_BLOCK_ON_PAUSE hint is set (the default),
the event loop will block itself when the app is paused (ie, when the user
returns to the main Android dashboard). Blocking is better in terms of battery
use, and it allows your app to spring back to life instantaneously after resume
@@ -224,12 +209,13 @@
manually or quit the app (which is actually the kind of behaviour you'll see
under iOS, if the OS can not restore your GL context it will just kill your app)
================================================================================
 Threads and the Java VM
================================================================================
For a quick tour on how Linux native threads interoperate with the Java VM, take
a look here: http://developer.android.com/guide/practices/jni.html
a look here: https://developer.android.com/guide/practices/jni.html
If you want to use threads in your SDL app, it's strongly recommended that you
do so by creating them using SDL functions. This way, the required attach/detach
@@ -239,6 +225,7 @@
your thread automatically anyway (when you make an SDL call), but it'll never
detach it.
================================================================================
 Using STL
================================================================================
@@ -246,34 +233,10 @@
You can use STL in your project by creating an Application.mk file in the jni
folder and adding the following line:
    APP_STL := stlport_static
    APP_STL := c++_shared
For more information check out CPLUSPLUS-SUPPORT.html in the NDK documentation.
================================================================================
 Additional documentation
================================================================================
The documentation in the NDK docs directory is very helpful in understanding the
build process and how to work with native code on the Android platform.
The best place to start is with docs/OVERVIEW.TXT
================================================================================
 Using Eclipse
================================================================================
First make sure that you've installed Eclipse and the Android extensions as described here:
   http://developer.android.com/tools/sdk/eclipse-adt.html
Once you've copied the SDL android project and customized it, you can create an Eclipse project from it:
 * File -> New -> Other
 * Select the Android -> Android Project wizard and click Next
 * Enter the name you'd like your project to have
 * Select "Create project from existing source" and browse for your project directory
 * Make sure the Build Target is set to Android 3.1 (API 12)
 * Click Finish
For more information go here:
   https://developer.android.com/ndk/guides/cpp-support
================================================================================
@@ -281,19 +244,17 @@
================================================================================
There are some good tips and tricks for getting the most out of the
emulator here: http://developer.android.com/tools/devices/emulator.html
emulator here: https://developer.android.com/tools/devices/emulator.html
Especially useful is the info on setting up OpenGL ES 2.0 emulation.
Notice that this software emulator is incredibly slow and needs a lot of disk space.
Using a real device works better.
================================================================================
 Troubleshooting
================================================================================
You can create and run an emulator from the Eclipse IDE:
 * Window -> Android SDK and AVD Manager
You can see if adb can see any devices with the following command:
@@ -331,7 +292,10 @@
    ndk-build V=1
If your application crashes in native code, you can use addr2line to convert the
If your application crashes in native code, you can use ndk-stack to get a symbolic stack trace:
   https://developer.android.com/ndk/guides/ndk-stack
If you want to go through the process manually, you can use addr2line to convert the
addresses in the stack trace to lines in your code.
For example, if your crash looks like this:
@@ -419,36 +383,30 @@
    adb shell setprop wrap.org.libsdl.app ""
================================================================================
 Graphics debugging
================================================================================
If you are developing on a compatible Tegra-based tablet, NVidia provides
Tegra Graphics Debugger at their website.  Because SDL2 dynamically loads EGL
Tegra Graphics Debugger at their website. Because SDL2 dynamically loads EGL
and GLES libraries, you must follow their instructions for installing the
interposer library on a rooted device.  The non-rooted instructions are not
interposer library on a rooted device. The non-rooted instructions are not
compatible with applications that use SDL2 for video.
The Tegra Graphics Debugger is available from NVidia here:
https://developer.nvidia.com/tegra-graphics-debugger
================================================================================
 Why is API level 10 the minimum required?
 Why is API level 16 the minimum required?
================================================================================
API level 10 is the minimum required level at runtime (that is, on the device)
because SDL requires some functionality for running not
available on older devices. Since the incorporation of joystick support into SDL,
the minimum SDK required to *build* SDL is version 12. Devices running API levels
10-11 are still supported, only with the joystick functionality disabled.
The latest NDK toolchain doesn't support targeting earlier than API level 16.
As of this writing, according to https://developer.android.com/about/dashboards/index.html
about 99% of the Android devices accessing Google Play support API level 16 or
higher (January 2018).
Support for native OpenGL ES and ES2 applications was introduced in the NDK for
API level 4 and 8. EGL was made a stable API in the NDK for API level 9, which
has since then been obsoleted, with the recommendation to developers to bump the
required API level to 10.
As of this writing, according to http://developer.android.com/about/dashboards/index.html
about 90% of the Android devices accessing Google Play support API level 10 or
higher (March 2013).
================================================================================
 A note regarding the use of the "dirty rectangles" rendering technique
@@ -468,6 +426,25 @@
Reference: http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html
================================================================================
 Ending your application
================================================================================
Two legitimate ways:
- return from your main() function. Java side will automatically terminate the
Activity by calling Activity.finish().
- Android OS can decide to terminate your application by calling onDestroy()
(see Activity life cycle). Your application will receive a SDL_QUIT event you
can handle to save things and quit.
Don't call exit() as it stops the activity badly.
NB: "Back button" can be handled as a SDL_KEYDOWN/UP events, with Keycode
SDLK_AC_BACK, for any purpose.
================================================================================
 Known issues
================================================================================