aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/android/build.sh114
-rwxr-xr-x.ci/android/package.sh22
-rw-r--r--CMakeLists.txt16
-rw-r--r--CMakeModules/CPMUtil.cmake8
-rw-r--r--cpmfile.json2
-rw-r--r--docs/build/Android.md62
-rw-r--r--externals/cpmfile.json10
-rw-r--r--externals/ffmpeg/CMakeLists.txt10
-rw-r--r--externals/ffmpeg/cpmfile.json6
-rw-r--r--src/android/app/build.gradle.kts71
-rwxr-xr-xtools/cpm/download.sh7
11 files changed, 253 insertions, 75 deletions
diff --git a/.ci/android/build.sh b/.ci/android/build.sh
index 836faa38d5..07cda2829f 100755
--- a/.ci/android/build.sh
+++ b/.ci/android/build.sh
@@ -1,21 +1,121 @@
-#!/bin/bash -e
+#!/bin/sh -e
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
-export NDK_CCACHE=$(which ccache)
+NUM_JOBS=$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)
+export CMAKE_BUILD_PARALLEL_LEVEL="${NUM_JOBS}"
+ARTIFACTS_DIR="$PWD/artifacts"
-if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
+: "${CCACHE:=false}"
+RETURN=0
+
+usage() {
+ cat <<EOF
+Usage: $0 [-t|--target FLAVOR] [-b|--build-type BUILD_TYPE]
+ [-h|--help] [-r|--release] [extra options]
+
+Build script for Android.
+Associated variables can be set outside the script,
+and will apply both to this script and the packaging script.
+bool values are "true" or "false"
+
+Options:
+ -r, --release Enable update checker. If set, sets the DEVEL bool variable to false.
+ By default, DEVEL is true.
+ -t, --target <FLAVOR> Build flavor (variable: TARGET)
+ Valid values are: legacy, optimized, standard, chromeos
+ Default: standard
+ -b, --build-type <TYPE> Build type (variable: TYPE)
+ Valid values are: Release, RelWithDebInfo, Debug
+ Default: Debug
+
+Extra arguments are passed to CMake (e.g. -DCMAKE_OPTION_NAME=VALUE)
+Set the CCACHE variable to "true" to enable build caching.
+The APK and AAB will be output into "artifacts".
+
+EOF
+
+ exit "$RETURN"
+}
+
+die() {
+ echo "-- ! $*" >&2
+ RETURN=1 usage
+}
+
+target() {
+ [ -z "$1" ] && die "You must specify a valid target."
+
+ TARGET="$1"
+}
+
+type() {
+ [ -z "$1" ] && die "You must specify a valid type."
+
+ TYPE="$1"
+}
+
+while true; do
+ case "$1" in
+ -r|--release) DEVEL=false ;;
+ -t|--target) target "$2"; shift ;;
+ -b|--build-type) type "$2"; shift ;;
+ -h|--help) usage ;;
+ *) break ;;
+ esac
+
+ shift
+done
+
+: "${TARGET:=standard}"
+: "${TYPE:=Release}"
+: "${DEVEL:=true}"
+
+TARGET_LOWER=$(echo "$TARGET" | tr '[:upper:]' '[:lower:]')
+
+case "$TARGET_LOWER" in
+ legacy) FLAVOR=Legacy ;;
+ optimized) FLAVOR=GenshinSpoof ;;
+ standard) FLAVOR=Mainline ;;
+ chromeos) FLAVOR=ChromeOS ;;
+ *) die "Invalid build flavor $TARGET."
+esac
+
+case "$TYPE" in
+ RelWithDebInfo|Release|Debug) ;;
+ *) die "Invalid build type $TYPE."
+esac
+
+LOWER_FLAVOR=$(echo "$FLAVOR" | sed 's/./\L&/')
+LOWER_TYPE=$(echo "$TYPE" | sed 's/./\L&/')
+
+if [ -n "${ANDROID_KEYSTORE_B64}" ]; then
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
- base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
+ echo "${ANDROID_KEYSTORE_B64}" | base64 --decode > "${ANDROID_KEYSTORE_FILE}"
+ SHA1SUM=$(keytool -list -v -storepass "${ANDROID_KEYSTORE_PASS}" -keystore "${ANDROID_KEYSTORE_FILE}" | grep SHA1 | cut -d " " -f3)
+ echo "-- Keystore SHA1 is ${SHA1SUM}"
fi
cd src/android
chmod +x ./gradlew
-./gradlew assembleMainlineRelease
-./gradlew bundleMainlineRelease
+set -- "$@" -DUSE_CCACHE="${CCACHE}"
+[ "$DEVEL" != "true" ] && set -- "$@" -DENABLE_UPDATE_CHECKER=ON
+
+echo "-- building..."
+
+./gradlew "copy${FLAVOR}${TYPE}Outputs" \
+ -Dorg.gradle.caching="${CCACHE}" \
+ -Dorg.gradle.parallel="${CCACHE}" \
+ -Dorg.gradle.workers.max="${NUM_JOBS}" \
+ -PYUZU_ANDROID_ARGS="$*" \
+ --info
-if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
+if [ -n "${ANDROID_KEYSTORE_B64}" ]; then
rm "${ANDROID_KEYSTORE_FILE}"
fi
+
+echo "-- Done! APK and AAB artifacts are in ${ARTIFACTS_DIR}"
+
+ls -l "${ARTIFACTS_DIR}/"
diff --git a/.ci/android/package.sh b/.ci/android/package.sh
deleted file mode 100755
index 50b7bbc332..0000000000
--- a/.ci/android/package.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-GITDATE="$(git show -s --date=short --format='%ad' | sed 's/-//g')"
-GITREV="$(git show -s --format='%h')"
-ARTIFACTS_DIR="$PWD/artifacts"
-mkdir -p "${ARTIFACTS_DIR}/"
-
-REV_NAME="eden-android-${GITDATE}-${GITREV}"
-BUILD_FLAVOR="mainline"
-BUILD_TYPE_LOWER="release"
-BUILD_TYPE_UPPER="Release"
-
-cp src/android/app/build/outputs/apk/"${BUILD_FLAVOR}/${BUILD_TYPE_LOWER}/app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.apk" \
- "${ARTIFACTS_DIR}/${REV_NAME}.apk" || echo "APK not found"
-
-cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}${BUILD_TYPE_UPPER}"/"app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.aab" \
- "${ARTIFACTS_DIR}/${REV_NAME}.aab" || echo "AAB not found"
-
-ls -la "${ARTIFACTS_DIR}/"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4afbc13683..4a108e47af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -436,10 +436,10 @@ if (ENABLE_OPENSSL)
option(YUZU_USE_BUNDLED_OPENSSL "Download bundled OpenSSL build" ${DEFAULT_YUZU_USE_BUNDLED_OPENSSL})
endif()
+# TODO(crueter): CPM this
if (ANDROID AND YUZU_DOWNLOAD_ANDROID_VVL)
- # TODO(crueter): CPM this
- set(vvl_version "1.4.321.0")
- set(vvl_zip_file "${CMAKE_BINARY_DIR}/externals/vvl-android.zip")
+ set(vvl_version "1.4.328.0")
+ set(vvl_zip_file "${CMAKE_BINARY_DIR}/externals/vvl-android-${vvl_version}.zip")
if (NOT EXISTS "${vvl_zip_file}")
# Download and extract validation layer release to externals directory
set(vvl_base_url "https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download")
@@ -450,8 +450,14 @@ if (ANDROID AND YUZU_DOWNLOAD_ANDROID_VVL)
endif()
# Copy the arm64 binary to src/android/app/main/jniLibs
- set(vvl_lib_path "${CMAKE_CURRENT_SOURCE_DIR}/src/android/app/src/main/jniLibs/arm64-v8a/")
- file(COPY "${CMAKE_BINARY_DIR}/externals/android-binaries-${vvl_version}/arm64-v8a/libVkLayer_khronos_validation.so"
+ if (ARCHITECTURE_arm64)
+ set(vvl_abi arm64-v8a)
+ elseif(ARCHITECTURE_x86_64)
+ set(vvl_abi x86_64)
+ endif()
+
+ set(vvl_lib_path "${CMAKE_CURRENT_SOURCE_DIR}/src/android/app/src/main/jniLibs/${vvl_abi}/")
+ file(COPY "${CMAKE_BINARY_DIR}/externals/android-binaries-${vvl_version}/${vvl_abi}/libVkLayer_khronos_validation.so"
DESTINATION "${vvl_lib_path}")
endif()
diff --git a/CMakeModules/CPMUtil.cmake b/CMakeModules/CPMUtil.cmake
index 78bab05030..53b9e24079 100644
--- a/CMakeModules/CPMUtil.cmake
+++ b/CMakeModules/CPMUtil.cmake
@@ -603,8 +603,12 @@ function(AddCIPackage)
add_ci_package(mingw-arm64)
endif()
- if (ANDROID AND NOT "android" IN_LIST DISABLED_PLATFORMS)
- add_ci_package(android)
+ if((ANDROID AND ARCHITECTURE_x86_64) AND NOT "android-x86_64" IN_LIST DISABLED_PLATFORMS)
+ add_ci_package(android-x86_64)
+ endif()
+
+ if((ANDROID AND ARCHITECTURE_arm64) AND NOT "android-aarch64" IN_LIST DISABLED_PLATFORMS)
+ add_ci_package(android-aarch64)
endif()
if(PLATFORM_SUN AND NOT "solaris-amd64" IN_LIST DISABLED_PLATFORMS)
diff --git a/cpmfile.json b/cpmfile.json
index 6cf7ed1a41..c00f955087 100644
--- a/cpmfile.json
+++ b/cpmfile.json
@@ -4,7 +4,7 @@
"package": "OpenSSL",
"name": "openssl",
"repo": "crueter-ci/OpenSSL",
- "version": "3.6.0-e3608d80df",
+ "version": "3.6.0-965d6279e8",
"min_version": "1.1.1"
},
"boost": {
diff --git a/docs/build/Android.md b/docs/build/Android.md
index 5805ed2797..638d429328 100644
--- a/docs/build/Android.md
+++ b/docs/build/Android.md
@@ -1,30 +1,37 @@
-# Note: These build instructions are a work-in-progress.
+# Android
## Dependencies
+
* [Android Studio](https://developer.android.com/studio)
* [NDK 27+ and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version)
* [Git](https://git-scm.com/download)
-### WINDOWS ONLY - Additional Dependencies
- * **[Visual Studio 2022 Community](https://visualstudio.microsoft.com/downloads/)** - **Make sure to select "Desktop development with C++" support in the installer. Make sure to update to the latest version if already installed.**
- * **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - **Make sure to select Latest SDK.**
- - A convenience script to install the latest SDK is provided in `.ci\windows\install-vulkan-sdk.ps1`.
+## WINDOWS ONLY - Additional Dependencies
+
+* **[Visual Studio 2022 Community](https://visualstudio.microsoft.com/downloads/)** - **Make sure to select "Desktop development with C++" support in the installer. Make sure to update to the latest version if already installed.**
+* **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - **Make sure to select Latest SDK.**
+ * A convenience script to install the latest SDK is provided in `.ci\windows\install-vulkan-sdk.ps1`.
## Cloning Eden with Git
-```
+
+```sh
git clone --recursive https://git.eden-emu.dev/eden-emu/eden.git
```
-Eden by default will be cloned into -
+
+Eden by default will be cloned into:
+
* `C:\Users\<user-name>\eden` on Windows
* `~/eden` on Linux and macOS
## Building
+
1. Start Android Studio, on the startup dialog select `Open`.
2. Navigate to the `eden/src/android` directory and click on `OK`.
3. In `Build > Select Build Variant`, select `release` or `relWithDebInfo` as the "Active build variant".
4. Build the project with `Build > Make Project` or run it on an Android device with `Run > Run 'app'`.
## Building with Terminal
+
1. Download the SDK and NDK from Android Studio.
2. Navigate to SDK and NDK paths.
3. Then set ANDROID_SDK_ROOT and ANDROID_NDK_ROOT in terminal via
@@ -38,7 +45,44 @@ Eden by default will be cloned into -
Remember to have a Java SDK installed if not already, on Debian and similar this is done with `sudo apt install openjdk-17-jdk`.
### Script
-A convenience script for building is provided in `.ci/android/build.sh`. The built APK can be put into an `artifacts` directory via `.ci/android/package.sh`. On Windows, these must be done in the Git Bash or MinGW terminal.
+
+A convenience script for building is provided in `.ci/android/build.sh`. On Windows, this must be run in Git Bash or MSYS2. This script provides the following options:
+
+```txt
+Usage: build.sh [-c|--chromeos] [-t|--target FLAVOR] [-b|--build-type BUILD_TYPE]
+ [-h|--help] [-r|--release] [extra options]
+
+Build script for Android.
+Associated variables can be set outside the script,
+and will apply both to this script and the packaging script.
+bool values are "true" or "false"
+
+Options:
+ -c, --chromeos Build for ChromeOS (x86_64) (variable: CHROMEOS, bool)
+ Default: false
+ -r, --release Enable update checker. If set, sets the DEVEL bool variable to false.
+ By default, DEVEL is true.
+ -t, --target <FLAVOR> Build flavor (variable: TARGET)
+ Valid values are: legacy, optimized, standard
+ Default: standard
+ -b, --build-type <TYPE> Build type (variable: TYPE)
+ Valid values are: Release, RelWithDebInfo, Debug
+ Default: Debug
+
+Extra arguments are passed to CMake (e.g. -DCMAKE_OPTION_NAME=VALUE)
+Set the CCACHE variable to "true" to enable build caching.
+The APK and AAB will be output into "artifacts".
+```
+
+Examples:
+
+* Build legacy release with update checker for ChromeOS:
+ * `.ci/android/build.sh -c -r -t legacy`
+* Build standard release with debug info without update checker for phones:
+ * `.ci/android/build.sh -b RelWithDebInfo`
+* Build optimized release with update checker:
+ * `.ci/android/build.sh -r -t optimized`
### Additional Resources
-https://developer.android.com/studio/intro
+
+<https://developer.android.com/studio/intro>
diff --git a/externals/cpmfile.json b/externals/cpmfile.json
index ee5ccb451e..7f5af5dfce 100644
--- a/externals/cpmfile.json
+++ b/externals/cpmfile.json
@@ -9,7 +9,7 @@
},
"sirit": {
"repo": "eden-emulator/sirit",
- "git_version": "1.0.2",
+ "git_version": "1.0.3",
"tag": "v%VERSION%",
"artifact": "sirit-source-%VERSION%.tar.zst",
"hash_suffix": "sha512sum",
@@ -23,11 +23,7 @@
"package": "sirit",
"name": "sirit",
"repo": "eden-emulator/sirit",
- "version": "1.0.2",
- "disabled_platforms": [
- "mingw-amd64",
- "mingw-arm64"
- ]
+ "version": "1.0.3"
},
"httplib": {
"repo": "yhirose/cpp-httplib",
@@ -167,7 +163,7 @@
"package": "SDL2",
"name": "SDL2",
"repo": "crueter-ci/SDL2",
- "version": "2.32.10-38e0094637",
+ "version": "2.32.10-a65111bd2d",
"min_version": "2.26.4"
},
"catch2": {
diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt
index 58461d8934..d71613db8c 100644
--- a/externals/ffmpeg/CMakeLists.txt
+++ b/externals/ffmpeg/CMakeLists.txt
@@ -114,16 +114,6 @@ if (UNIX AND NOT ANDROID)
endif()
if (YUZU_USE_BUNDLED_FFMPEG)
- # MSVC conflicts with ksuser otherwise
- # MinGW has the funny quirk of requiring avutil after avcodec
- # Android needs some deps to be compiled with PIC (TODO)
- # TODO(crueter) fix
- if (ANDROID)
- set(BUILD_SHARED_LIBS ON)
- else()
- set(BUILD_SHARED_LIBS OFF)
- endif()
-
AddJsonPackage(ffmpeg-ci)
set(FFmpeg_INCLUDE_DIR
diff --git a/externals/ffmpeg/cpmfile.json b/externals/ffmpeg/cpmfile.json
index 0baeeb4713..0d0a612eda 100644
--- a/externals/ffmpeg/cpmfile.json
+++ b/externals/ffmpeg/cpmfile.json
@@ -1,8 +1,8 @@
{
"ffmpeg": {
"repo": "FFmpeg/FFmpeg",
- "sha": "c2184b65d2",
- "hash": "007b1ccdd4d3ea3324835258d9a255103253bd66edb442b12d9c60dca85149cad52136a3b3120e5094115b6a3d9e80eeacbf9c07e5ffafc9ac459614d5fa3b22",
+ "sha": "ddf443f1e9",
+ "hash": "ded1c313843f23805102565bd3ca92602fb9c2951e059ca5e1a486ab3ef7d589acccf3cde05c5ff0cfc5199c3a261dccb4d2a93254e585824850696fb41a292e",
"bundled": true
},
"ffmpeg-ci": {
@@ -10,7 +10,7 @@
"package": "FFmpeg",
"name": "ffmpeg",
"repo": "crueter-ci/FFmpeg",
- "version": "8.0-be99d2c0b2",
+ "version": "8.0-ddf443f1e9",
"min_version": "4.1"
}
}
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index 01a413261e..87d815c92c 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -4,10 +4,11 @@
// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-import android.annotation.SuppressLint
+// import android.annotation.SuppressLint
import kotlin.collections.setOf
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
+import org.gradle.api.tasks.Copy
plugins {
id("com.android.application")
@@ -63,11 +64,6 @@ android {
versionName = getGitVersion()
versionCode = autoVersion
- ndk {
- @SuppressLint("ChromeOsAbiSupport")
- abiFilters += listOf("arm64-v8a")
- }
-
externalNativeBuild {
cmake {
val extraCMakeArgs =
@@ -127,7 +123,7 @@ android {
isMinifyEnabled = true
isDebuggable = false
proguardFiles(
- getDefaultProguardFile("proguard-android.txt"),
+ getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
@@ -139,7 +135,7 @@ android {
signingConfig = signingConfigs.getByName("default")
isDebuggable = true
proguardFiles(
- getDefaultProguardFile("proguard-android.txt"),
+ getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
versionNameSuffix = "-relWithDebInfo"
@@ -163,12 +159,20 @@ android {
create("mainline") {
dimension = "version"
resValue("string", "app_name_suffixed", "Eden")
+
+ ndk {
+ abiFilters += listOf("arm64-v8a")
+ }
}
create("genshinSpoof") {
dimension = "version"
resValue("string", "app_name_suffixed", "Eden Optimized")
applicationId = "com.miHoYo.Yuanshen"
+
+ ndk {
+ abiFilters += listOf("arm64-v8a")
+ }
}
create("legacy") {
@@ -187,6 +191,25 @@ android {
res.srcDirs("src/main/legacy")
}
}
+
+ ndk {
+ abiFilters += listOf("arm64-v8a")
+ }
+ }
+
+ create("chromeOS") {
+ dimension = "version"
+ resValue("string", "app_name_suffixed", "Eden")
+
+ ndk {
+ abiFilters += listOf("x86_64")
+ }
+
+ externalNativeBuild {
+ cmake {
+ abiFilters("x86_64")
+ }
+ }
}
}
@@ -321,3 +344,35 @@ fun getGitVersion(): String {
}
return versionName.ifEmpty { "0.0" }
}
+
+afterEvaluate {
+ val artifactsDir = layout.projectDirectory.dir("../../../artifacts")
+ val outputsDir = layout.buildDirectory.dir("outputs").get()
+
+ android.applicationVariants.forEach { variant ->
+ val variantName = variant.name
+ val variantTask = variantName.replaceFirstChar { it.uppercaseChar() }
+
+ val flavor = variant.flavorName
+ val type = variant.buildType.name
+
+ val baseName = "app-$flavor-$type"
+
+ val apkFile = outputsDir.file("apk/$flavor/$type/$baseName.apk")
+ val aabFile = outputsDir.file("bundle/$variantName/$baseName.aab")
+
+ val taskName = "copy${variantTask}Outputs"
+
+ tasks.register<Copy>(taskName) {
+ group = "publishing"
+ description = "Copy APK and AAB for $variantName to $artifactsDir"
+
+ from(apkFile)
+ from(aabFile)
+ into(artifactsDir)
+
+ dependsOn("assemble${variantTask}")
+ dependsOn("bundle${variantTask}")
+ }
+ }
+}
diff --git a/tools/cpm/download.sh b/tools/cpm/download.sh
index 9793db0c04..bc436ba0f1 100755
--- a/tools/cpm/download.sh
+++ b/tools/cpm/download.sh
@@ -65,7 +65,12 @@ ci_package() {
echo "-- CI package $PACKAGE_NAME"
- for platform in windows-amd64 windows-arm64 mingw-amd64 mingw-arm64 android solaris-amd64 freebsd-amd64 openbsd-amd64 linux-amd64 linux-aarch64 macos-universal; do
+ for platform in windows-amd64 windows-arm64 \
+ mingw-amd64 mingw-arm64 \
+ android-aarch64 android-x86_64 \
+ solaris-amd64 freebsd-amd64 openbsd-amd64 \
+ linux-amd64 linux-aarch64 \
+ macos-universal; do
echo "-- * platform $platform"
case $DISABLED in