程式語言 - Java - Android - Build SDL2



參考資料:
https://github.com/libsdl-org/SDL

編譯環境

$ java -version
    openjdk version "17.0.17" 2025-10-21

$ sdkmanager --version
    12.0

$ gradle --version
    Gradle 8.2

$ sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0"

步驟如下:

$ cd
$ git clone https://github.com/libsdl-org/SDL -b release-2.30.0
$ cd android-project/app/jni
$ ln -s ../../../../SDL SDL
$ cd ../../
$ rm app/jni/Android.mk
$ rm app/jni/Application.mk

app/build.gradle

def buildAsLibrary = project.hasProperty('BUILD_AS_LIBRARY');
def buildAsApplication = !buildAsLibrary

if (buildAsApplication) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

android {
    namespace "org.libsdl.app"
    compileSdkVersion 34
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 34
        versionCode 1
        versionName "1.0"

        externalNativeBuild {
            cmake {
                arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static"
                abiFilters 'arm64-v8a'
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    if (buildAsApplication) {
        applicationVariants.all { variant ->
            tasks["merge${variant.name.capitalize()}Assets"]
                .dependsOn("externalNativeBuild${variant.name.capitalize()}")
        }
    } else {
        libraryVariants.all { variant ->
            tasks["merge${variant.name.capitalize()}Assets"]
                .dependsOn("externalNativeBuild${variant.name.capitalize()}")

            variant.outputs.all { output ->
                output.outputFileName = "org.libsdl.app.aar"
            }
        }
    }

    ndkVersion "27.0.12077973"

    lint {
        abortOnError false
    }

    sourceSets.main {
        jniLibs.srcDir 'libs'
    }

    externalNativeBuild {
        cmake {
            path 'jni/CMakeLists.txt'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
}

app/jni/src/CMakeLists.txt

cmake_minimum_required(VERSION 3.6)

project(MY_APP)

find_library(SDL2 SDL2)

add_library(main SHARED)
target_sources(main PRIVATE main.c)
target_link_libraries(main SDL2)

app/jni/src/main.c

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
  
int main(int argc, char **argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Quit();
    return 0;
}

編譯

$ ./gradlew clean

$ ./gradlew assembleDebug -PBUILD_AS_LIBRARY=true
$ file ./app/build/intermediates/cmake/debug/obj/arm64-v8a/libSDL2.so
    ./app/build/intermediates/cmake/debug/obj/arm64-v8a/libSDL2.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV)

$ ./gradlew assembleDebug -PBUILD_AS_APPLICATION=true
$ file ./app/build/outputs/apk/debug/app-debug.apk
./app/build/outputs/apk/debug/app-debug.apk: Android package (APK)