Skip to content

love-android as a library #290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 100 additions & 26 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: build

on: [push, pull_request]
on:
push:
pull_request:
workflow_dispatch:

jobs:
build-android:
Expand All @@ -18,50 +21,121 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
submodules: false # We'll handle this manually for better control
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why we don't need to clone submodules? For someone who wants to compile from source quickly, they can just do:

$ git clone --recurse-submodules https://github.com/love2d/love-android
$ cd love-android
$ gradlew assemble

Instead of having to manually re-clone the needed repository (megasource and main LOVE)

token: ${{ secrets.GITHUB_TOKEN }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

token is ${{ github.token }} (alias of secrets.GITHUB_TOKEN) by default. This is redundant.

- name: Initialize Submodules (Robust)
run: |
echo "=== Initial Git Status ==="
git status
echo "=== Checking .gitmodules ==="
cat .gitmodules || echo "No .gitmodules found"
echo "=== Checking git config for submodules ==="
git config --list | grep submodule || echo "No submodule config found"
echo "=== Checking .git/modules ==="
ls -la .git/modules/ || echo "No .git/modules found"
echo "=== Force clean submodule state and re-init ==="
git submodule deinit --all --force || true
rm -rf .git/modules/library || true
rm -rf .git/modules/app || true
echo "=== Re-sync and init submodules ==="
git submodule sync --recursive
git submodule update --init --recursive --force
echo "=== Submodule status after clean init ==="
git submodule status --recursive
echo "=== Manual clone fallback if needed ==="
if [ ! -d "library/src/main/cpp/love" ]; then
echo "Love submodule still missing, manual clone..."
mkdir -p library/src/main/cpp
git clone https://github.com/love2d/love.git library/src/main/cpp/love --depth 1
fi
if [ ! -d "library/src/main/cpp/megasource" ]; then
echo "Megasource submodule still missing, manual clone..."
mkdir -p library/src/main/cpp
git clone https://github.com/love2d/megasource.git library/src/main/cpp/megasource --depth 1
fi
echo "=== Final verification ==="
ls -la library/src/main/cpp/
ls -la library/src/main/cpp/love/ | head -5 || echo "love directory empty/missing"
ls -la library/src/main/cpp/megasource/ | head -5 || echo "megasource directory empty/missing"
Comment on lines +26 to +59
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason why we have to clone the submodules manually? This breaks people who just want to compile quickly (see my above review).

- name: Setup Java 17
uses: actions/setup-java@v4
with:
distribution: adopt-hotspot
java-version: 17
distribution: 'temurin' # adopt-hotspot is an alias for temurin
java-version: '17' # This will pick the latest 17.x
# Or be more specific like '17.0.10' if '17.0.15' is problematic
Comment on lines +63 to +65
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single quotes is redundant.

As for the comment, the exact version specifier comment is also bit out of place. Always stick to just the major version. If specific version has issue then it's upstream issue and should be reported.

Suggested change
distribution: 'temurin' # adopt-hotspot is an alias for temurin
java-version: '17' # This will pick the latest 17.x
# Or be more specific like '17.0.10' if '17.0.15' is problematic
distribution: temurin
java-version: 17

cache: gradle
- name: Build Normal Flavor
run: bash ./gradlew assembleNormalRecord${{ matrix.build_type }}
- name: Build Release-specific Binaries

# Build Library AAR variants
- name: Build Library AAR (Normal Record ${{ matrix.build_type }})
run: bash ./gradlew :library:assembleNormalRecord${{ matrix.build_type }}
- name: Build Library AAR Release variants
if: ${{ matrix.build_type == 'Release' }}
run: bash ./gradlew bundleNormalNoRecordRelease bundleEmbedRecordRelease bundleEmbedNoRecordRelease
- name: Artifact (Normal debug APK)
run: bash ./gradlew :library:assembleNormalNoRecordRelease :library:assembleEmbedRecordRelease :library:assembleEmbedNoRecordRelease

# Build Sample App Debug APK (only for Debug builds)
- name: Build Sample App Debug APK
if: ${{ matrix.build_type == 'Debug' }}
run: bash ./gradlew :sample:assembleDebug

# Upload Library AAR artifacts
- name: Artifact (Library AAR Normal Record Debug)
if: ${{ matrix.build_type == 'Debug' }}
uses: actions/upload-artifact@v4
with:
name: love-library-normal-record-debug.aar
path: library/build/outputs/aar/library-normal-record-debug.aar

- name: Artifact (Library AAR Normal Record Release)
if: ${{ matrix.build_type == 'Release' }}
uses: actions/upload-artifact@v4
with:
name: love-android-debug.apk
path: app/build/outputs/apk/normalRecord/debug/app-normal-record-debug.apk
- name: Artifact (Normal unsigned APK)
name: love-library-normal-record-release.aar
path: library/build/outputs/aar/library-normal-record-release.aar

- name: Artifact (Library AAR Normal No Record Release)
if: ${{ matrix.build_type == 'Release' }}
uses: actions/upload-artifact@v4
with:
name: love-android.apk
path: app/build/outputs/apk/normalRecord/release/app-normal-record-release-unsigned.apk
- name: Artifact (Normal AAB w/o recording)
name: love-library-normal-norecord-release.aar
path: library/build/outputs/aar/library-normal-noRecord-release.aar

- name: Artifact (Library AAR Embed Record Release)
if: ${{ matrix.build_type == 'Release' }}
uses: actions/upload-artifact@v4
with:
name: love-android-ps.aab
path: app/build/outputs/bundle/normalNoRecordRelease/app-normal-noRecord-release.aab
- name: Artifact (Embed AAB)
name: love-library-embed-record-release.aar
path: library/build/outputs/aar/library-embed-record-release.aar

- name: Artifact (Library AAR Embed No Record Release)
if: ${{ matrix.build_type == 'Release' }}
uses: actions/upload-artifact@v4
with:
name: love-android-embed-record.aab
path: app/build/outputs/bundle/embedRecordRelease/app-embed-record-release.aab
- name: Artifact (Embed AAB w/o recording)
name: love-library-embed-norecord-release.aar
path: library/build/outputs/aar/library-embed-noRecord-release.aar

# Upload Sample App APK
- name: Artifact (Sample App Debug APK)
if: ${{ matrix.build_type == 'Debug' }}
uses: actions/upload-artifact@v4
with:
name: love-sample-app-debug.apk
path: sample/build/outputs/apk/debug/sample-debug.apk

# Test JitPack build compatibility
- name: Test JitPack Build
if: ${{ matrix.build_type == 'Release' }}
run: bash ./gradlew :library:publishToMavenLocal

# Upload Debug symbols (for both library and sample app)
- name: Artifact (Library Debug symbols)
uses: actions/upload-artifact@v4
with:
name: love-android-embed.aab
path: app/build/outputs/bundle/embedNoRecordRelease/app-embed-noRecord-release.aab
- name: Artifact (Debug symbols)
name: love-library-unstripped-debugsyms-${{ matrix.build_type }}
path: library/build/intermediates/cxx

- name: Artifact (Sample App Debug symbols)
if: ${{ matrix.build_type == 'Debug' }}
uses: actions/upload-artifact@v4
with:
name: love-android-unstripped-debugsyms-${{ matrix.build_type }}
path: app/build/intermediates/cxx
name: love-sample-app-unstripped-debugsyms-debug
path: sample/build/intermediates/cxx
12 changes: 6 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[submodule "app/src/main/cpp/love"]
path = app/src/main/cpp/love
url = https://github.com/love2d/love
[submodule "library/src/main/cpp/love"]
path = library/src/main/cpp/love
url = https://github.com/love2d/love.git
branch = main
[submodule "app/src/main/cpp/megasource"]
path = app/src/main/cpp/megasource
url = https://github.com/love2d/megasource
[submodule "library/src/main/cpp/megasource"]
path = library/src/main/cpp/megasource
url = https://github.com/love2d/megasource.git
branch = main
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
About fork:
---------
This is a fork of the original project, it moves the app into a library and publishes it into an aar for easy app integration.

https://jitpack.io/#eltonkola/love-android/Tag

if there is interest we can clean it and try to merge into the main project

Comment on lines +1 to +8
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this line. Thanks.

Android Port of LÖVE, an awesome 2D game engine for Lua (http://love2d.org)
Copyright (c) 2006-2024 LOVE Development Team

Expand Down
1 change: 0 additions & 1 deletion app/src/main/cpp/love
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove the submodules? If you just want to move them to library, use git mv.

Submodule love deleted from 0f39ee
1 change: 0 additions & 1 deletion app/src/main/cpp/megasource
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove the submodules? If you just want to move them to library, use git mv.

Submodule megasource deleted from 358248
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:8.7.0'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21'
classpath 'org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.0.21'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
92 changes: 58 additions & 34 deletions app/build.gradle → library/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import java.nio.charset.StandardCharsets
import java.nio.charset.StandardCharsets // Keep if getAppName or other parts need it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant comment. Makes the commit noisy.

Suggested change
import java.nio.charset.StandardCharsets // Keep if getAppName or other parts need it
import java.nio.charset.StandardCharsets

plugins {
id 'com.android.application'
id 'com.android.library'
id 'maven-publish' // Keep: essential for maven publishing
}

android {
namespace "org.love2d.android"
ndkVersion '27.1.12297006'

defaultConfig {
applicationId project.properties["app.application_id"]
// Use distinct properties for library versioning if they differ from app versions
// e.g., project.properties["lib.version_code"]
versionCode project.properties["app.version_code"].toInteger()
versionName project.properties["app.version_name"]
minSdk 23
Expand All @@ -19,21 +21,19 @@ android {
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=1"
// https://issuetracker.google.com/issues/274493986
// Transitive shared library that's added through `add_dependencies` is not taken into
// account. This result in liboboe.so and libluajit.so not get included into the final
// APK. "love" target depends on LuaJIT, and OpenAL that depends on oboe::oboe. So,
// add "OpenAL" and "love" target.
targets "love_android", "OpenAL", "love"
}
}

ndk {
//noinspection ChromeOsAbiSupport
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
debugSymbolLevel 'full'
}

// getAppName function and manifestPlaceholders:
// These seem more app-specific. If your library's manifest doesn't use these,
// they could be removed or adjusted for library context.
// For now, keeping them as they were in your file.
def getAppName = {
def nameArray = project.properties["app.name_byte_array"]
def name = project.properties["app.name"]
Expand All @@ -54,55 +54,54 @@ android {
}

manifestPlaceholders = [
NAME:getAppName(),
ORIENTATION:project.properties["app.orientation"],
NAME:getAppName(),
ORIENTATION:project.properties["app.orientation"],
]
}

// retrieveAll3pModules function: Keep as is if used by your sourceSets
def retrieveAll3pModules = { ->
def modules = []

fileTree("src/main/cpp/lua-modules/").visit { FileVisitDetails details ->
if (details.isDirectory()) {
if (file(details.file.path + "/Android.mk").exists() ||
file(details.file.path + "/CMakeLists.mk").exists()) {
def logger = project.getLogger()
logger.lifecycle("3rd-party module: " + details.file.path)

def javainfo = file(details.file.path + "/java.txt")
if (javainfo.exists()) {
def fstream = new FileInputStream(javainfo)
def infile = new BufferedReader(new InputStreamReader(fstream))
def javapath = infile.readLine().replace("\\", "/")
def mpath = null

if (javapath[0] != '/') {
mpath = details.file.path + "/" + javapath
} else {
mpath = details.file.path + javapath
}

modules << mpath

logger.lifecycle("Registered path " + mpath)
infile.close()
}
}
}
}

return modules
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // Usually not for libraries
}
// debug {} // Can add if needed
}

// buildFeatures - prefab was already there, keep it.
// viewBinding was duplicated, keep one.
buildFeatures {
prefab true
viewBinding true // If your library uses ViewBinding.
}

flavorDimensions = ['mode', 'recording']
Expand Down Expand Up @@ -130,7 +129,7 @@ android {
srcDirs += retrieveAll3pModules()
}
}
normal {
normal { // This was for 'normal' flavor, keep if it has specific sources
java {
srcDir 'src/normal/java'
}
Expand All @@ -141,31 +140,57 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}

externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
// '+' notation apparently has been supported long time ago
// https://issuetracker.google.com/issues/110693527#comment22
// We require CMake 3.21 because r23 has important fixes
// that's only fixed if CMake 3.21 is used.
// https://github.com/android/ndk/issues/463
version '3.21.0+'
}
}
packagingOptions {
jniLibs {
excludes += [
'lib/armeabi-v7a/libOpenSLES.so',
'lib/arm64-v8a/libOpenSLES.so',
'lib/x86/libOpenSLES.so',
'lib/x86_64/libOpenSLES.so'
'lib/armeabi-v7a/libOpenSLES.so',
'lib/arm64-v8a/libOpenSLES.so',
'lib/x86/libOpenSLES.so',
'lib/x86_64/libOpenSLES.so'
]
}
}
}

// RECOMMENDED: Use AGP's built-in publishing DSL (for AGP 7.0+)
// This should be placed INSIDE the android {} block.
publishing {
singleVariant("normalRecordRelease") {
// This tells AGP to prepare the 'normalRecordRelease' variant for publishing.
// The maven-publish plugin will then pick this up.

// To include a sources JAR in the publication (highly recommended for libraries):
// withSourcesJar()

// To include a Javadoc JAR (optional):
// withJavadocJar()
}
}

} // End of android {} block


// REMOVE the old 'android.libraryVariants.all { ... }' publishing block.
// It conflicts with the android.publishing DSL and afterEvaluate.

// REMOVE the 'afterEvaluate { ... }' publishing block.
// The debug code was helpful but the publishing part conflicts.
// The android.publishing DSL is preferred.


// Define project.group and project.version for Maven publishing.
// These will be used by the publication created by android.publishing and maven-publish.
// Ensure these properties are defined (e.g., in gradle.properties or set sensible defaults).
// Use properties specific to the library's Maven coordinates if they differ from the app.
project.group = project.findProperty("LIB_GROUP_ID")?.toString() ?: "org.love2d.android.sdk" // Example: use a library-specific group
project.version = project.findProperty("LIB_VERSION_NAME")?.toString() ?: android.defaultConfig.versionName // Use library version


dependencies {
implementation 'androidx.appcompat:appcompat:1.7.0'
Expand All @@ -178,7 +203,6 @@ dependencies {
implementation 'com.google.oboe:oboe:1.9.3'
}

// We don't even use Kotlin. Why we have to care about it?
configurations.implementation {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
}
File renamed without changes.
File renamed without changes.
Loading
Loading