mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 11:01:07 +00:00
Merge remote-tracking branch 'origin/main' into feat/frontend-motion
This commit is contained in:
commit
9b034fcbb2
7 files changed
+225
-8
No files matched your search
@@ -7,6 +7,7 @@ build/
|
||||
captures/
|
||||
.externalNativeBuild/
|
||||
.cxx/
|
||||
.kotlin/
|
||||
# Built in CI from tools/linuxfs and app/src/main/cpp/fakeinput.cpp, never committed, so the two
|
||||
# copies cannot drift.
|
||||
app/src/main/assets/linuxfs/
|
||||
|
||||
@@ -26,11 +26,12 @@ _From the repository's pull requests; rewritten when one is opened, merged or cl
|
||||
|
||||
| Contributor | Pull request | Opened | State |
|
||||
|---|---|---|---|
|
||||
| [@xXJSONDeruloXx](https://github.com/xXJSONDeruloXx) | [#1](https://github.com/The412Banner/SteamDeck/pull/1) initial decky installer stuff | 2026-09-23 | draft |
|
||||
| [@xXJSONDeruloXx](https://github.com/xXJSONDeruloXx) | [#1](https://github.com/The412Banner/SteamDeck/pull/1) initial decky installer stuff | 2026-09-23 | closed |
|
||||
| [@xXJSONDeruloXx](https://github.com/xXJSONDeruloXx) | [#3](https://github.com/The412Banner/SteamDeck/pull/3) Fix hardware back in Steam session | 2026-09-23 | merged 2026-09-23 |
|
||||
| [@xXJSONDeruloXx](https://github.com/xXJSONDeruloXx) | [#4](https://github.com/The412Banner/SteamDeck/pull/4) Update app launcher icon | 2026-09-23 | merged 2026-09-23 |
|
||||
| [@xXJSONDeruloXx](https://github.com/xXJSONDeruloXx) | [#5](https://github.com/The412Banner/SteamDeck/pull/5) Add reproducible local build and deploy helpers | 2026-09-23 | merged 2026-09-23 |
|
||||
|
||||
- **@xXJSONDeruloXx**: 3 submitted, 2 merged
|
||||
- **@xXJSONDeruloXx**: 4 submitted, 3 merged
|
||||
<!-- contributions:end -->
|
||||
|
||||
## Requirements
|
||||
@@ -141,10 +142,27 @@ first use.
|
||||
|
||||
## Building
|
||||
|
||||
Nothing is built locally. Push, and the `Build APK` workflow produces `steamdeck-apk`, a
|
||||
debug-signed arm64 apk. It cross-compiles the two glibc preloads the session needs
|
||||
(`libfakeinput.so`, `libblsession.so`) from the sources in this repo before the app build, so
|
||||
those can never drift from what ships.
|
||||
The repeatable local build is `tools/build_local.sh`. It uses Docker's Ubuntu cross-toolchain for
|
||||
the two glibc ARM64 preloads (`libfakeinput.so`, `libblsession.so`), the Android SDK/NDK already
|
||||
installed on the machine, and the same release signing and native dependency checks as CI. The
|
||||
APK is written to `app/build/outputs/apk/release/app-release.apk`.
|
||||
|
||||
```sh
|
||||
tools/build_local.sh
|
||||
```
|
||||
|
||||
CI remains available through the `Build APK` workflow. Both paths cross-compile the preloads from
|
||||
the sources in this repo before the app build, so those cannot drift from what ships.
|
||||
|
||||
With an authorized Android device attached over USB or ADB, install the locally built APK with:
|
||||
|
||||
```sh
|
||||
tools/deploy_local.sh
|
||||
```
|
||||
|
||||
Set `ADB_SERIAL` when more than one device is attached. The deploy helper installs over the
|
||||
existing `com.steamdeck.launcher` package using the repository's stable test key and verifies the
|
||||
package path afterward; it does not launch a session automatically.
|
||||
|
||||
## If Bannerlator is already installed
|
||||
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ android {
|
||||
compileSdk 34
|
||||
// The NDK is pinned by property so CI can hand in whatever the runner already has rather than
|
||||
// downloading a second copy; see gradle.properties.
|
||||
ndkVersion project.findProperty('ndkVersion') ?: '27.0.12077973'
|
||||
ndkVersion project.findProperty('ndkVersion') ?: '27.3.13750724'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.steamdeck.launcher"
|
||||
|
||||
+1
-1
@@ -10,4 +10,4 @@ android.useAndroidX=true
|
||||
android.nonTransitiveRClass=true
|
||||
# The NDK the compositor is built with. CI passes the one the runner has installed
|
||||
# (-PndkVersion=…); this is the fallback for a local build.
|
||||
ndkVersion=27.0.12077973
|
||||
ndkVersion=27.3.13750724
|
||||
Executable
+147
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
sdk_dir=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-"${HOME}/Library/Android/sdk"}}
|
||||
java_dir=${JAVA_HOME:-"/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home"}
|
||||
image_name=${STEAMDECK_BUILD_IMAGE:-steamdeck-local-cross:24.04-v2}
|
||||
|
||||
if [[ ! -x "${sdk_dir}/platform-tools/adb" ]]; then
|
||||
echo "Android SDK not found at ${sdk_dir}; set ANDROID_HOME or ANDROID_SDK_ROOT." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "${java_dir}/bin/java" ]]; then
|
||||
echo "Java 17 not found at ${java_dir}; set JAVA_HOME." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "Docker is required to cross-compile the glibc ARM64 preload libraries." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker image inspect "${image_name}" >/dev/null 2>&1; then
|
||||
docker build --platform linux/amd64 -t "${image_name}" \
|
||||
-f "${repo_root}/tools/local-cross.Dockerfile" "${repo_root}"
|
||||
fi
|
||||
|
||||
docker run --rm --platform linux/amd64 \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-v "${repo_root}:/src" -w /src "${image_name}" bash -lc '
|
||||
set -euo pipefail
|
||||
d=app/src/main/assets/linuxfs
|
||||
mkdir -p "$d"
|
||||
aarch64-linux-gnu-g++ -shared -fPIC -O2 -Wall -Wno-attributes -Wno-nonnull-compare \
|
||||
-pthread -std=c++17 -static-libstdc++ -static-libgcc \
|
||||
-o "$d/libfakeinput.so" app/src/main/cpp/fakeinput_steam.cpp -ldl
|
||||
aarch64-linux-gnu-strip --strip-unneeded "$d/libfakeinput.so"
|
||||
aarch64-linux-gnu-gcc -shared -fPIC -O2 -Wall -pthread \
|
||||
-o "$d/libblsession.so" tools/linuxfs/preload/*.c -ldl
|
||||
aarch64-linux-gnu-strip --strip-unneeded "$d/libblsession.so"
|
||||
for script in tools/linuxfs/overlay/usr/local/bin/bannerlator-*; do
|
||||
install -Dm644 "$script" "$d/usr/local/bin/$(basename "$script")"
|
||||
done
|
||||
install -Dm644 tools/linuxfs/desktop/steamdeck-desktop "$d/usr/local/bin/steamdeck-desktop"
|
||||
install -Dm644 tools/linuxfs/desktop/autostart "$d/etc/xdg/labwc/autostart"
|
||||
install -Dm644 tools/linuxfs/desktop/rc.xml "$d/etc/xdg/labwc/rc.xml"
|
||||
install -Dm644 tools/linuxfs/desktop/panel.conf "$d/etc/xdg/lxqt/panel.conf"
|
||||
install -Dm644 tools/linuxfs/desktop/firefox-steamdeck.js \
|
||||
"$d/usr/lib/firefox/defaults/pref/steamdeck.js"
|
||||
|
||||
need=$(aarch64-linux-gnu-readelf -d "$d/libfakeinput.so" | sed -n "s/.*NEEDED.*\\[\\(.*\\)\\]/\\1/p")
|
||||
for bad in libstdc++.so.6 libgcc_s.so.1; do
|
||||
if printf "%s\\n" "$need" | grep -qx "$bad"; then
|
||||
echo "libfakeinput.so links $bad; the C++ runtime must stay static" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
syms() { aarch64-linux-gnu-readelf -Ws "$1" | awk '\''$4 == "FUNC" && $5 == "GLOBAL" {sub(/@.*/, "", $8); print $8}'\''; }
|
||||
fake=$(syms "$d/libfakeinput.so")
|
||||
for sym in open openat ioctl read close poll ppoll select stat fstat access scandir; do
|
||||
printf "%s\\n" "$fake" | grep -qx "$sym" || {
|
||||
echo "libfakeinput.so does not export $sym" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
session=$(syms "$d/libblsession.so")
|
||||
for sym in socket bind getsockname setsockopt statfs statvfs; do
|
||||
printf "%s\\n" "$session" | grep -qx "$sym" || {
|
||||
echo "libblsession.so does not export $sym" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
test -f "$d/usr/local/bin/bannerlator-session"
|
||||
test -f "$d/usr/local/bin/bannerlator-proton-extra"
|
||||
'
|
||||
|
||||
export ANDROID_HOME="${sdk_dir}"
|
||||
export ANDROID_SDK_ROOT="${sdk_dir}"
|
||||
export JAVA_HOME="${java_dir}"
|
||||
ndk_version=${STEAMDECK_NDK_VERSION:-}
|
||||
if [[ -z "${ndk_version}" ]]; then
|
||||
ndk_path=$(find "${sdk_dir}/ndk" -mindepth 1 -maxdepth 1 -type d -print | sort -V | tail -1)
|
||||
ndk_version=${ndk_path##*/}
|
||||
fi
|
||||
if [[ -z "${ndk_version}" || ! -d "${sdk_dir}/ndk/${ndk_version}" ]]; then
|
||||
echo "No Android NDK found under ${sdk_dir}/ndk; set STEAMDECK_NDK_VERSION." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "${repo_root}"
|
||||
./gradlew assembleRelease -PndkVersion="${ndk_version}"
|
||||
|
||||
apk="${repo_root}/app/build/outputs/apk/release/app-release.apk"
|
||||
build_tools=$(find "${sdk_dir}/build-tools" -mindepth 1 -maxdepth 1 -type d -print | sort -V | tail -1)
|
||||
if [[ ! -x "${build_tools}/zipalign" || ! -x "${build_tools}/apksigner" ]]; then
|
||||
echo "Android build-tools with zipalign/apksigner are required under ${sdk_dir}/build-tools." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
staging_dir=$(mktemp -d "${TMPDIR:-/tmp}/steamdeck-apk.XXXXXX")
|
||||
trap 'rm -rf -- "${staging_dir}"' EXIT
|
||||
"${build_tools}/zipalign" -p -f 4 "${apk}" "${staging_dir}/app-release.aligned.apk"
|
||||
"${build_tools}/apksigner" sign \
|
||||
--ks keystore/testkey.p12 --ks-type PKCS12 --ks-pass pass:android \
|
||||
--ks-key-alias testkey --key-pass pass:android \
|
||||
--v1-signing-enabled true --v2-signing-enabled true --v3-signing-enabled true \
|
||||
--out "${apk}" "${staging_dir}/app-release.aligned.apk"
|
||||
|
||||
signature_output=$("${build_tools}/apksigner" verify --min-sdk-version 21 --verbose --print-certs "${apk}")
|
||||
printf '%s\n' "${signature_output}"
|
||||
for scheme in \
|
||||
'Verified using v1 scheme (JAR signing): true' \
|
||||
'Verified using v2 scheme (APK Signature Scheme v2): true' \
|
||||
'Verified using v3 scheme (APK Signature Scheme v3): true'; do
|
||||
grep -qF "${scheme}" <<<"${signature_output}" || {
|
||||
echo "APK signature check failed: ${scheme}" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
grep -qF 'Signer #1 certificate DN: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android' \
|
||||
<<<"${signature_output}"
|
||||
|
||||
docker run --rm --platform linux/amd64 -v "${repo_root}:/src:ro" -w /src "${image_name}" \
|
||||
bash -lc '
|
||||
set -euo pipefail
|
||||
apk=app/build/outputs/apk/release/app-release.apk
|
||||
work=$(mktemp -d)
|
||||
unzip -q "$apk" "lib/arm64-v8a/*" -d "$work"
|
||||
cd "$work/lib/arm64-v8a"
|
||||
system="libc.so libm.so libdl.so liblog.so libandroid.so libz.so libvulkan.so
|
||||
libGLESv2.so libEGL.so libnativewindow.so libjnigraphics.so libaaudio.so
|
||||
libOpenSLES.so libmediandk.so libcamera2ndk.so libsync.so libneuralnetworks.so"
|
||||
fail=0
|
||||
for so in *.so; do
|
||||
for need in $(readelf -d "$so" | sed -n "s/.*NEEDED.*\\[\\(.*\\)\\]/\\1/p"); do
|
||||
[ -f "$need" ] && continue
|
||||
case " $(echo $system) " in *" $need "*) continue ;; esac
|
||||
echo "missing: $so -> $need"
|
||||
fail=1
|
||||
done
|
||||
done
|
||||
[ "$fail" -eq 0 ]
|
||||
echo "every NEEDED resolves"
|
||||
'
|
||||
|
||||
printf 'APK: %s\n' "${apk}"
|
||||
printf 'SHA-256: '
|
||||
shasum -a 256 "${apk}" | awk '{print $1}'
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
sdk_dir=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-"${HOME}/Library/Android/sdk"}}
|
||||
adb_bin=${ADB:-${sdk_dir}/platform-tools/adb}
|
||||
apk=${1:-"${repo_root}/app/build/outputs/apk/release/app-release.apk"}
|
||||
|
||||
if [[ ! -x "${adb_bin}" ]]; then
|
||||
echo "adb not found at ${adb_bin}; set ADB or ANDROID_HOME." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "${apk}" ]]; then
|
||||
echo "APK not found at ${apk}; run tools/build_local.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "${ADB_SERIAL:-}" ]]; then
|
||||
serial=${ADB_SERIAL}
|
||||
else
|
||||
devices=$("${adb_bin}" devices | awk '$2 == "device" {print $1}')
|
||||
device_count=$(printf '%s\n' "${devices}" | sed '/^$/d' | wc -l | tr -d ' ')
|
||||
if [[ "${device_count}" == 0 ]]; then
|
||||
echo "No authorized Android device found. Connect one or set ADB_SERIAL." >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ "${device_count}" != 1 ]]; then
|
||||
echo "Multiple Android devices found; set ADB_SERIAL explicitly." >&2
|
||||
printf '%s\n' "${devices}" >&2
|
||||
exit 2
|
||||
fi
|
||||
serial=${devices}
|
||||
fi
|
||||
|
||||
"${adb_bin}" -s "${serial}" install -r --no-incremental "${apk}"
|
||||
installed_path=$("${adb_bin}" -s "${serial}" shell pm path com.steamdeck.launcher | tr -d '\r')
|
||||
printf 'Installed on %s: %s\n' "${serial}" "${installed_path}"
|
||||
@@ -0,0 +1,14 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
binutils \
|
||||
binutils-aarch64-linux-gnu \
|
||||
gcc-aarch64-linux-gnu \
|
||||
g++-aarch64-linux-gnu \
|
||||
unzip \
|
||||
&& mkdir -p /src
|
||||
|
||||
WORKDIR /src
|
||||
Reference in new issue
Block a user