mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
Built with ffmpeg 8, libaom 3.13, x265 4.1, glibc 2.43 and clang 21, five lanes failed on the 26.04 runners: - AV1 fixtures: a monochrome sequence comes out full range with no matrix whatever is asked for; the oracle takes the colour ffprobe reads instead of assuming it. - Preview audio oracle: ffmpeg 8 leaves a timestamp gap at every seam of a -stream_loop copy, which the mixer honours and ffmpeg's raw decode does not. trailing_large loops its picture and encodes its sound as one track. - rh265 multi-slice oracle: x265 4.1 writes unreadable slice headers when two slices are encoded on several threads; those cases encode on one worker. - vkms: the kernel follows the runner's own release, its modules may sit under /usr/lib/modules, and modules-extra is fetched only where it exists. - clang -std=c89 -pedantic: glibc's const-generic strchr/strstr under _GNU_SOURCE are _Generic; -Wno-c11-extensions goes wherever -Wno-c99-extensions already does. ci_paths filters a file at the top of a samples tree by its own path. rh264 and rh265 lose the parameters no instantiation reads, the 8-bit H.264 kernels mark the depth they ignore, and the AV1 WebM fixtures leave out the MP4 box writer they never use.
246 lines
10 KiB
YAML
246 lines
10 KiB
YAML
name: CI Android
|
|
|
|
on:
|
|
push:
|
|
branches: [master]
|
|
# ci_paths: generated by tools/ci_paths.py, do not edit
|
|
paths:
|
|
- '**'
|
|
- '!.github/workflows/*.yml'
|
|
- '.github/workflows/Android.yml'
|
|
# ci_paths: end
|
|
pull_request:
|
|
# ci_paths: generated by tools/ci_paths.py, do not edit
|
|
paths:
|
|
- '**'
|
|
- '!.github/workflows/*.yml'
|
|
- '.github/workflows/Android.yml'
|
|
# ci_paths: end
|
|
workflow_dispatch:
|
|
repository_dispatch:
|
|
types: [run_build]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
env:
|
|
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 30
|
|
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
|
|
- name: Link with lld
|
|
run: sh .github/workflows/scripts/use-lld.sh
|
|
|
|
- name: Set up JDK 25
|
|
uses: actions/setup-java@v4
|
|
with:
|
|
java-version: '25'
|
|
distribution: 'temurin'
|
|
cache: 'gradle'
|
|
|
|
- name: Compile RA
|
|
run: |
|
|
cd pkg/android/phoenix
|
|
# A repository that answers with a server error is retried with
|
|
# a backoff (2 s doubling, six tries) before Gradle gives up on
|
|
# it for the rest of the build. A build that still fails to fetch
|
|
# a dependency is run again, keeping what it already fetched and
|
|
# built; any other failure fails the step at once.
|
|
set -o pipefail
|
|
for i in 1 2 3; do
|
|
./gradlew assembleDebug \
|
|
-Dorg.gradle.internal.repository.max.tentatives=6 \
|
|
-Dorg.gradle.internal.repository.initial.backoff=2000 \
|
|
2>&1 | tee gradle.log && break
|
|
grep -qE 'Could not (resolve|GET|HEAD|download)' gradle.log \
|
|
&& [ $i != 3 ] || exit 1
|
|
echo "dependency fetch failed (attempt $i); retrying in 30s"
|
|
sleep 30
|
|
done
|
|
find . -iname "*.apk" -exec ls -l "{}" \;
|
|
|
|
- name: Verify 64-bit APK alignment
|
|
run: |
|
|
set -eu
|
|
for apk in pkg/android/phoenix/build/outputs/apk/{aarch64,quest}/debug/*.apk; do
|
|
python3 tools/android_elf_alignment.py "$apk"
|
|
"$ANDROID_HOME/build-tools/36.0.0/zipalign" -c -P 16 4 "$apk"
|
|
done
|
|
|
|
- name: Get short SHA
|
|
id: slug
|
|
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: retroarch-android-${{ steps.slug.outputs.sha8 }}
|
|
path: |
|
|
pkg/android/phoenix/build/outputs/apk/normal/debug/phoenix-normal-debug.apk
|
|
pkg/android/phoenix/build/outputs/apk/aarch64/debug/phoenix-aarch64-debug.apk
|
|
pkg/android/phoenix/build/outputs/apk/quest/debug/phoenix-quest-debug.apk
|
|
|
|
vp9-stack-abi:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
- name: Use the Android project NDK version
|
|
run: |
|
|
set -eu
|
|
version=$(sed -n 's/.*ndkVersion "\([^"]*\)".*/\1/p' pkg/android/phoenix/build.gradle)
|
|
test -n "$version"
|
|
"$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "ndk;$version"
|
|
echo "MEDIA_NDK=$ANDROID_HOME/ndk/$version" >> "$GITHUB_ENV"
|
|
- name: VP9 C89 stack ceiling on both Android ABIs and file-offset modes
|
|
run: |
|
|
set -eu
|
|
bin="$MEDIA_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin"
|
|
unity="$RUNNER_TEMP/android-record-unity.c"
|
|
: > "$unity"
|
|
for source in gfx/common/mediacodec_inventory.c record/record_mediacodec_encoder.c \
|
|
record/record_mux_mediacodec.c record/record_mediacodec_worker.c \
|
|
record/record_mediacodec_surface.c record/record_android_capture_images.c \
|
|
record/record_android_capture_submit.c record/record_android_capture_gl.c \
|
|
record/record_android_capture_draw.c record/record_mediacodec_gpu_worker.c \
|
|
record/record_mediacodec_file.c record/record_gpu_queue.c \
|
|
record/record_audio_queue.c libretro-common/queues/retro_spsc.c; do
|
|
printf '#include "%s/%s"\n' "$PWD" "$source" >> "$unity"
|
|
done
|
|
for target in armv7a-linux-androideabi aarch64-linux-android; do
|
|
for api in 21 29; do
|
|
for offset in default 64; do
|
|
extra=""
|
|
if [ "$offset" = 64 ]; then extra="-D_FILE_OFFSET_BITS=64"; fi
|
|
CC="$bin/$target$api-clang $extra" python3 libretro-common/samples/formats/vp9/check_stack.py
|
|
"$bin/$target$api-clang" $extra -O1 -std=c89 -pedantic -Wall -Wextra -Werror \
|
|
-Wno-long-long -Wno-c99-extensions -Wno-c11-extensions -Wframe-larger-than=2048 \
|
|
-DHAVE_THREADS -DHAVE_DYLIB -Ilibretro-common/include -Igfx/include \
|
|
-c "$unity" -o "$RUNNER_TEMP/record-$target-$api-$offset.o"
|
|
if "$bin/llvm-nm" -u "$RUNNER_TEMP/record-$target-$api-$offset.o" | \
|
|
grep -Eq ' U (AMedia|ANativeWindow|AHardwareBuffer|egl|gl[A-Z]|record_android_capture_|record_mediacodec_|record_mux_mediacodec_|record_audio_queue_|record_gpu_queue_|retro_spsc_|mediacodec_inventory_)'; then
|
|
echo "Unresolved Android recording dependency"
|
|
exit 1
|
|
fi
|
|
for source in android_image_queue android_image_ndk mediacodec_session android_frame \
|
|
mediacodec_color mediacodec_frame_export vulkan_android_device \
|
|
vulkan_android_image vulkan_android_pipeline vulkan_android_sync \
|
|
vulkan_android_submit vulkan_android_cache_entry vulkan_android_cache vulkan_android_queue; do
|
|
"$bin/$target$api-clang" $extra -O1 -std=c89 -pedantic -Wall -Wextra -Werror \
|
|
-Wno-long-long -Wno-c99-extensions -Wno-c11-extensions -Wframe-larger-than=2048 \
|
|
-DHAVE_THREADS -DHAVE_DYLIB -Ilibretro-common/include -Igfx/include \
|
|
-c "gfx/common/$source.c" -o "$RUNNER_TEMP/$source-$target-$api-$offset.o"
|
|
done
|
|
done
|
|
done
|
|
done
|
|
|
|
- name: Link media-enabled Android unity frontend
|
|
run: |
|
|
set -eu
|
|
features="-DHAVE_RAAC -DHAVE_RMP4 -DHAVE_RWEBM -DHAVE_RVP9 -DHAVE_RAV1 -DHAVE_RVORBIS -DHAVE_ROPUS"
|
|
"$MEDIA_NDK/ndk-build" -j2 \
|
|
NDK_PROJECT_PATH=. \
|
|
APP_BUILD_SCRIPT=pkg/android/phoenix-common/jni/Android.mk \
|
|
NDK_APPLICATION_MK=pkg/android/phoenix-common/jni/Application.mk \
|
|
NDK_OUT="$RUNNER_TEMP/android-media-obj" \
|
|
NDK_LIBS_OUT="$RUNNER_TEMP/android-media-libs" \
|
|
TARGET_ABIS=arm64-v8a APP_ABI=arm64-v8a \
|
|
GLES=3 NDK_GL_HEADER_VER=android-29 APP_PLATFORM=android-29 \
|
|
APP_CFLAGS="$features" APP_CPPFLAGS="$features"
|
|
test -s "$RUNNER_TEMP/android-media-libs/arm64-v8a/libretroarch-activity.so"
|
|
|
|
codec-inventory:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
cc: [gcc, clang]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
- uses: actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: '21'
|
|
- name: Real JNI codec admission and exception contracts
|
|
run: make -C samples/gfx/mediacodec_inventory clean all check CC=${{ matrix.cc }} SANITIZER=undefined
|
|
|
|
image-ownership:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
cc: [gcc, clang]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
- name: Image ownership and runtime reader fault contracts
|
|
run: make -C samples/gfx/android_image_queue clean all check CC=${{ matrix.cc }} SANITIZER=address,undefined
|
|
|
|
codec-session:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
cc: [gcc, clang]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
- uses: actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: '21'
|
|
- name: Android encoder, AAC, mux and worker contracts
|
|
run: make -C samples/record/mediacodec_encode check CC=${{ matrix.cc }} SANITIZER=address,undefined
|
|
- name: Cold session, Surface timestamps and terminal output contracts
|
|
run: make -C samples/gfx/mediacodec_session session-check CC=${{ matrix.cc }} SANITIZER=address,undefined
|
|
- name: Opaque frame leases, HDR refinement and concurrent handoffs
|
|
run: make -C samples/gfx/mediacodec_session frame-check CC=${{ matrix.cc }} SANITIZER=address,undefined
|
|
- name: HEVC VP9 AV1 color intersection and renderer export contracts
|
|
run: make -C samples/gfx/mediacodec_session export-check CC=${{ matrix.cc }} SANITIZER=address,undefined
|
|
|
|
vulkan-import-resources:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
strategy:
|
|
matrix:
|
|
cc: [gcc, clang]
|
|
env:
|
|
APT_PKGS: libvulkan-dev mesa-vulkan-drivers glslc spirv-tools libegl1 libgles2 libgl1-mesa-dri
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
- uses: actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: '21'
|
|
- name: FD ownership, warm submission and cache retirement contracts
|
|
run: make -C samples/gfx/mediacodec_session warm-check CC=${{ matrix.cc }} SANITIZER=address,undefined
|
|
- name: Modeled image resources, device admission and pipeline contracts
|
|
run: make -C samples/gfx/mediacodec_session vulkan-check CC=${{ matrix.cc }} SANITIZER=address,undefined
|
|
- name: Apt cache key
|
|
id: apt
|
|
run: sh .github/workflows/scripts/apt-cache-key.sh "$APT_PKGS"
|
|
- name: Restore apt cache
|
|
uses: actions/cache/restore@v4
|
|
with:
|
|
path: ~/.apt-cache
|
|
key: ${{ steps.apt.outputs.key }}
|
|
restore-keys: ${{ steps.apt.outputs.prefix }}
|
|
- name: Install pixel oracle and shader validation dependencies
|
|
timeout-minutes: 20
|
|
run: sh .github/workflows/scripts/apt-install.sh $APT_PKGS
|
|
- name: Save apt cache
|
|
if: env.APT_CACHE_SAVE == '1'
|
|
uses: actions/cache/save@v4
|
|
with:
|
|
path: ~/.apt-cache
|
|
key: ${{ steps.apt.outputs.key }}
|
|
- name: Execute embedded and freshly compiled SDR PQ HLG cropped pixels
|
|
run: make -C samples/gfx/mediacodec_session vulkan-gpu-check CC=${{ matrix.cc }} SANITIZER=
|
|
- name: GLES recording SDR PQ and scRGB pixel oracle
|
|
run: EGL_PLATFORM=surfaceless LIBGL_ALWAYS_SOFTWARE=1 CC=${{ matrix.cc }} python3 samples/record/mediacodec_encode/draw_pixels.py
|