Skip to content
Merged
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
31 changes: 26 additions & 5 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
name: CMake on multiple platforms

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
on: [push, pull_request]

jobs:
build-all:
Expand Down Expand Up @@ -74,3 +70,28 @@ jobs:
- name: Test
working-directory: ./build/tests
run: ctest --build-config ${{ matrix.build_type }} --output-on-failure

build-android:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Setup JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'

- name: Setup Android SDK
uses: android-actions/setup-android@v4

- name: Grant execute permission for gradlew
run: chmod +x android/gradlew

- name: Buld APK with Gradle
run: ./gradlew assembleRelease
working-directory: android
env:
ANDROID_NDK_HOME: ${{ env.ANDROID_NDK_HOME }}
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -1055,4 +1055,9 @@ dkms.conf
# Raspberry Pi Pico Object file
*.uf2
# Raspberry Pi Pico disassembler file
*.dis
*.dis

# Android / CLion / IntelliJ
.idea
android/local.properties
android/.gradle/
55 changes: 40 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.28)

project ("GadgetCore" LANGUAGES CXX)
project ("GadgetCore" LANGUAGES C CXX)

# --------------------------------------- #
# ----- Fetch External Dependencies ----- #
Expand Down Expand Up @@ -74,6 +74,10 @@ set(ASSIMP_BUILD_RAW_IMPORTER ON)
set(ASSIMP_BUILD_STL_IMPORTER ON)
set(ASSIMP_BUILD_USD_IMPORTER OFF) # I would like to support this but build fails on Linux

if (ANDROID)
add_compile_definitions(USE_FILE32API) # Forces minizip to use standard fopen instead of missing fopen64
endif()

FetchContent_MakeAvailable(Assimp)

FetchContent_Declare(
Expand All @@ -100,17 +104,20 @@ else()
set(EXCEPTION_FLAG "")
endif()

find_program(CLANG_TIDY_EXE NAMES clang-tidy)

if (CLANG_TIDY_EXE)
message(STATUS "clang-tidy checks enabled")
set(CMAKE_CXX_CLANG_TIDY
clang-tidy
"-extra-arg=${EXCEPTION_FLAG}"
"--header-filter=.*[/\\]include[/\\]GCore[/\\]"
)
else()
message(STATUS "clang-tidy not found, will not run checks")
# TODO - See if we get clang-tidy to work reliably with Android Studio
if (NOT ANDROID)
find_program(CLANG_TIDY_EXE NAMES clang-tidy)

if (CLANG_TIDY_EXE)
message(STATUS "clang-tidy checks enabled")
set(CMAKE_CXX_CLANG_TIDY
clang-tidy
"-extra-arg=${EXCEPTION_FLAG}"
"--header-filter=.*[/\\]include[/\\]GCore[/\\]"
)
else()
message(STATUS "clang-tidy not found, will not run checks")
endif()
endif()

# --------------------------------------- #
Expand Down Expand Up @@ -178,11 +185,29 @@ endif()
# --------------------------------------- #

if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_definitions(GadgetCore PUBLIC GADGET_PLATFORM_WINDOWS)
target_compile_definitions(GadgetCore
PUBLIC
GADGET_PLATFORM_TYPE_PC
GADGET_PLATFORM_WINDOWS
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_compile_definitions(GadgetCore PUBLIC GADGET_PLATFORM_MACOS)
target_compile_definitions(GadgetCore
PUBLIC
GADGET_PLATFORM_TYPE_PC
GADGET_PLATFORM_MACOS
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_compile_definitions(GadgetCore PUBLIC GADGET_PLATFORM_LINUX)
target_compile_definitions(GadgetCore
PUBLIC
GADGET_PLATFORM_TYPE_PC
GADGET_PLATFORM_LINUX
)
elseif(ANDROID)
target_compile_definitions(GadgetCore
PUBLIC
GADGET_PLATFORM_TYPE_MOBILE
GADGET_PLATFORM_ANDROID
)
endif()

# --------------------------- #
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ GadgetCore spawned out of work on [GadgetEngine](https://github.com/ShikenNugget
- **Platform Abstraction**: You should never need to directly call a platform-specific function or an underlying system API.

## Platform Support
GadgetCore officially supports Windows, Mac, and Linux.
GadgetCore officially supports Windows, Mac, Linux, and Android.

Official platform support will be expanded to include mobile, game consoles, and WASM some time in the future. Android is the next highest priority. That said, I expect most features to work on most platforms regardless.
This will be expanded to include WebAssembly, game consoles, and iOS some time in the future. Most features should work on most platforms regardless of official support status. Bug reports for unsupported platforms are welcome.

## Stability
This library is in early development and is considered **unstable**. Expect frequent and unceremonious API breaks at this stage. I also do not plan to guarantee ABI stability for the foreseeable future. This will be updated as we approach a stable release.
Expand Down
68 changes: 68 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
plugins {
id 'com.android.application'
}

def buildWithCMake = true;

android {
namespace = "org.libsdl.app"
compileSdkVersion 35
ndkVersion = "28.2.13676358"
defaultConfig {
minSdkVersion 21
targetSdkVersion 35
versionCode 1
versionName "1.0"
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-21"
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'arm64-v8a', 'x86_64'
}
cmake {
arguments "-DANDROID_PLATFORM=android-21", "-DANDROID_STL=c++_static"
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'arm64-v8a', 'x86_64'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
applicationVariants.all { variant ->
tasks["merge${variant.name.capitalize()}Assets"]
.dependsOn("externalNativeBuild${variant.name.capitalize()}")
}
if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) {
//sourceSets.main {
// jniLibs.srcDir 'libs'
//}
externalNativeBuild {
if (buildWithCMake) {
cmake {
path '../../CMakeLists.txt'
version "3.28.0+"
}
} else {
ndkBuild {
path 'jni/Android.mk'
}
}
}

}
lint {
abortOnError = false
}

packagingOptions {
doNotStrip "*/libSDL3.so"
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
}
76 changes: 76 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in [sdk]/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# https://developer.android.com/build/shrink-code

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLActivity {
java.lang.String nativeGetHint(java.lang.String); # Java-side doesn't use this, so it gets minified, but C-side still tries to register it
java.lang.String clipboardGetText();
boolean clipboardHasText();
void clipboardSetText(java.lang.String);
int createCustomCursor(int[], int, int, int, int);
void destroyCustomCursor(int);
android.app.Activity getContext();
boolean getManifestEnvironmentVariables();
android.view.Surface getNativeSurface();
void initTouch();
boolean isAndroidTV();
boolean isChromebook();
boolean isDeXMode();
boolean isTablet();
void manualBackButton();
int messageboxShowMessageBox(int, java.lang.String, java.lang.String, int[], int[], java.lang.String[], int[]);
void minimizeWindow();
boolean openURL(java.lang.String);
void requestPermission(java.lang.String, int);
boolean showToast(java.lang.String, int, int, int, int);
boolean sendMessage(int, int);
boolean setActivityTitle(java.lang.String);
boolean setCustomCursor(int);
void setOrientation(int, int, boolean, java.lang.String);
boolean setRelativeMouseEnabled(boolean);
boolean setSystemCursor(int);
void setWindowStyle(boolean);
boolean shouldMinimizeOnFocusLoss();
boolean showTextInput(int, int, int, int, int);
boolean supportsRelativeMouse();
int openFileDescriptor(java.lang.String, java.lang.String);
boolean showFileDialog(java.lang.String[], boolean, boolean, int);
java.lang.String getPreferredLocales();
java.lang.String formatLocale(java.util.Locale);
}

-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {
void closeDevice(int);
boolean initialize(boolean, boolean);
boolean openDevice(int);
boolean readReport(int, byte[], boolean);
int writeReport(int, byte[], boolean);
}

-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLAudioManager {
void registerAudioDeviceCallback();
void unregisterAudioDeviceCallback();
void audioSetThreadPriority(boolean, int);
}

-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLControllerManager {
void pollInputDevices();
void pollHapticDevices();
void hapticRun(int, float, int);
void hapticRumble(int, float, float, int);
void hapticStop(int);
}
Loading