Compare commits

..
Author SHA1 Message Date
LibretroAdminandf4mrfaux d530eb8f10 android: report a controller the OS has removed as disconnected
Android tells the activity when an input device goes away - a pad
switched off, out of range or unplugged - but nothing passed that on
to the input driver, and no input event marks a removal. A pad
therefore stayed connected for as long as the app ran:

- its port kept its device name, so an overlay hidden while a
  controller is connected never came back;
- whatever it was holding stayed held, since no release arrives from a
  device that is gone;
- no disconnect notification was shown, and pausing on disconnect
  could not happen.

RetroActivityCommon.onInputDeviceRemoved now hands the device id to
the driver. It is left in a small lock-free mailbox and taken out at
the next input poll, which clears the pad's key, axis and hat state
and reports the disconnect through input_autoconfigure_disconnect, as
the other joypad drivers do.

The pad's slot keeps its name and is marked removed instead of being
emptied, so the device gets its old port back when it returns, under
whatever id Android gives it; its return is reported as a connect. A
removed slot is matched before a live one of the same name, so of two
identical controllers the one that went away is not taken for the one
still connected.

A removal is read at the next poll, which can be long after it
happened if the app was in the background. If the id resolves again by
then, the device has come back under it and nothing is reported.

This is the device-removal part of PR #19077, reworked. That version
emptied the slot's name, which the driver uses to find a returning
device's port: every reconnect would have moved the pad to the next
free port.

Compiled with the NDK through the Android unity build. Not run on a
device.

Co-authored-by: f4mrfaux <[email protected]>
2026-10-02 06:05:48 +02:00
11207 changed files with 1081675 additions and 1247240 deletions

No files matched your search

+1 -17
View File
@@ -3,23 +3,7 @@ name: CI 3DS
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/3DS.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/3DS.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-devkitpro:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
+1 -196
View File
@@ -3,19 +3,7 @@ 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]
@@ -38,45 +26,18 @@ jobs:
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
./gradlew assembleDebug
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)"
@@ -87,159 +48,3 @@ jobs:
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
-16
View File
@@ -12,23 +12,7 @@ name: CI Apple
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Apple.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Apple.yml'
# ci_paths: end
permissions:
contents: read
-61
View File
@@ -1,61 +0,0 @@
name: Deferred auto-state regression
on:
push:
paths:
- 'runloop.c'
- 'runloop.h'
- 'runahead.c'
- 'command.c'
- 'samples/runloop/auto_state_load/**'
- '.github/workflows/Auto-state-load.yml'
pull_request:
paths:
- 'runloop.c'
- 'runloop.h'
- 'runahead.c'
- 'command.c'
- 'samples/runloop/auto_state_load/**'
- '.github/workflows/Auto-state-load.yml'
jobs:
regression:
runs-on: ubuntu-latest
env:
APT_PKGS: gcc-mingw-w64-x86-64
steps:
- uses: actions/checkout@v4
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Linux and sanitizer tests
working-directory: samples/runloop/auto_state_load
run: |
make check
make clean
make check EXTRA_CFLAGS='-DHAVE_NETWORKING -DHAVE_CHEEVOS' SANITIZER=address,undefined
- name: Windows cross-build
working-directory: samples/runloop/auto_state_load
run: |
make clean
make CC=x86_64-w64-mingw32-gcc TARGET=auto_state_load_test.exe EXTRA_CFLAGS='-DHAVE_NETWORKING -DHAVE_CHEEVOS'
-94
View File
@@ -1,94 +0,0 @@
name: CI local workflow runner
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
ci-local-selftest:
name: tools/ci_local.py reads and runs every workflow
runs-on: ubuntu-latest
env:
APT_PKGS: python3-yaml
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Self-test
shell: bash
run: |
set -eu
# Every workflow parses exactly as PyYAML reads it, every job and
# matrix combination resolves in a dry run, and a fixture job runs
# with GitHub's step semantics.
python3 tools/ci_local.py selftest
- name: Every runner job installs through apt-install.sh
shell: bash
run: |
set -eu
# A bare apt-get waits on a stalled mirror until the job is
# cancelled, and fetches every package again each run.
python3 tools/ci_apt_check.py --selftest
python3 tools/ci_apt_check.py
- name: Every workflow's paths filter names the samples it runs
shell: bash
run: |
set -eu
# A workflow skips a push that touches only samples it does not
# build or run; a step that starts naming another sample, or a
# sample's files that start reaching into another, leave the
# filter written by tools/ci_paths.py out of date.
python3 tools/ci_paths.py --check
- name: compile_commands.py self-test
shell: bash
run: |
set -eu
python3 tools/compile_commands.py --selftest
- name: A checker workflow, run through the runner
shell: bash
run: |
set -eu
python3 tools/ci_local.py run Extern-C-Prototype-Check
+38 -42
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Compile-Matrix.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Compile-Matrix.yml'
# ci_paths: end
permissions:
contents: read
@@ -29,39 +17,47 @@ concurrency:
jobs:
compile-matrix: # every codec combination real builds select, not just this one
# Ubuntu 26.04 ships no MIPS cross toolchain; the mipsel lanes
# need 24.04's gcc-mipsel-linux-gnu.
runs-on: ubuntu-24.04
env:
APT_PKGS: build-essential libgl-dev libegl-dev libgles-dev libsdl1.2-dev gcc-mingw-w64-x86-64 clang gcc-aarch64-linux-gnu gcc-mipsel-linux-gnu libdrm-dev libgbm-dev
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 20
run: |
# The gl2 arms compile against the desktop GL and EGL headers,
# and the Dingux and RS90 video drivers against SDL 1.2's.
# The Direct3D and WASAPI lanes cross-compile with mingw-w64.
pkgs="build-essential libgl-dev libegl-dev libgles-dev libsdl1.2-dev gcc-mingw-w64-x86-64 clang gcc-aarch64-linux-gnu gcc-mipsel-linux-gnu"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Compile matrix
run: ./.github/workflows/scripts/compile-matrix.sh
+4 -35
View File
@@ -100,8 +100,6 @@ jobs:
./vfs_seek_contract_test
./vfs_mapped_ptr_test
./vfs_v5_metadata_test
./vfs_readahead_test
./vfs_close_result_test
}
# Mapping on (what the platform actually ships), mapping off
# with the descriptor path forced (what the consoles have),
@@ -143,34 +141,14 @@ jobs:
steps:
- uses: actions/checkout@v5
# The system upgrade runs in the action: an msys2-runtime update
# kills every MSYS2 process, which a run step's own shell would
# not survive.
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
update: true
- name: Install packages
shell: msys2 {0}
run: |
# A mirror that stalls or rate-limits (HTTP 429) fails pacman's
# whole transaction; what it fetched stays in the cache, so a
# retry fetches only the rest, one file at a time after a
# growing wait so a shared runner's rate limit can clear.
# pacman waits out a slow mirror instead of aborting;
# timeout-minutes bounds a hang.
p=$MINGW_PACKAGE_PREFIX
pkgs="base-devel $p-toolchain"
for i in 1 2 3 4 5; do
pacman -S --noconfirm --needed --disable-download-timeout $pkgs &&
exit 0
[ $i = 5 ] && break
echo "package install failed (attempt $i); retrying in $((30 * i))s, serial downloads"
sed -i -e '/^#*ParallelDownloads/d' -e '/^\[options\]/a ParallelDownloads = 1' /etc/pacman.conf
sleep $((30 * i))
done
exit 1
install: >-
base-devel
pacboy: >-
toolchain:p
- name: Build and run
working-directory: libretro-common/samples/file/vfs
@@ -197,15 +175,6 @@ jobs:
# Exercises the Win32 CreateFileMapping/MapViewOfFile
# backend, which no other job in the tree reaches.
./vfs_mapped_ptr_test.exe
# Mapped read-ahead: PrefetchVirtualMemory, the pre-Windows 8
# toucher thread (forced) and neither.
./vfs_readahead_test.exe
RETRO_VFS_PREFETCH=touch ./vfs_readahead_test.exe
RETRO_VFS_PREFETCH=none ./vfs_readahead_test.exe
# ... and never on, or stalling, the reader's thread.
./vfs_prefetch_offthread_test.exe
# The descriptor path's close() result, with PS2's semantics.
./vfs_close_result_test.exe
# The Win64 fastjmp_set stores xmm6-xmm15 with movaps and faults
# on a misaligned buffer. Linux has no such stores, so the Linux
+2 -17
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Ctx-Presentable-Check.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Ctx-Presentable-Check.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -38,9 +26,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checker self-test
shell: bash
run: |
@@ -48,7 +33,7 @@ jobs:
# Fixture pass: a correct driver is clean, a presentable()
# casting another driver's context type is flagged, and one
# that is defined but never wired into the vtable is flagged.
tools/check.sh tools/ctx_presentable_check.c --selftest
python3 tools/ctx_presentable_check.py --selftest
- name: Tree check
shell: bash
@@ -58,4 +43,4 @@ jobs:
# presentable() that casts the wrong driver's type, or that is
# never wired in, is invisible to every other job. This is the
# check that sees all of them at once.
tools/check.sh tools/ctx_presentable_check.c
python3 tools/ctx_presentable_check.py
+2 -60
View File
@@ -3,23 +3,7 @@ name: CI DOS/DJGPP
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/DOS-DJGPP.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/DOS-DJGPP.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,57 +23,15 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-djgpp-build-container:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Set up ccache
run: |
# Best effort: without ccache, ccache-make.sh runs plain make.
command -v ccache > /dev/null || {
s=$(command -v sudo || true)
for i in 1 2 3; do
$s timeout 90 apt-get -yq update \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 &&
$s timeout 120 apt-get -yq install --no-install-recommends \
ccache > /dev/null && break
echo "installing ccache failed (attempt $i); retrying in 10s"
sleep 10
done
}
echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> "$GITHUB_ENV"
echo "CCACHE_MAXSIZE=250M" >> "$GITHUB_ENV"
if command -v ccache > /dev/null; then
CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" ccache -z
fi
- name: Compile RA
run: |
make -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) clean
bash .github/workflows/scripts/ccache-make.sh -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv || ccache -s
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
make -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
- name: Get short SHA
id: slug
+1 -17
View File
@@ -3,23 +3,7 @@ name: CI Emscripten
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Emscripten.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Emscripten.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-emscripten:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
+2 -17
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Extern-C-Prototype-Check.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Extern-C-Prototype-Check.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -38,9 +26,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checker self-test
shell: bash
run: |
@@ -49,7 +34,7 @@ jobs:
# with a parameter more than its prototype (the shape of the
# 0b2613d Xbox boot crash) is flagged, and a parameter of
# another type is flagged.
tools/check.sh tools/extern_c_prototype_check.c --selftest
python3 tools/extern_c_prototype_check.py --selftest
- name: Tree check
shell: bash
@@ -60,4 +45,4 @@ jobs:
# never checked against the prototype by any compiler: the
# linker matches on the name alone. This is the check that
# compares the two, for every such definition in the tree.
tools/check.sh tools/extern_c_prototype_check.c
python3 tools/extern_c_prototype_check.py
-19
View File
@@ -15,23 +15,7 @@ name: CI FreeBSD
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/FreeBSD.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/FreeBSD.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -51,9 +35,6 @@ jobs:
- name: Check Out Repo
uses: actions/checkout@v4
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build in FreeBSD
uses: vmactions/freebsd-vm@v1
with:
+3 -62
View File
@@ -3,23 +3,7 @@ name: CI GameCube
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/GameCube.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/GameCube.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -38,56 +22,13 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: devkitpro/devkitppc:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
image: reallibretroretroarch/libretro-build-devkitpro:latest
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Set up ccache
run: |
# Best effort: without ccache, ccache-make.sh runs plain make.
command -v ccache > /dev/null || {
s=$(command -v sudo || true)
for i in 1 2 3; do
$s timeout 90 apt-get -yq update \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 &&
$s timeout 120 apt-get -yq install --no-install-recommends \
ccache > /dev/null && break
echo "installing ccache failed (attempt $i); retrying in 10s"
sleep 10
done
}
echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> "$GITHUB_ENV"
echo "CCACHE_MAXSIZE=250M" >> "$GITHUB_ENV"
if command -v ccache > /dev/null; then
CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" ccache -z
fi
- name: Compile RA
run: |
make -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) clean
bash .github/workflows/scripts/ccache-make.sh -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv || ccache -s
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
make -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1 info all
+34 -75
View File
@@ -4,25 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-Headless.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-Headless.yml'
# ci_paths: end
permissions:
contents: read
@@ -37,70 +21,45 @@ concurrency:
jobs:
linux-nomenu: # Smoketest build with no menu support compiled in
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libxkbcommon-dev libx11-xcb-dev zlib1g-dev libfreetype-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev nvidia-cg-toolkit nvidia-cg-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm ccache
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 20
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev zlib1g-dev libfreetype6-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev nvidia-cg-toolkit nvidia-cg-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
- name: Configure
run: ./configure --disable-menu
- name: Build
run: make
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-104
View File
@@ -1,104 +0,0 @@
name: CI Linux (aarch64, OpenXR)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-aarch64.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-aarch64.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
workflow_dispatch:
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-24.04-arm
timeout-minutes: 30
env:
APT_PKGS: >-
build-essential pkg-config
libwayland-dev wayland-protocols libxkbcommon-dev libdecor-0-dev
libx11-dev libxext-dev libxrandr-dev libxinerama-dev libxxf86vm-dev
libxi-dev libx11-xcb-dev libxcb1-dev
libegl-dev libgl-dev libgles-dev libgbm-dev libdrm-dev libvulkan-dev
libasound2-dev libpulse-dev libpipewire-0.3-dev
libudev-dev libusb-1.0-0-dev libdbus-1-dev libsystemd-dev
libfreetype-dev libfontconfig-dev zlib1g-dev libsdl2-dev libv4l-dev
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Configure
run: |
./configure --disable-qt --disable-ffmpeg --disable-cg --enable-openxr
grep -q '^HAVE_OPENXR = 1' config.mk
grep -q '^HAVE_XSCRNSAVER = 1' config.mk
- name: Compile RA
run: make -j$(getconf _NPROCESSORS_ONLN)
- name: Check and strip
run: |
./retroarch --version
if readelf -d retroarch | grep -q 'libXss'; then
echo 'retroarch must load libXss at run time, not link it'
exit 1
fi
strip retroarch
- name: Get short SHA
id: slug
run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
with:
name: retroarch-linux-aarch64-${{ steps.slug.outputs.sha8 }}
path: retroarch
if-no-files-found: error
+44 -74
View File
@@ -40,25 +40,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-asan-ubsan.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-asan-ubsan.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -75,56 +59,56 @@ jobs:
asan-ubsan:
name: Build with ASan+UBSan and run headless smoke
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev nvidia-cg-toolkit nvidia-cg-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm ccache
timeout-minutes: 25
steps:
- name: Install dependencies
# Mirrors Linux-Headless.yml's apt set so the build matches a
# known-good headless configuration. Adds:
# xvfb / x11-utils -- virtual X server for the imageviewer
# smoke step + xdpyinfo for diagnostics
# libsdl2-dev (already in the base set) provides the SDL2
# video driver used by that smoke -- see the smoke step's
# comment for why SDL2 over xvideo. No sanitizer-specific
# packages required; libasan / libubsan ship with the gcc
# that ubuntu-latest has installed by default.
timeout-minutes: 20
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev nvidia-cg-toolkit nvidia-cg-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
- name: Configure (no menu, no discord/cheevos/networking, sdl2 on)
# Trim the build surface for the first iteration so any
# sanitizer hit is a RetroArch-internal bug rather than noise
@@ -477,17 +461,3 @@ jobs:
fi
test -s /tmp/lsan-shots/exit.png
echo "[pass] screenshot on exit, no leaks outside the system libraries"
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -3,20 +3,8 @@ name: CI Linux native audio transport
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-audio-transport.yml'
# ci_paths: end
pull_request:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-audio-transport.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -36,9 +24,6 @@ jobs:
sanitizer: ['', 'address,undefined']
steps:
- uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build the shipping frontend and real audio wrapper fixture
working-directory: samples/audio/pipeline_wakeups
run: make clean all SANITIZER='${{ matrix.sanitizer }}'
@@ -78,51 +63,3 @@ jobs:
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: make check-auto SANITIZER='${{ matrix.sanitizer }}'
- name: A device's lend reached through the real wrapper
working-directory: samples/audio/pipeline_wakeups
env:
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: make check-lend SANITIZER='${{ matrix.sanitizer }}'
- name: Pause boundary on the real wrapper
working-directory: samples/audio/pipeline_wakeups
env:
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: make check-pause SANITIZER='${{ matrix.sanitizer }}'
- name: Fast-forward stall on the real wrapper
working-directory: samples/audio/pipeline_wakeups
env:
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: make check-ff-stall SANITIZER='${{ matrix.sanitizer }}'
- name: Consumer leaving under a parked producer
working-directory: samples/audio/pipeline_wakeups
env:
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: make check-consumer-exit SANITIZER='${{ matrix.sanitizer }}'
- name: Device kept stopped across a rebuild
working-directory: samples/audio/pipeline_wakeups
env:
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: make check-kept-device SANITIZER='${{ matrix.sanitizer }}'
- name: Menu mixer continues without frame submissions
working-directory: samples/audio/pipeline_wakeups
env:
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: make check-menu SANITIZER='${{ matrix.sanitizer }}'
- name: Consumer leaving and a kept device (ThreadSanitizer)
if: matrix.sanitizer == ''
working-directory: samples/audio/pipeline_wakeups
env:
TSAN_OPTIONS: halt_on_error=1 second_deadlock_stack=1
run: |
# Last: it rebuilds the fixture instrumented. The lanes are the
# pipe_consumer_gone handshake and a stopped wrapper beside the
# state rebuilt under it, which only the race detector can judge.
make clean
make check-consumer-exit check-kept-device check-menu check-ff-stall \
SANITIZER=thread
+37 -72
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-autoconf-tests.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-autoconf-tests.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -35,8 +23,6 @@ jobs:
autoconf-tests:
name: Build and run the autoconfig regression suite (${{ matrix.lane }})
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential zlib1g-dev libfreetype-dev ccache
timeout-minutes: ${{ matrix.sanitizer == '' && 15 || 40 }}
strategy:
fail-fast: false
@@ -53,50 +39,43 @@ jobs:
sanitizer: thread
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ strategy.job-index }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-${{ strategy.job-index }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
pkgs="build-essential zlib1g-dev libfreetype6-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure (headless, test drivers)
run: |
@@ -112,7 +91,7 @@ jobs:
- name: Build
run: |
if [ -n "${{ matrix.sanitizer }}" ]; then
CFLAGS="-O0 -g1" CXXFLAGS="-O0 -g1" make -j"$(nproc)" SANITIZER=${{ matrix.sanitizer }} DEBUG=1
make -j"$(nproc)" SANITIZER=${{ matrix.sanitizer }} DEBUG=1
else
make -j"$(nproc)"
fi
@@ -125,21 +104,7 @@ jobs:
if [ "${{ matrix.sanitizer }}" = thread ]; then
# TSan cannot map its shadow under the runner's ASLR
# entropy; setarch -R carries to every child the suite runs.
setarch "$(uname -m)" -R ./samples/input/test_input/test_autoconf.sh ./retroarch
setarch "$(uname -m)" -R ./tests-other/test_autoconf.sh ./retroarch
else
./samples/input/test_input/test_autoconf.sh ./retroarch
./tests-other/test_autoconf.sh ./retroarch
fi
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ strategy.job-index }}-${{ github.sha }}
-74
View File
@@ -1,74 +0,0 @@
name: CI CDFS sector I/O
on:
push:
branches: [master]
paths:
- 'libretro-common/formats/cdfs/**'
- 'libretro-common/include/formats/cdfs.h'
- 'libretro-common/samples/formats/cdfs/**'
- 'cheevos/cheevos.c'
- '.github/workflows/Linux-cdfs-io.yml'
pull_request:
branches: [master]
paths:
- 'libretro-common/formats/cdfs/**'
- 'libretro-common/include/formats/cdfs.h'
- 'libretro-common/samples/formats/cdfs/**'
- 'cheevos/cheevos.c'
- '.github/workflows/Linux-cdfs-io.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
cdfs:
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential gcc-mingw-w64-x86-64 wine64
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 15
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: Linux sectors and faults
working-directory: libretro-common/samples/formats/cdfs
run: |
set -eu
make -j2 SANITIZER=address,undefined SAMPLE_OBJDIR=obj-ci-asan
./cdfs_dir_record_test
./cdfs_pure_api_test
./cdfs_io_error_test
env:
ASAN_OPTIONS: detect_leaks=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
- name: Windows sectors and faults
working-directory: libretro-common/samples/formats/cdfs
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make -j2 CC=x86_64-w64-mingw32-gcc OS=Windows_NT EXE=.exe SAMPLE_OBJDIR=obj-ci-win
WINEDEBUG=-all wine ./cdfs_dir_record_test.exe
WINEDEBUG=-all wine ./cdfs_pure_api_test.exe
WINEDEBUG=-all wine ./cdfs_io_error_test.exe
+7 -51
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-driver-vtables.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-driver-vtables.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -35,52 +23,20 @@ jobs:
driver-vtables:
name: Every driver against its interface
runs-on: ubuntu-latest
env:
APT_PKGS: --no-install-recommends build-essential libasound2-dev libpulse-dev libjack-jackd2-dev libopenal-dev libpipewire-0.3-dev libsdl2-dev
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Check no input driver's table outgrows the structure
shell: bash
run: |
set -eu
# The step below compiles the drivers Linux can. The UWP,
# Cocoa and console input drivers are not among them, and a
# table with one entry more than struct input_driver has
# members is only a warning to gcc anyway - and C2078, a
# failed build, to MSVC. That reached master for the UWP
# driver. This counts the entries of every input driver's
# table in the source, whatever SDK the driver needs.
tools/check.sh tools/input_driver_table_check.c --selftest
tools/check.sh tools/input_driver_table_check.c
sudo apt-get update -qq
sudo apt-get install -y -qq --no-install-recommends \
build-essential libasound2-dev libpulse-dev libjack-jackd2-dev \
libopenal-dev libpipewire-0.3-dev libsdl2-dev
- name: Checkout
uses: actions/checkout@v5
- name: Compile each driver against its interface
shell: bash
-88
View File
@@ -1,88 +0,0 @@
name: CI optical DVD blocks
on:
push:
branches: [master]
paths:
- 'tasks/task_content_disc.c'
- 'libretro-common/cdrom/**'
- 'libretro-common/vfs/**'
- 'libretro-common/include/cdrom/**'
- 'libretro-common/include/vfs/**'
- 'libretro-common/samples/file/vfs_cdrom/**'
- '.github/workflows/Linux-dvd-blocks.yml'
pull_request:
branches: [master]
paths:
- 'tasks/task_content_disc.c'
- 'libretro-common/cdrom/**'
- 'libretro-common/vfs/**'
- 'libretro-common/include/cdrom/**'
- 'libretro-common/include/vfs/**'
- 'libretro-common/samples/file/vfs_cdrom/**'
- '.github/workflows/Linux-dvd-blocks.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
blocks:
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential gcc-mingw-w64-x86-64 wine64
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 15
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: Linux commands and VFS
working-directory: libretro-common/samples/file/vfs_cdrom
run: |
set -eu
make -j2 dvd_blocks_test SANITIZER=address,undefined SAMPLE_OBJDIR=obj-dvd-asan
./dvd_blocks_test
make -j2 disc_dump_test SANITIZER=address,undefined SAMPLE_OBJDIR=obj-dvd-asan
./disc_dump_test
make -j2 vfs_close_test SANITIZER=address,undefined SAMPLE_OBJDIR=obj-dvd-asan
./vfs_close_test
make -j2 macos_command_test SANITIZER=address,undefined SAMPLE_OBJDIR=obj-dvd-asan
./macos_command_test
make -j2 SANITIZER=address,undefined SAMPLE_OBJDIR=obj-dvd-asan
./cdrom_cuesheet_overflow_test
env:
ASAN_OPTIONS: detect_leaks=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
- name: Windows commands and VFS
working-directory: libretro-common/samples/file/vfs_cdrom
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make -j2 dvd_blocks_test.exe CC=x86_64-w64-mingw32-gcc OS=Windows_NT EXE=.exe SAMPLE_OBJDIR=obj-dvd-win
WINEDEBUG=-all wine ./dvd_blocks_test.exe
make -j2 disc_dump_test.exe CC=x86_64-w64-mingw32-gcc OS=Windows_NT EXE=.exe SAMPLE_OBJDIR=obj-dvd-win
WINEDEBUG=-all wine ./disc_dump_test.exe
make -j2 vfs_close_test.exe CC=x86_64-w64-mingw32-gcc OS=Windows_NT EXE=.exe SAMPLE_OBJDIR=obj-dvd-win
WINEDEBUG=-all wine ./vfs_close_test.exe
make -j2 macos_command_test.exe CC=x86_64-w64-mingw32-gcc OS=Windows_NT EXE=.exe SAMPLE_OBJDIR=obj-dvd-win
WINEDEBUG=-all wine ./macos_command_test.exe
-135
View File
@@ -1,135 +0,0 @@
name: CI Linux EGL hardware core
# Runs the gl video driver on the X11 EGL context under Xvfb with an
# OpenGL hardware core, and checks that the core was given a context
# and that its frame is what reaches the screen - with threaded video
# on, where the core's context lives on the main thread and cannot be
# bound to the window surface the video thread holds, and with it off.
# Mesa takes the surfaceless path by itself; a preloaded shim hides
# parts of its EGL so the pbuffer paths run too.
on:
push:
branches:
- master
paths:
- 'gfx/common/egl_common.c'
- 'gfx/common/egl_common.h'
- 'gfx/drivers_context/xegl_ctx.c'
- 'gfx/drivers/gl2.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_hw.c'
- 'gfx/video_thread_wrapper.c'
- 'samples/gfx/egl_hw_core/**'
- '.github/workflows/Linux-egl-hw-core.yml'
pull_request:
paths:
- 'gfx/common/egl_common.c'
- 'gfx/common/egl_common.h'
- 'gfx/drivers_context/xegl_ctx.c'
- 'gfx/drivers/gl2.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_hw.c'
- 'gfx/video_thread_wrapper.c'
- 'samples/gfx/egl_hw_core/**'
- '.github/workflows/Linux-egl-hw-core.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
egl-hw-core:
name: Run a GL hardware core on the EGL context under Xvfb
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential zlib1g-dev ccache python3 xvfb libgl1-mesa-dri libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev libxxf86vm-dev libxrandr-dev libxinerama-dev libgl-dev libegl-dev
timeout-minutes: 25
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
- name: Build RetroArch (X11 + OpenGL + EGL, the rest off)
shell: bash
run: |
set -eu
./configure --disable-qt --disable-wayland --disable-sdl \
--disable-sdl2 --disable-ffmpeg --disable-vulkan \
--disable-pulse --disable-discord \
--disable-networking --disable-cheevos \
--disable-glslang --disable-slang \
--disable-spirv_cross --disable-xmb \
--disable-materialui --disable-ozone \
--disable-7zip --disable-flac \
--disable-audiomixer --disable-translate \
--disable-accessibility --disable-crtswitchres \
--disable-langextra --disable-libretrodb \
--disable-video_filter --disable-dsp_filter
grep -q '^HAVE_OPENGL = 1' config.mk
grep -q '^HAVE_EGL = 1' config.mk
grep -q '^HAVE_X11 = 1' config.mk
make -j$(nproc)
ccache -s
- name: Run egl_hw_core_test
shell: bash
run: |
set -eu
make -C samples/gfx/egl_hw_core
timeout 600 python3 samples/gfx/egl_hw_core/egl_hw_core_test.py ./retroarch
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
+1 -28
View File
@@ -9,12 +9,7 @@ name: CI Linux filter plugins
# takes more than one worker must give the single-worker output byte for
# byte with 2, 3 and 4 workers running at once. The same run is repeated
# with the plugins and the harness built under ASan, UBSan and
# LeakSanitizer, and under ThreadSanitizer. The NTSC, 2xBR, NTSC-CRT,
# 2xSaI-family, Phosphor2x, Blargg NTSC SNES, De-Dither, Pixel Art AA,
# Scale2x, Scanline2x, Upscale 1.5x/1.66x and the Normal, Grid, Game Boy
# and Dot Matrix scalers are also held byte for byte to output hashes
# recorded from their earlier implementations
# (samples/gfx/{ntsc,crt}_filter_golden and samples/gfx/filter_golden).
# LeakSanitizer, and under ThreadSanitizer.
on:
push:
@@ -25,9 +20,6 @@ on:
- 'libretro-common/audio/dsp_filters/**'
- 'libretro-common/include/libretro_dspfilter.h'
- 'samples/gfx/filter_plugins/**'
- 'samples/gfx/ntsc_filter_golden/**'
- 'samples/gfx/crt_filter_golden/**'
- 'samples/gfx/filter_golden/**'
- '.github/workflows/Linux-filter-plugins.yml'
pull_request:
paths:
@@ -35,9 +27,6 @@ on:
- 'libretro-common/audio/dsp_filters/**'
- 'libretro-common/include/libretro_dspfilter.h'
- 'samples/gfx/filter_plugins/**'
- 'samples/gfx/ntsc_filter_golden/**'
- 'samples/gfx/crt_filter_golden/**'
- 'samples/gfx/filter_golden/**'
- '.github/workflows/Linux-filter-plugins.yml'
workflow_dispatch:
@@ -58,9 +47,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build the plugins and the harness
run: |
set -eu
@@ -84,19 +70,6 @@ jobs:
make -C samples/gfx/filter_plugins clean
make -C samples/gfx/filter_plugins check SANITIZER=address,undefined
- name: NTSC, 2xBR, NTSC-CRT and 2xSaI-family filter output against their recorded hashes
env:
ASAN_OPTIONS: abort_on_error=1:detect_leaks=1:print_stacktrace=1
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
run: |
set -eu
jobs=$(getconf _NPROCESSORS_ONLN)
for t in ntsc_filter_golden crt_filter_golden filter_golden; do
make -C samples/gfx/$t -j"$jobs" check
make -C samples/gfx/$t clean
make -C samples/gfx/$t -j"$jobs" check SANITIZER=address,undefined
done
- name: Load and run every plugin under ThreadSanitizer
env:
TSAN_OPTIONS: halt_on_error=1
+34 -142
View File
@@ -19,125 +19,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'libretro-common/samples/encodings/rbzip2/**'
- 'samples/runloop/auto_state_load/**'
- 'samples/runloop/autosave_snapshot/**'
- 'samples/runloop/cloudsync_unload/**'
- 'samples/runloop/content_closing/**'
- 'samples/runloop/core_status_defer/**'
- 'samples/runloop/frontend_overhead/**'
- 'samples/runloop/hw_context_request/**'
- 'samples/runloop/log_ring/**'
- 'samples/runloop/pacing/**'
- 'samples/tasks/autodetect_handoff/**'
- 'samples/tasks/bluetooth_scan/**'
- 'samples/tasks/bps_patch/**'
- 'samples/tasks/bsv_checkpoint/**'
- 'samples/tasks/bsv_replay/**'
- 'samples/tasks/bsv_replay_init/**'
- 'samples/tasks/bsv_statestream/**'
- 'samples/tasks/cloudsync/**'
- 'samples/tasks/content_load/**'
- 'samples/tasks/content_prefetch/**'
- 'samples/tasks/core_backup/**'
- 'samples/tasks/core_updater/**'
- 'samples/tasks/database/**'
- 'samples/tasks/decompress/**'
- 'samples/tasks/exit_drain/**'
- 'samples/tasks/file_transfer/**'
- 'samples/tasks/http/**'
- 'samples/tasks/http_emscripten/**'
- 'samples/tasks/image_decode_slice/**'
- 'samples/tasks/input_remap/**'
- 'samples/tasks/natt_desc/**'
- 'samples/tasks/netplay_nat/**'
- 'samples/tasks/ordering/**'
- 'samples/tasks/overlay/**'
- 'samples/tasks/patch_stream/**'
- 'samples/tasks/pl_thumbnail/**'
- 'samples/tasks/playlist_manager/**'
- 'samples/tasks/progress_push/**'
- 'samples/tasks/save_state/**'
- 'samples/tasks/steam_dlc/**'
- 'samples/tasks/subtitle_load/**'
- 'samples/tasks/translation_reply/**'
- 'samples/tasks/turbo_bind/**'
- 'samples/tasks/video_shader_parse/**'
- 'samples/tasks/wait_timeout/**'
- 'samples/tasks/watchdog/**'
- 'samples/tasks/wifi_tasks/**'
- 'samples/runloop/**'
- 'samples/tasks/**'
- 'samples/ui_companion_log_stub.c'
- '.github/workflows/Linux-frontend-overhead.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'libretro-common/samples/encodings/rbzip2/**'
- 'samples/runloop/auto_state_load/**'
- 'samples/runloop/autosave_snapshot/**'
- 'samples/runloop/cloudsync_unload/**'
- 'samples/runloop/content_closing/**'
- 'samples/runloop/core_status_defer/**'
- 'samples/runloop/frontend_overhead/**'
- 'samples/runloop/hw_context_request/**'
- 'samples/runloop/log_ring/**'
- 'samples/runloop/pacing/**'
- 'samples/tasks/autodetect_handoff/**'
- 'samples/tasks/bluetooth_scan/**'
- 'samples/tasks/bps_patch/**'
- 'samples/tasks/bsv_checkpoint/**'
- 'samples/tasks/bsv_replay/**'
- 'samples/tasks/bsv_replay_init/**'
- 'samples/tasks/bsv_statestream/**'
- 'samples/tasks/cloudsync/**'
- 'samples/tasks/content_load/**'
- 'samples/tasks/content_prefetch/**'
- 'samples/tasks/core_backup/**'
- 'samples/tasks/core_updater/**'
- 'samples/tasks/database/**'
- 'samples/tasks/decompress/**'
- 'samples/tasks/exit_drain/**'
- 'samples/tasks/file_transfer/**'
- 'samples/tasks/http/**'
- 'samples/tasks/http_emscripten/**'
- 'samples/tasks/image_decode_slice/**'
- 'samples/tasks/input_remap/**'
- 'samples/tasks/natt_desc/**'
- 'samples/tasks/netplay_nat/**'
- 'samples/tasks/ordering/**'
- 'samples/tasks/overlay/**'
- 'samples/tasks/patch_stream/**'
- 'samples/tasks/pl_thumbnail/**'
- 'samples/tasks/playlist_manager/**'
- 'samples/tasks/progress_push/**'
- 'samples/tasks/save_state/**'
- 'samples/tasks/steam_dlc/**'
- 'samples/tasks/subtitle_load/**'
- 'samples/tasks/translation_reply/**'
- 'samples/tasks/turbo_bind/**'
- 'samples/tasks/video_shader_parse/**'
- 'samples/tasks/wait_timeout/**'
- 'samples/tasks/watchdog/**'
- 'samples/tasks/wifi_tasks/**'
- 'samples/runloop/**'
- 'samples/tasks/**'
- 'samples/ui_companion_log_stub.c'
- '.github/workflows/Linux-frontend-overhead.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -151,38 +35,46 @@ jobs:
linux-frontend-overhead:
name: Release build, frame-path heap and cost
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libxkbcommon-dev libx11-xcb-dev zlib1g-dev libfreetype-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libxml2-dev yasm
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 20
run: sh .github/workflows/scripts/apt-install.sh $APT_PKGS
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev zlib1g-dev libfreetype6-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libxml2-dev yasm"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checkout
uses: actions/checkout@v5
- name: Configure
# Non-Qt, as the harness requires (with Qt, main() lives in
+40 -38
View File
@@ -36,41 +36,52 @@ jobs:
gl1-upload:
name: Run retroarch on gl1 under Xvfb and check the frame
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential zlib1g-dev ccache python3 xvfb libgl1-mesa-dri libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev libxxf86vm-dev libxrandr-dev libxinerama-dev libgl-dev libegl-dev
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
build-essential zlib1g-dev ccache python3 \
xvfb libgl1-mesa-dri \
libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev \
libxxf86vm-dev libxrandr-dev libxinerama-dev \
libgl-dev libegl-dev && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
build-essential zlib1g-dev ccache python3 \
xvfb libgl1-mesa-dri \
libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev \
libxxf86vm-dev libxrandr-dev libxinerama-dev \
libgl-dev libegl-dev
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -83,7 +94,7 @@ jobs:
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build RetroArch (X11 + OpenGL, the rest off)
@@ -112,12 +123,3 @@ jobs:
set -eu
make -C samples/gfx/gl1_upload
timeout 600 python3 samples/gfx/gl1_upload/gl1_upload_test.py ./retroarch
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-104
View File
@@ -1,104 +0,0 @@
name: CI Linux Griffin [Unity build]
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-griffin.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-griffin.yml'
# ci_paths: end
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:
linux-griffin: # griffin/griffin.c as Makefile.griffin builds it for Linux
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libgl-dev libudev-dev libpulse-dev libx11-dev libx11-xcb-dev libxcb1-dev libxxf86vm-dev ccache
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
- name: Build
run: make -f Makefile.griffin platform=unix -j"$(nproc)"
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -13,31 +13,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/network/cheevos_login/**'
- 'samples/network/smb_retro/**'
- 'samples/network/tls_retro/**'
- '.github/workflows/Linux-library-net-backends.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/network/cheevos_login/**'
- 'samples/network/smb_retro/**'
- 'samples/network/tls_retro/**'
- '.github/workflows/Linux-library-net-backends.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -51,8 +29,6 @@ jobs:
library-backends:
name: ${{ matrix.lane }}
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config cmake libgl1-mesa-dev libx11-dev libxext-dev libasound2-dev libsdl2-dev zlib1g-dev libfreetype-dev python3 openssl libmbedtls-dev libbearssl-dev samba ccache
timeout-minutes: 60
strategy:
fail-fast: false
@@ -72,51 +48,17 @@ jobs:
absent: ' T rsmb_connect'
steps:
- name: Dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y build-essential pkg-config cmake \
libgl1-mesa-dev libx11-dev libxext-dev libasound2-dev libsdl2-dev \
zlib1g-dev libfreetype6-dev python3 openssl \
libmbedtls-dev libbearssl-dev samba
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ strategy.job-index }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-${{ strategy.job-index }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
- name: libsmb2 from upstream (no Ubuntu package)
if: matrix.lane == 'libsmb2'
run: |
@@ -159,18 +101,11 @@ jobs:
run: |
set -eu
case "${{ matrix.lane }}" in mbedtls) be=mbed ;; bearssl) be=bear ;; esac
make clean SSL_BACKEND=$be SANITIZER=address,undefined && make -j$(nproc) all SSL_BACKEND=$be SANITIZER=address,undefined
make clean all SSL_BACKEND=$be SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 timeout 120 \
make check SSL_BACKEND=$be
echo "[pass] ${{ matrix.lane }}: cheevos login transport over a local HTTPS server"
# A server that goes silent mid-handshake: the read bound ends it.
make -C ../tls_retro clean SSL_BACKEND=$be && make -C ../tls_retro -j$(nproc) tls_stall SSL_BACKEND=$be
../tls_retro/tls_stall
# A refused certificate reaches the verify hook.
make -C ../tls_retro clean
SSL_BACKEND=$be ../tls_retro/verify_hook_test.sh
make -C ../tls_retro clean
- name: Operate the libsmb2 backend (SMB VFS against a local smbd)
if: matrix.lane == 'libsmb2'
@@ -191,7 +126,7 @@ jobs:
set -eu
cmake -S "$RUNNER_TEMP/libsmb2" -B "$RUNNER_TEMP/libsmb2/build-tsan" \
-DCMAKE_INSTALL_PREFIX=/opt/libsmb2-tsan -DBUILD_SHARED_LIBS=ON \
-DCMAKE_C_FLAGS="-O1 -g1 -fsanitize=thread" \
-DCMAKE_C_FLAGS="-O1 -g -fsanitize=thread" \
-DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=thread" >/dev/null
make -C "$RUNNER_TEMP/libsmb2/build-tsan" -j"$(nproc)" >/dev/null
sudo make -C "$RUNNER_TEMP/libsmb2/build-tsan" install >/dev/null
@@ -199,20 +134,6 @@ jobs:
PKG_CONFIG_PATH=/opt/libsmb2-tsan/lib/pkgconfig \
LD_LIBRARY_PATH=/opt/libsmb2-tsan/lib \
TSAN_OPTIONS="halt_on_error=1 exitcode=66" \
CFLAGS="-O1 -g1 -fsanitize=thread" LDLIBS="-fsanitize=thread" \
CFLAGS="-O1 -g -fsanitize=thread" LDLIBS="-fsanitize=thread" \
WITH_LIBSMB2=1 samples/network/smb_retro/local_samba_test.sh
sudo make -C samples/network/smb_retro clean
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ strategy.job-index }}-${{ github.sha }}
File diff suppressed because it is too large. Load diff
+102 -245
View File
@@ -10,21 +10,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-libretro-common-tests.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-libretro-common-tests.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -40,46 +28,63 @@ concurrency:
jobs:
libretro-common-tests:
name: Build and run libretro-common/Makefile.test
# Ubuntu 26.04 ships no MIPS cross toolchain; the mipsel lanes
# need 24.04's gcc-mipsel-linux-gnu.
runs-on: ubuntu-24.04
env:
APT_PKGS: build-essential check pkg-config zlib1g-dev gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 wine wine64 ffmpeg gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf gcc-mipsel-linux-gnu qemu-user ccache
# The suites and the stack check have grown with the tree; the
# companion harnesses are a job of their own, run beside this one.
timeout-minutes: 30
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
# ffmpeg: tools/companion_thumbs_test.sh builds its video-hover
# fixture (a 2 KB Baseline MP4) with it.
pkgs="build-essential check pkg-config zlib1g-dev lcov gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 wine wine64 ffmpeg gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf gcc-mipsel-linux-gnu qemu-user"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
# mingw and wine are for the Windows A/W configuration matrix
# in Makefile.test. libretro-common selects between the ANSI
# and the wide Win32 entry points three ways and, until these
# were installed, no job built two of them: the ANSI branch
# was compiled by nothing, so nothing noticed when it stopped
# compiling. wine takes it past a build check - an ANSI build
# under wine really does call CreateFileA and
# GetFileAttributesA, so the branch is executed rather than
# merely parsed. Both are optional to the recipe: without
# them it says which tool is missing and passes, so a
# contributor's local run is not blocked.
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -89,10 +94,11 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build and run the unit test suites
@@ -105,8 +111,8 @@ jobs:
WINEPREFIX: "/tmp/wineprefix"
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
# The recipe builds each suite and runs it, in order.
# The recipe builds each suite, runs it, and collects
# coverage, in order -- coverage files collide otherwise.
# Any suite failing to build, or any check failing, or any
# sanitizer report, fails the job.
# 'unit-tests' by name: the default goal of Makefile.test is
@@ -114,9 +120,7 @@ jobs:
# matrix and none of the suites this step exists to run. The
# 'all' target adds the concurrency and I/O samples, whose
# runtime depends on how many processors the runner has.
# COVERAGE=0: nothing here reads the coverage, and collecting
# it instruments every compile and runs lcov once a suite
make -f Makefile.test unit-tests COVERAGE=0 \
make -f Makefile.test unit-tests \
LIBCHECK_CFLAGS="$(pkg-config --cflags check)" \
CFLAGS="$(pkg-config --cflags check)"
echo "[pass] libretro-common unit test suites"
@@ -129,10 +133,6 @@ jobs:
# every lazily set up table or CPU check, first used by
# eight threads at once under TSan
make -f Makefile.test crypto-tsan-check
# the Windows wait tiers - eventcount and condition variable,
# high resolution timer and kernel timeout - as Windows
# binaries under wine
make -f Makefile.test win32-waits-check
- name: Check VFS backend symbol parity
shell: bash
@@ -147,7 +147,7 @@ jobs:
# That is how retro_vfs_file_get_mapped_ptr_impl reached the
# branch broken. This is the same check at source level, for
# free, on Linux.
tools/check.sh tools/vfs_backend_parity.c
python3 tools/vfs_backend_parity.py
- name: Check every command describes itself
shell: bash
@@ -157,70 +157,7 @@ jobs:
# HELP prints command.h's tables, and interfaces that hand the
# commands to a client are generated from them: a command
# added without a description reaches all of those blank.
tools/check.sh tools/command_table_check.c
- name: Check video and input code stay out of each other's state
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# The frontend starts the input driver; a video driver says
# only what kind of window it put up. What is still to be
# moved is listed in the check, file by file, and the lists
# only shrink: a video file that starts naming an input
# driver, or either side taking the other's state, fails.
tools/check.sh tools/input_video_separation_check.c --selftest
tools/check.sh tools/input_video_separation_check.c
- name: Check input drivers ask by name and do not take the frontend's state
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# A driver that needs something from the settings, the run
# loop, the menu or the input frontend asks for it by name;
# it does not take the whole state and pick a field out.
# What is still to be converted is listed in the check, file
# by file with a count, and the counts only go down.
tools/check.sh tools/input_state_grab_check.c --selftest
tools/check.sh tools/input_state_grab_check.c
- name: Check the GL drivers take the hardware ring's fence ahead of the swap
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# Taken after the swap, the fence completes only when a driver
# that queues swaps releases it, and a hardware rendered core
# fast-forwards at the display's rate.
tools/check.sh tools/gl_ring_fence_check.c --selftest
tools/check.sh tools/gl_ring_fence_check.c
- name: Check the GL drivers set their vsync report with the swap interval
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# Set apart, the threaded presenter counts a vsync wait as
# drawing time, or subtracts one that was not made.
tools/check.sh tools/gl_present_vsynced_check.c --selftest
tools/check.sh tools/gl_present_vsynced_check.c
- name: Check a setting's label exists wherever its translations name it
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# The translation files name a label for every string they
# have, in every build. intl/json2h.py copies a row's feature
# guard into them, unless the guard line mentions a
# SETTINGS_DEF pass: that line it drops. A line that mentions
# a pass and still depends on a feature leaves the
# translations naming a label the build does not have, and
# nothing fails until the first translation arrives from
# Crowdin - then every build without the feature does.
tools/check.sh tools/settings_def_guard_check.c --selftest
tools/check.sh tools/settings_def_guard_check.c
python3 tools/command_table_check.py
- name: Check no video driver deletes overlay textures it was lent
shell: bash
@@ -234,7 +171,7 @@ jobs:
# restarted. No runner can run a GL driver, so this is the
# check at source level: every driver with load_textures
# sets, tests and clears its borrowed marker.
tools/check.sh tools/overlay_texture_ownership.c
python3 tools/overlay_texture_ownership.py
- name: Check overlay setters refuse an image the driver does not hold
shell: bash
@@ -248,116 +185,7 @@ jobs:
# set_alpha; D3D, Vulkan and Metal had no check at all. No
# runner can run these drivers, so this is the check at
# source level for the ones that have been audited.
tools/check.sh tools/overlay_setter_bounds.c
- name: WDM-KS ABI against the system ks.h
shell: bash
working-directory: samples/audio/wdmks_abi
run: |
set -eu
# audio/common/wdmks_ks.h declares the kernel-streaming
# interface the WDM-KS driver uses, because ks.h and
# ksmedia.h ship with the driver kit rather than the
# Platform SDK and not every toolchain here has them.
#
# That is only safe while what is declared matches what the
# system declares. A wrong layout does not fail to build and
# does not misbehave visibly: it hands the kernel a structure
# whose fields are in the wrong places. So this compiles ours
# beside the real headers and asserts every size, every field
# offset, every constant and the IOCTL code, on both word
# sizes, and in C89 as well as gnu99.
#
# It has already earned it. KSDATAFORMAT is a union with a
# LONGLONG that aligns it to eight; declared as the plain
# struct it resembles, KSDATARANGE_AUDIO came out 84 bytes
# against 88 and every field past the first would have been
# read four bytes off.
make check
echo "[pass] wdmks_abi"
- name: Check stack frame budget
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# PSP and GX threads get 8 KiB of stack (STACKSIZE in
# rthreads/psp_pthread.h and rthreads/gx_pthread.h). Nothing
# warns when a local buffer outgrows that: it builds
# everywhere and overflows only on a target most contributors
# cannot build. config_file_write() carried a 16 KiB stdio
# buffer as a local - twice that stack - on a path reached
# from a task handler, and nothing noticed.
python3 tools/stack_budget.py
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
companion-tests:
name: Companion regression tests
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config zlib1g-dev ffmpeg ccache gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 gobjc gnustep-devel gnustep-back-common xvfb wine
# beside the suites, not after them: together they took twice as
# long as either
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
python3 tools/overlay_setter_bounds.py
- name: Check companion backend feature parity
shell: bash
@@ -369,7 +197,7 @@ jobs:
# a feature (no file browser, no scan, no core picker) and still
# build and run, the gap only showing when a user switches
# drivers. Source-level check, for free, on Linux.
tools/check.sh tools/companion_parity.c
python3 tools/companion_parity.py
- name: Companion thumbnail engine regression test (plain, TSan, ASan)
shell: bash
@@ -410,6 +238,7 @@ jobs:
# (the host gcc has no <windows.h>, which used to make the
# pass skip it silently - that is how mixed declarations
# reached master).
sudo apt-get install -y -qq gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 > /dev/null
tools/mingw_syntax_check.sh ui/drivers/ui_win32_companion.c \
ui/companion/companion_core.c ui/companion/companion_thumbs.c \
ui/companion/companion_dock.c \
@@ -425,6 +254,7 @@ jobs:
# core and the core test's fixtures, driven under Xvfb the way a
# user drives it (view popup, File Browser tab, close) and
# checked on the AppKit objects themselves.
sudo apt-get install -y -qq gobjc gnustep-devel gnustep-back-common xvfb > /dev/null
tools/companion_cocoa_test.sh
# ASan too: the grid's prefetch reaching past the thumbnail
# marks only shows under a checking allocator (it crashed the
@@ -440,18 +270,45 @@ jobs:
# linked with the real companion core and the core test's
# fixtures, run under Wine on Xvfb and driven with the messages
# the widgets send; checked on the real controls.
sudo apt-get install -y -qq gcc-mingw-w64-x86-64 wine xvfb > /dev/null
tools/companion_win32_test.sh
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: WDM-KS ABI against the system ks.h
shell: bash
working-directory: samples/audio/wdmks_abi
run: |
set -eu
# audio/common/wdmks_ks.h declares the kernel-streaming
# interface the WDM-KS driver uses, because ks.h and
# ksmedia.h ship with the driver kit rather than the
# Platform SDK and not every toolchain here has them.
#
# That is only safe while what is declared matches what the
# system declares. A wrong layout does not fail to build and
# does not misbehave visibly: it hands the kernel a structure
# whose fields are in the wrong places. So this compiles ours
# beside the real headers and asserts every size, every field
# offset, every constant and the IOCTL code, on both word
# sizes, and in C89 as well as gnu99.
#
# It has already earned it. KSDATAFORMAT is a union with a
# LONGLONG that aligns it to eight; declared as the plain
# struct it resembles, KSDATARANGE_AUDIO came out 84 bytes
# against 88 and every field past the first would have been
# read four bytes off.
make check
echo "[pass] wdmks_abi"
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
- name: Check stack frame budget
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# PSP and GX threads get 8 KiB of stack (STACKSIZE in
# rthreads/psp_pthread.h and rthreads/gx_pthread.h). Nothing
# warns when a local buffer outgrows that: it builds
# everywhere and overflows only on a target most contributors
# cannot build. config_file_write() carried a 16 KiB stdio
# buffer as a local - twice that stack - on a path reached
# from a task handler, and nothing noticed.
python3 tools/stack_budget.py
+38 -56
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-libretro-db-samples.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-libretro-db-samples.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -35,41 +23,49 @@ jobs:
samples:
name: Build and run libretro-db/samples
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential zlib1g-dev ccache
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential zlib1g-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -79,10 +75,11 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build and run samples
@@ -105,7 +102,6 @@ jobs:
# failure. These are built AND executed.
declare -a RUN_TARGETS=(
rmsgpack_overflow_test
rmsgpack_window_test
libretrodb_leak_test
)
@@ -214,17 +210,3 @@ jobs:
if [[ $fails -gt 0 ]]; then
exit 1
fi
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-97
View File
@@ -1,97 +0,0 @@
name: CI Linux MCP over stdio
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-mcp-stdio.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-mcp-stdio.yml'
# ci_paths: end
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
mcp-stdio:
name: retroarch --mcp-stdio driving a core
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config zlib1g-dev libfreetype-dev python3 ccache
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build RetroArch and the views test core
shell: bash
run: |
set -eu
./configure --disable-qt --disable-ffmpeg --disable-vulkan \
--disable-wayland --disable-x11 --disable-opengl
grep -q '^HAVE_MCP = 1' config.mk
make -j"$(nproc)" CC="ccache gcc" CXX="ccache g++"
make -C samples/cores/video_views
# a core that maps memory, for the tools that read it
gcc -O1 -shared -fPIC -Ilibretro-common/include \
-o samples/network/command_frames/harness_core.so \
samples/network/command_frames/harness_core.c
# and one that maps none, handing its RAM over as snes9x does
gcc -O1 -shared -fPIC -DHARNESS_NO_MAP -Ilibretro-common/include \
-o samples/network/command_frames/harness_core_nomap.so \
samples/network/command_frames/harness_core.c
- name: Command-line command errors and delivery
run: python3 samples/network/command_frames/cli_e2e.py ./retroarch
- name: MCP over stdin and stdout, end to end
shell: bash
run: |
set -eu
# null drivers: no display on the runner
timeout 300 python3 samples/network/mcp_server/stdio_e2e.py \
./retroarch samples/cores/video_views/video_views_libretro.so \
samples/network/command_frames/harness_core.so \
samples/network/command_frames/harness_core_nomap.so
+38 -207
View File
@@ -22,20 +22,12 @@ on:
- 'playlist.h'
- 'tasks/task_content*'
- 'samples/menu/playlist_nav/**'
- 'samples/network/command_frames/**'
- 'samples/menu/nav_repeat_stall/**'
- 'samples/menu/mouse_click/**'
- 'samples/menu/menu_icon_ownership/**'
- 'samples/menu/ozone_sublabel_scroll/**'
- 'gfx/gfx_display.c'
- 'runloop.c'
- 'samples/menu/network_settings/**'
- 'intl/msg_hash_lbl.h'
- 'msg_hash_lbl_str.h'
- 'samples/menu/resolution_reset/**'
- 'samples/menu/setting_command/**'
- 'samples/menu/core_info_page/**'
- 'samples/menu/load_content_filter/**'
- 'samples/settings/packed_rows/**'
- 'setting_list.h'
- 'gfx/video_defines.h'
@@ -47,20 +39,12 @@ on:
- 'playlist.h'
- 'tasks/task_content*'
- 'samples/menu/playlist_nav/**'
- 'samples/network/command_frames/**'
- 'samples/menu/nav_repeat_stall/**'
- 'samples/menu/mouse_click/**'
- 'samples/menu/menu_icon_ownership/**'
- 'samples/menu/ozone_sublabel_scroll/**'
- 'gfx/gfx_display.c'
- 'runloop.c'
- 'samples/menu/network_settings/**'
- 'intl/msg_hash_lbl.h'
- 'msg_hash_lbl_str.h'
- 'samples/menu/resolution_reset/**'
- 'samples/menu/setting_command/**'
- 'samples/menu/core_info_page/**'
- 'samples/menu/load_content_filter/**'
- 'samples/settings/packed_rows/**'
- 'setting_list.h'
- 'gfx/video_defines.h'
@@ -75,41 +59,49 @@ jobs:
menu-harness:
name: Build and run the menu navigation harness
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential zlib1g-dev ccache
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential zlib1g-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -119,10 +111,11 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build RetroArch headless
@@ -168,23 +161,6 @@ jobs:
./samples/runloop/content_closing/content_closing_test
make -C samples/runloop/content_closing clean
- name: Build and run cloudsync_unload_test
shell: bash
run: |
set -eu
# Closing content with Cloud Sync in automatic mode asks for
# a sync; it has to start once the content's save RAM is on
# disk and no core owns the file, which a close from the
# menu reaches a frame or more later. The real retroarch.c,
# a core with save RAM, and task_push_cloud_sync wrapped at
# link time to record what the save file held when the sync
# was asked for. No server is contacted.
#
# Shares the non-Qt build made above.
samples/runloop/cloudsync_unload/build.sh
./samples/runloop/cloudsync_unload/cloudsync_unload_test
make -C samples/runloop/cloudsync_unload clean
- name: Build and run menu_playlist_nav_test
shell: bash
run: |
@@ -224,61 +200,6 @@ jobs:
./samples/menu/nav_repeat_stall/menu_nav_repeat_stall_test
make -C samples/menu/nav_repeat_stall clean
- name: Build and run menu_icon_ownership_test
shell: bash
run: |
set -eu
# Every texture handle the menu drivers hold, accounted for
# against a counting null driver: a handle unloaded twice or
# still live at deinit fails the lane. Ozone's sidebar wrote
# the shared cursor texture into a playlist node whose own
# icon had not landed, and the context destroy then freed the
# cursor twice - a heap-corruption crash at startup under
# threaded video. MaterialUI's playlist icon array could be
# rebuilt under a decode still in flight. The contentless
# cores list's icons, fallback and per core, go at deinit.
# Shares the non-Qt build made above; one binary, one run per
# lane.
samples/menu/menu_icon_ownership/build.sh
./samples/menu/menu_icon_ownership/menu_icon_ownership_test ozone
./samples/menu/menu_icon_ownership/menu_icon_ownership_test xmb
./samples/menu/menu_icon_ownership/menu_icon_ownership_test materialui
./samples/menu/menu_icon_ownership/menu_icon_ownership_test contentless
make -C samples/menu/menu_icon_ownership clean
- name: Build and run ozone_sublabel_scroll_test
shell: bash
run: |
set -eu
# Ozone with sublabels on the selected entry only: a selection
# change asking for no animation moves the list at once, an
# animated one tweens and fades the cursor once, the list
# behind the sidebar follows a new selection, and a selection
# past the end is not taken for a new one on every compute.
# Shares the non-Qt build made above.
samples/menu/ozone_sublabel_scroll/build.sh
./samples/menu/ozone_sublabel_scroll/ozone_sublabel_scroll_test
make -C samples/menu/ozone_sublabel_scroll clean
- name: Build and run menu_mouse_click_test
shell: bash
run: |
set -eu
# A left click in the menu has to select the entry under the
# pointer. The pen support gave every pointer that is not a
# touchscreen no gesture on release, and a mouse's left click
# reaches the menu drivers as a tap gesture, so the click was
# thrown away in every menu driver while movement, the wheel
# and the right button kept working. Drives the real runloop
# with a scripted mouse: points at Settings by asking the menu
# which entry is under the pointer, opens it with a left
# click, scrolls its list with the wheel, goes back with a
# right click, and checks a long press is not a click. Shares
# the non-Qt build made above.
samples/menu/mouse_click/build.sh
./samples/menu/mouse_click/menu_mouse_click_test
make -C samples/menu/mouse_click clean
- name: Build and run menu_network_settings_test
shell: bash
run: |
@@ -320,19 +241,6 @@ jobs:
./samples/settings/packed_rows/packed_rows_test
make -C samples/settings/packed_rows clean
- name: Build and run setting_command_test
shell: bash
run: |
set -eu
# A press on a settings row whose command reinitialises the
# video driver has to bring the driver up once, on the first
# press and on every later one, whether or not the row
# applies its command by itself. Shares the non-Qt build
# made above.
samples/menu/setting_command/build.sh
./samples/menu/setting_command/setting_command_test
make -C samples/menu/setting_command clean
- name: Hot function budget
shell: bash
run: |
@@ -355,12 +263,6 @@ jobs:
# build has no Vulkan, so the Vulkan entries report SKIP.
tools/lock_acquire_budget.sh
- name: Wait budget
run: |
# Main-thread waits on the video thread, per file, against
# tools/wait_budget.ref: a count that only comes down.
tools/wait_budget.sh
- name: Build and run threaded_video_test
shell: bash
run: |
@@ -394,49 +296,6 @@ jobs:
./samples/tasks/content_load/content_load_test
make -C samples/tasks/content_load clean
- name: Build and run video_filter_menu_test
shell: bash
run: |
set -eu
# The menu's Video Filter and Video Filter Enable rows get the
# driver the frames they make - a chosen filter's scale and
# format, the core's or the filter's format as Enable turns it
# off and on: told in place to a driver that takes it
# (set_frame_format), set up again otherwise, and nothing at
# all when the frames do not change.
samples/gfx/video_filter_menu/build.sh
./samples/gfx/video_filter_menu/video_filter_menu_test
# Under the threaded wrapper too: a filter swapped without
# waiting for the video thread, the old one freed behind the
# frames staged with it
HARNESS_THREADED=1 ./samples/gfx/video_filter_menu/video_filter_menu_test
make -C samples/gfx/video_filter_menu clean
- name: Build and run core_info_page_test
shell: bash
run: |
set -eu
# The running core's information - its current-core entry,
# Core Information in the Information menu and the page
# itself - comes from its info file, once it is up and again
# after the drivers are set up again under it.
samples/menu/core_info_page/build.sh
./samples/menu/core_info_page/core_info_page_test
make -C samples/menu/core_info_page clean
- name: Build and run load_content_filter_test
shell: bash
run: |
set -eu
# Load Content with no core lists every file an installed core
# or a built-in player opens, however long the installed cores'
# extensions run together. Content Scan's Content Location
# lists files and folders, and Import Content offers Content
# Scan alone.
samples/menu/load_content_filter/build.sh
./samples/menu/load_content_filter/load_content_filter_test
make -C samples/menu/load_content_filter clean
- name: Build and run explore_build_test
shell: bash
run: |
@@ -447,31 +306,3 @@ jobs:
samples/menu/explore_build/build.sh
./samples/menu/explore_build/explore_build_test
make -C samples/menu/explore_build clean
- name: Frame command progress through the real runloop
shell: bash
run: |
set -eu
make -C samples/network/command_frames check
make -C samples/network/command_frames clean
- name: Structured HDR queries through the real frontend
shell: bash
run: |
set -eu
make -j$(nproc)
python3 samples/gfx/hdr_metadata/live.py --retroarch ./retroarch --log-dir /tmp/hdr-metadata-live
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-258
View File
@@ -1,258 +0,0 @@
name: CI fullscreen media menu
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-menu-media.yml'
# ci_paths: end
pull_request:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-menu-media.yml'
# ci_paths: end
workflow_dispatch:
permissions:
contents: read
jobs:
rgui-media:
runs-on: ubuntu-latest
env:
APT_PKGS: ffmpeg
timeout-minutes: 20
strategy:
matrix:
threads: [enable, disable]
steps:
- uses: actions/checkout@v6
- 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 dependencies
timeout-minutes: 10
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: Configure C89 frontend
run: ./configure --disable-qt --disable-vulkan --disable-wayland --disable-x11 --disable-opengl --disable-opengl1 --disable-opengl_core --disable-ffmpeg --disable-cheevos --disable-webmplayer --${{ matrix.threads }}-threads
- name: Build shipping frontend
run: make -j2 C89_BUILD=1
- name: Generate movie fixture
run: ffmpeg -v error -y -f lavfi -i testsrc2=size=320x240:rate=30 -f lavfi -i sine=frequency=440:sample_rate=48000 -t 3 -c:v libx264 -preset ultrafast -pix_fmt yuv420p -c:a aac -shortest samples/menu/rgui_media/fixture.mp4
- name: Real RGUI framebuffer and playback controls
run: python3 samples/menu/rgui_media/run.py --c89 --cadence-hz 30 samples/menu/rgui_media/fixture.mp4
- name: Real MaterialUI file-browser playback controls
run: python3 samples/menu/rgui_media/run.py --c89 --cadence-hz 30 --driver materialui samples/menu/rgui_media/fixture.mp4
- name: Real XMB file-browser playback controls
run: python3 samples/menu/rgui_media/run.py --c89 --cadence-hz 30 --driver xmb samples/menu/rgui_media/fixture.mp4
- name: Real Ozone file-browser playback controls
run: python3 samples/menu/rgui_media/run.py --c89 --cadence-hz 30 --driver ozone samples/menu/rgui_media/fixture.mp4
- name: UTF-8 subtitle sidecars across all four menus
run: |
python3 -c "from pathlib import Path; Path('samples/menu/rgui_media/fixture.srt').write_text('1\n00:00:00,000 --> 00:10:00,000\nSubtitle sidecar\nUTF-8 \u00e9\n\n', encoding='utf-8')"
python3 -c "from pathlib import Path; Path('samples/menu/rgui_media/fixture.en.srt').write_text('1\n00:00:00,000 --> 00:10:00,000\nEnglish track\n', encoding='utf-8')"
for driver in rgui materialui xmb ozone; do
python3 samples/menu/rgui_media/run.py --c89 --subtitles --driver "$driver" samples/menu/rgui_media/fixture.mp4
done
- name: Embedded MP4 subtitles across all four menus
run: |
python3 -c "from pathlib import Path; [Path('samples/menu/rgui_media/embedded-'+n+'.srt').write_text('1\n00:00:00,000 --> 00:10:00,000\nEmbedded '+n+' UTF-8 \u00e9\n', encoding='utf-8') for n in ('first', 'second')]"
ffmpeg -v error -y -i samples/menu/rgui_media/fixture.mp4 -i samples/menu/rgui_media/embedded-first.srt -i samples/menu/rgui_media/embedded-second.srt -map 0:v:0 -map 1:0 -map 2:0 -c:v copy -c:s mov_text samples/menu/rgui_media/embedded.mp4
for driver in rgui materialui xmb ozone; do
MEDIA_TEST_EMBEDDED_SUBTITLES=1 python3 samples/menu/rgui_media/run.py --c89 --driver "$driver" samples/menu/rgui_media/embedded.mp4
done
- name: Embedded Matroska subtitles across all four menus
run: |
ffmpeg -v error -y -f lavfi -i testsrc2=size=320x240:rate=30 -i samples/menu/rgui_media/embedded-first.srt -i samples/menu/rgui_media/embedded-second.srt -map 0:v:0 -map 1:0 -map 2:0 -t 4 -c:v libvpx-vp9 -deadline realtime -cpu-used 8 -g 30 -auto-alt-ref 0 -threads 1 -c:s srt samples/menu/rgui_media/embedded.mkv
for driver in rgui materialui xmb ozone; do
MEDIA_TEST_EMBEDDED_SUBTITLES=1 python3 samples/menu/rgui_media/run.py --c89 --driver "$driver" samples/menu/rgui_media/embedded.mkv
done
- name: Folder playback and fullscreen settings across all menus
run: |
ffmpeg -v error -y -i samples/menu/rgui_media/embedded.mkv -map 0:v:0 -c:v copy samples/menu/rgui_media/folder.mkv
for driver in rgui materialui xmb ozone; do
python3 samples/menu/rgui_media/run.py --c89 --desktop-refresh --driver "$driver" samples/menu/rgui_media/fixture.mp4
python3 samples/menu/rgui_media/run.py --c89 --continuous-error --driver "$driver" samples/menu/rgui_media/fixture.mp4
python3 samples/menu/rgui_media/run.py --c89 --continuous --driver "$driver" samples/menu/rgui_media/folder.mkv
done
- name: External movies and internal image activation across all menus
run: |
ffmpeg -v error -y -f lavfi -i color=c=orange:size=32x32 -frames:v 1 -threads 1 samples/menu/rgui_media/fixture.png
for driver in rgui materialui xmb ozone; do
python3 samples/menu/rgui_media/run.py --c89 --external --driver "$driver" samples/menu/rgui_media/fixture.mp4
python3 samples/menu/rgui_media/run.py --c89 --external --driver "$driver" samples/menu/rgui_media/fixture.png
python3 samples/menu/rgui_media/run.py --c89 --browser-image --driver "$driver" samples/menu/rgui_media/fixture.png
done
- name: Background setting browser picks images instead of viewing them
run: |
ffmpeg -v error -y -f lavfi -i color=c=orange:size=32x32 -frames:v 1 -threads 1 samples/menu/rgui_media/fixture.png
for driver in xmb materialui; do
python3 samples/menu/rgui_media/run.py --c89 --wallpaper-pick --driver "$driver" samples/menu/rgui_media/fixture.png
done
- name: Images history entries open in the viewer and Back returns to the list
run: |
ffmpeg -v error -y -f lavfi -i color=c=orange:size=32x32 -frames:v 1 -threads 1 samples/menu/rgui_media/fixture.png
for driver in rgui materialui xmb ozone; do
python3 samples/menu/rgui_media/run.py --c89 --history-image --driver "$driver" samples/menu/rgui_media/fixture.png
done
- name: Generate WebM transport fixtures
run: |
ffmpeg -v error -y -f lavfi -i testsrc2=size=320x240:rate=30 -f lavfi -i sine=frequency=440:sample_rate=48000 -t 3 -c:v libvpx -deadline realtime -cpu-used 8 -g 30 -auto-alt-ref 0 -c:a libopus -shortest samples/menu/rgui_media/fixture-opus.webm
ffmpeg -v error -y -f lavfi -i testsrc2=size=320x240:rate=30 -f lavfi -i sine=frequency=440:sample_rate=48000 -t 3 -c:v libvpx-vp9 -g 30 -auto-alt-ref 0 -c:a libvorbis -shortest samples/menu/rgui_media/fixture-vorbis.webm
- name: Real WebM controls across all four menus
run: |
for driver in rgui materialui xmb ozone; do
python3 samples/menu/rgui_media/run.py --c89 --driver "$driver" samples/menu/rgui_media/fixture-opus.webm
python3 samples/menu/rgui_media/run.py --c89 --driver "$driver" samples/menu/rgui_media/fixture-vorbis.webm
done
window-toggle-media:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
APT_PKGS: ffmpeg xvfb xauth libgl1-mesa-dev libx11-dev libxext-dev libxrandr-dev
steps:
- uses: actions/checkout@v6
- 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 dependencies
timeout-minutes: 10
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: Configure C89 GL frontend
run: ./configure --disable-qt --disable-vulkan --disable-wayland --disable-ffmpeg --disable-cheevos --disable-webmplayer
- name: Build shipping frontend
run: make -j2 C89_BUILD=1
- name: Generate moving VP8 fixture
run: |
ffmpeg -v error -y -f lavfi -i "testsrc2=size=320x240:rate=30,hue=h=90*t" -t 3 -c:v libvpx -deadline realtime -cpu-used 8 -g 90 -auto-alt-ref 0 samples/menu/rgui_media/window-toggle.webm
ffmpeg -v error -y -f lavfi -i "color=orange:size=320x240:rate=30" -t 3 -c:v libvpx -deadline realtime -cpu-used 8 -g 90 -auto-alt-ref 0 samples/menu/rgui_media/settings-preview.webm
- name: External media starts without browser frames and recovers from failure
run: |
set -eu
ffmpeg -v error -y -f lavfi -i color=c=orange:size=32x32 -frames:v 1 -threads 1 samples/menu/rgui_media/startup.png
python3 -c "from pathlib import Path; root = Path('samples/menu/rgui_media'); [(root / name).write_bytes(b'not decodable media') for name in ('corrupt.mp4', 'corrupt.png')]"
for driver in rgui materialui xmb ozone; do
for threaded in '' --threaded; do
for fixture in window-toggle.webm startup.png; do
xvfb-run -a python3 samples/menu/rgui_media/run.py --c89 --external --first-frame --video-driver gl --driver "$driver" $threaded "samples/menu/rgui_media/$fixture"
done
for fixture in corrupt.mp4 corrupt.png; do
xvfb-run -a python3 samples/menu/rgui_media/run.py --c89 --external --startup-failure --video-driver gl --driver "$driver" $threaded "samples/menu/rgui_media/$fixture"
done
done
done
- name: Fullscreen window transitions retain movie pixels and seeking
run: |
for driver in rgui materialui xmb ozone; do
for threaded in '' --threaded; do
xvfb-run -a python3 samples/menu/rgui_media/run.py --c89 --window-toggle --video-driver gl --driver "$driver" $threaded samples/menu/rgui_media/window-toggle.webm
done
done
- name: GPU folder playback and fullscreen settings across all menus
run: |
for driver in rgui materialui xmb ozone; do
for threaded in '' --threaded; do
MEDIA_TEST_SETTINGS_ORANGE=1 xvfb-run -a python3 samples/menu/rgui_media/run.py --c89 --fullscreen-settings --video-driver gl --driver "$driver" $threaded samples/menu/rgui_media/settings-preview.webm
xvfb-run -a python3 samples/menu/rgui_media/run.py --c89 --continuous-error --video-driver gl --driver "$driver" $threaded samples/menu/rgui_media/window-toggle.webm
done
done
- name: Generate delayed first-picture fixture
run: ffmpeg -v error -y -f lavfi -i "testsrc2=size=320x240:rate=30,hue=h=90*t" -vf "setpts=PTS+0.2/TB" -t 3 -c:v libvpx -deadline realtime -cpu-used 8 -g 90 -auto-alt-ref 0 samples/menu/rgui_media/delayed.webm
- name: Compare actual visible pictures after delayed-start seeks
run: |
for driver in rgui materialui xmb ozone; do
xvfb-run -a python3 samples/menu/rgui_media/run.py --c89 --video-driver gl --driver "$driver" --first-video-us 200000 samples/menu/rgui_media/delayed.webm
done
subtitle-sidecars:
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential clang ffmpeg
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
- 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 dependencies
timeout-minutes: 10
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: SubRip parsing, task ownership and drawing (GCC and Clang sanitizers)
shell: bash
run: |
set -eu
for compiler in gcc clang; do
for sample in libretro-common/samples/formats/subtitle_srt samples/tasks/subtitle_load samples/gfx/media_subtitle samples/gfx/media_controls; do
extra_flags=''
if [ "$compiler" = clang ]; then extra_flags="-Wno-c99-extensions -Wno-c11-extensions"; fi
make -C "$sample" clean
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1 CFLAGS="$extra_flags" \
make -C "$sample" check CC="$compiler" SANITIZER=address,undefined
done
done
- name: Subtitle ownership and publication races
shell: bash
run: |
set -eu
for sample in samples/tasks/subtitle_load samples/gfx/media_subtitle samples/gfx/media_controls; do
make -C "$sample" clean
TSAN_OPTIONS=halt_on_error=1 CFLAGS="-Wno-c99-extensions -Wno-c11-extensions" \
make -C "$sample" check CC=clang SANITIZER=thread
done
- name: Threadless subtitle loading and drawing
shell: bash
run: |
set -eu
for sample in libretro-common/samples/formats/subtitle_srt samples/tasks/subtitle_load samples/gfx/media_subtitle samples/gfx/media_controls; do
make -C "$sample" clean
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1 \
make -C "$sample" check THREADS=0 SANITIZER=address,undefined
done
-159
View File
@@ -1,159 +0,0 @@
name: CI Visual C++ 6 project (stand-in compiler)
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-msvc6-standin.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-msvc6-standin.yml'
# ci_paths: end
workflow_dispatch:
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:
msvc6-standin:
name: The Visual C++ 6 project's sources, defines and libraries, on mingw held to old C
runs-on: ubuntu-latest
env:
APT_PKGS: --no-install-recommends gcc-mingw-w64-i686 g++-mingw-w64-i686 gcc-mingw-w64-x86-64 wine64 pulseaudio xvfb
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 15
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Check the VC8 dialog optimizer workaround
run: python3 tools/msvc2005_dialog_check.py
- name: Compile and link what pkg/msvc/msvc-6 builds
shell: bash
run: |
set -eu
# Visual C++ 6 cannot be fetched here, so nothing built its
# project. This reads the project file - sources, defines,
# libraries - and builds the same with a 32-bit mingw
# compiler under old-C rules, at Windows NT 4.0's API, and
# links it. See the script for what that does and does not
# catch.
tools/msvc6_standin_check.sh
- name: The DXGI bridge as Visual C++ 2005 and 2010 build it
shell: bash
run: |
set -eu
# Their SDKs have no dxgi1_5.h or d3d12.h; the griffin builds
# for them still compile and link the bridge.
tools/dxgi_bridge_old_sdk_check.sh
- name: Run the waveout audio driver on a wave output device (Wine)
working-directory: samples/audio/waveout
shell: bash
run: |
set -eu
# The audio driver the Visual C++ 6 project uses: the
# multimedia library's wave output, which is all a Windows
# with no DirectX has. Run for real against a device - a
# silent one, from a sound server started here - and held to
# what the audio interface says of a driver. With no device
# the test only skips, which checks nothing: that is a
# failure here.
trap 'wineserver -k >/dev/null 2>&1 || true; pulseaudio --kill >/dev/null 2>&1 || true' EXIT
pulseaudio --start --exit-idle-time=-1
pactl load-module module-null-sink sink_name=ci >/dev/null
pactl set-default-sink ci
WINE=$(command -v wine64 || command -v wine || echo /usr/lib/wine/wine64)
make clean && make -j$(nproc) all
WINEDEBUG=-all timeout 300 make check WINE="$WINE" | tee waveout.log
grep -q "PASS waveout_test" waveout.log
make clean
rm -f waveout.log
- name: Run the plain Win32 input driver against a window (Wine)
working-directory: samples/input/win32_input
shell: bash
run: |
set -eu
# The input driver the Visual C++ 6 project uses: keys from
# the window's messages, the mouse from where the cursor is.
# Run against a real window: its key map, keys down and up,
# nothing down with another window in front, the mouse's
# place and motion. A part it had to skip - no window, or one
# that would not come to the front - checks nothing, and is a
# failure here.
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
WINE=$(command -v wine64 || command -v wine || echo /usr/lib/wine/wine64)
make clean && make -j$(nproc) all
WINEDEBUG=-all timeout 300 make check WINE="$WINE" | tee win32_input.log
grep -q "PASS win32_input_test" win32_input.log
if grep -q "^\[skip\]" win32_input.log; then
echo "a part of the test was skipped"
exit 1
fi
make clean
rm -f win32_input.log
- name: Run the winmm joypad driver against stand-in joystick calls (Wine)
working-directory: samples/input/winmm_joypad
shell: bash
run: |
set -eu
# The joypad driver the Visual C++ 6 project uses: the
# multimedia library's joystick calls. No controller can be
# scripted here, so the calls and the clock are the test's:
# axes across the controller's own ranges, thirty-two
# buttons, the hat's eight ways, the RetroPad mask, a
# controller pulled out and plugged in, and the controllers
# that are not there not asked at every poll.
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
WINE=$(command -v wine64 || command -v wine || echo /usr/lib/wine/wine64)
make clean && make -j$(nproc) all
WINEDEBUG=-all timeout 300 make check WINE="$WINE" | tee winmm_joypad.log
grep -q "PASS winmm_joypad_test" winmm_joypad.log
make clean
rm -f winmm_joypad.log
-94
View File
@@ -1,94 +0,0 @@
name: CI Linux netplay end to end
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/network/netplay_e2e/**'
- '.github/workflows/Linux-netplay-e2e.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/network/netplay_e2e/**'
- '.github/workflows/Linux-netplay-e2e.yml'
# ci_paths: end
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
netplay-e2e:
name: Two retroarch processes in netplay
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config zlib1g-dev python3 ccache
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build RetroArch with no menu, video or sound
shell: bash
run: |
set -eu
./configure --disable-qt --disable-ffmpeg --disable-vulkan \
--disable-wayland --disable-x11 --disable-opengl --disable-egl \
--disable-kms --disable-sdl2 --disable-pulse --disable-alsa \
--disable-jack --disable-oss --disable-freetype --disable-menu
grep -q '^HAVE_NETWORKGAMEPAD = 1' config.mk
make -j"$(nproc)" CC="ccache gcc" CXX="ccache g++"
- name: Host and client over the loopback
shell: bash
run: |
set -eu
# analog sticks synced and not, lockstep asked for, a lockstep
# host with a rollback client, and a state too large to roll
# back; the peers' RAM agrees on every frame
make -C samples/network/netplay_e2e
timeout 600 make -C samples/network/netplay_e2e check RETROARCH=$PWD/retroarch
make -C samples/network/netplay_e2e clean
+32 -118
View File
@@ -10,21 +10,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-network-clients.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-network-clients.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -38,42 +26,41 @@ jobs:
network-clients:
name: TLS, SMB and NFS clients against local servers
runs-on: ubuntu-latest
env:
APT_PKGS: --no-install-recommends build-essential clang gcc-mingw-w64-x86-64 openssl samba libtirpc-dev flex bison autoconf automake wine wine64 nfs-ganesha nfs-ganesha-vfs krb5-kdc krb5-admin-server krb5-user winbind samba-dsdb-modules samba-ad-provision samba-vfs-modules acl smbclient tshark iproute2
timeout-minutes: 45
steps:
- name: Checkout
uses: actions/checkout@v5
- 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: Preseed tshark
# dumpcap asks whether to be setuid: no, runs are root
run: echo "wireshark-common wireshark-common/install-setuid boolean false" | sudo debconf-set-selections
- name: Install dependencies
timeout-minutes: 25
run: sh .github/workflows/scripts/apt-install.sh $APT_PKGS
run: |
sudo apt-get update -y
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
# tshark's dumpcap asks whether to be setuid: no, runs are root
echo "wireshark-common wireshark-common/install-setuid boolean false" | sudo debconf-set-selections
export DEBIAN_FRONTEND=noninteractive
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only --no-install-recommends build-essential clang \
gcc-mingw-w64-x86-64 openssl samba libtirpc-dev flex bison autoconf automake wine wine64 \
nfs-ganesha nfs-ganesha-vfs krb5-kdc krb5-admin-server krb5-user winbind \
samba-dsdb-modules samba-ad-provision samba-vfs-modules acl smbclient tshark && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y --no-install-recommends build-essential clang \
gcc-mingw-w64-x86-64 openssl samba libtirpc-dev flex bison autoconf automake wine wine64 \
nfs-ganesha nfs-ganesha-vfs krb5-kdc krb5-admin-server krb5-user winbind \
samba-dsdb-modules samba-ad-provision samba-vfs-modules acl smbclient tshark
- 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checkout
uses: actions/checkout@v5
- name: Built-in TLS client against a local openssl server
shell: bash
@@ -107,59 +94,6 @@ jobs:
sudo samples/network/smb_retro/local_ad_dc_test.sh
sudo make -C samples/network/smb_retro clean
- name: Embedded MCP server over the loopback
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# network/mcp_server.c as it ships, in front of a stub command
# table: the handshake, the tool list and its hints, answers now
# and later, the JSON-RPC errors, the HTTP gate (method, path,
# Origin, the bearer token it will not start without), an
# oversized body, a request in pieces, and teardown with a
# request waiting
make -C samples/network/mcp_server clean
make -C samples/network/mcp_server SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1 \
make -C samples/network/mcp_server check
make -C samples/network/mcp_server clean
- name: Netplay input bookkeeping
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# netplay_frontend.c's input decode, real-client mask, analog
# joypad ports and relay host setup, as they ship
make -C samples/network/netplay_input clean
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1 \
make -C samples/network/netplay_input check SANITIZER=address,undefined
make -C samples/network/netplay_input clean
make -C samples/network/netplay_input CC=x86_64-w64-mingw32-gcc LDFLAGS=-static
make -C samples/network/netplay_input clean
- name: GET_LOG's ring, written from four threads while read
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
make -C samples/runloop/log_ring clean
make -C samples/runloop/log_ring SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1 \
make -C samples/runloop/log_ring check
make -C samples/runloop/log_ring clean
- name: Command options and speed setters
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
make -C samples/network/command_options clean
make -C samples/network/command_options SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1 \
make -C samples/network/command_options check
make -C samples/network/command_options clean
- name: Windows builds under Wine
shell: bash
@@ -172,26 +106,7 @@ jobs:
export WINEDEBUG=-all WINEPREFIX=$RUNNER_TEMP/wineprefix
# the tools below are run through wine, so it must be there
command -v wine >/dev/null
# One wineserver for the whole step. Ubuntu's wrapper starts
# it with -p0: it exits with each tool and the next tool
# starts another. A tool that starts while the last server
# is still on its way out is cut off by it before main()
# ("wine client error:0: recvmsg: Connection reset by peer")
# and the lane fails with nothing wrong in the tree. The
# first process brings up Wine's services, which keep its
# output for as long as they live, so it is given none.
mkdir -p "$WINEPREFIX"
wineserver -p
trap 'wineserver -k || true; sudo -E env HOME=/root WINEPREFIX=/tmp/wineprefix-root wineserver -k || true' EXIT
wine cmd /c exit > /dev/null 2>&1 < /dev/null
make -C libretro-common -f Makefile.test win32-wine-check
# the MCP server on Winsock
make -C samples/network/mcp_server clean
make -C samples/network/mcp_server compiler=x86_64-w64-mingw32-gcc
(cd samples/network/mcp_server && wine ./mcp_server_test.exe)
make -C samples/network/mcp_server clean
make -C samples/network/command_options check compiler=x86_64-w64-mingw32-gcc RUNNER=wine
make -C samples/network/command_options clean
export CC=x86_64-w64-mingw32-gcc RUNNER=wine EXE=.exe
make -C samples/network/tls_retro clean
samples/network/tls_retro/local_server_test.sh
@@ -201,8 +116,7 @@ jobs:
# owned by someone else and creating one inside a directory it
# does not own ($RUNNER_TEMP belongs to the runner user), so the
# root run gets a prefix under /tmp with root's own HOME
sudo -E env HOME=/root WINEPREFIX=/tmp/wineprefix-root sh -c 'mkdir -p "$WINEPREFIX" && wineserver -p'
sudo -E env HOME=/root WINEPREFIX=/tmp/wineprefix-root wineboot -u > /dev/null 2>&1 < /dev/null
sudo -E env HOME=/root WINEPREFIX=/tmp/wineprefix-root wineboot -u
sudo -E env HOME=/root WINEPREFIX=/tmp/wineprefix-root samples/network/smb_retro/local_samba_test.sh
sudo -E env HOME=/root WINEPREFIX=/tmp/wineprefix-root samples/network/smb_retro/local_ad_dc_test.sh
sudo make -C samples/network/smb_retro clean
@@ -228,7 +142,7 @@ jobs:
# client with the fuzzer's input), under ASan + UBSan, from a
# seed corpus recorded off real servers. Any crash, timeout or
# leak artifact fails the step.
make -j$(nproc) -C libretro-common/test/fuzz fuzz-run FUZZ_SECONDS=30
make -C libretro-common/test/fuzz fuzz-run FUZZ_SECONDS=30
if ls libretro-common/test/fuzz/crash-* libretro-common/test/fuzz/leak-* libretro-common/test/fuzz/timeout-* >/dev/null 2>&1; then
echo "fuzzer artifacts found"; exit 1
fi
@@ -245,7 +159,7 @@ jobs:
# for memory errors, undefined behaviour and leaks. UBSan found
# a NULL memcpy in the SHA-2 stream updates on the SHA-384 PRF
# path the first time this ran.
export CFLAGS="-O1 -g1 -fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer"
export CFLAGS="-O1 -g -fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer"
export LDFLAGS="-fsanitize=address,undefined"
export ASAN_OPTIONS=detect_leaks=1:strict_string_checks=1
export UBSAN_OPTIONS=print_stacktrace=1
+11 -45
View File
@@ -4,27 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/frontend/dbus_runtime/**'
- '.github/workflows/Linux-no-pkg-config.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/frontend/dbus_runtime/**'
- '.github/workflows/Linux-no-pkg-config.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -41,39 +23,23 @@ jobs:
no-pkg-config:
name: Configure and build with pkg-config unavailable
runs-on: ubuntu-latest
env:
APT_PKGS: --no-install-recommends build-essential zlib1g-dev libfreetype-dev libdrm-dev libasound2-dev libpulse-dev libpipewire-0.3-dev libdbus-1-dev libwayland-dev libwayland-bin libxkbcommon-dev libdecor-0-dev libssl-dev qt6-base-dev qt6-base-dev-tools
timeout-minutes: 30
steps:
- name: Install dependencies
shell: bash
run: |
set -eu
sudo apt-get update -qq
sudo apt-get install -y -qq --no-install-recommends \
build-essential zlib1g-dev libfreetype-dev libdrm-dev \
libasound2-dev libpulse-dev libpipewire-0.3-dev \
libdbus-1-dev libwayland-dev libwayland-bin libxkbcommon-dev \
libdecor-0-dev libssl-dev qt6-base-dev qt6-base-dev-tools
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 15
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Configure
shell: bash
run: |
-353
View File
@@ -1,353 +0,0 @@
name: CI OpenXR (stand-in runtime, desktop headset path)
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-openxr-input.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-openxr-input.yml'
# ci_paths: end
workflow_dispatch:
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:
openxr-input:
name: OpenXR input and shared units against a stand-in runtime
runs-on: ubuntu-latest
env:
APT_PKGS: pkg-config libegl-dev libgl-dev libx11-dev
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Run input/common/input_openxr.c against a stand-in runtime
working-directory: samples/input/openxr_input
shell: bash
run: |
set -euo pipefail
# The headset's controllers, the desktop's and the Quest's, as
# they ship, against a runtime and a frontend the test stands
# in for: what the actions give the RetroPad, Touch's menu
# button, the laser on a frame and on the menu, rumble, and
# nothing held when the runtime has nothing to give.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
./openxr_input_test | tee openxr_input.log
grep -q "PASS openxr_input_test" openxr_input.log
make clean
rm -f openxr_input.log
- name: Run the shared OpenXR units against a stand-in runtime
working-directory: samples/openxr/core
shell: bash
run: |
set -euo pipefail
# The Makefile leaves the desktop GL host's tests out where
# these are not found, and the run still passes.
pkg-config --exists egl x11 gl
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
./openxr_core_test | tee openxr_core.log
grep -q "PASS openxr_core_test" openxr_core.log
make clean
rm -f openxr_core.log
- name: Run the shared OpenXR units under TSan
working-directory: samples/openxr/core
shell: bash
run: |
set -euo pipefail
# The XR thread, the tick waiters and the lock gaps.
pkg-config --exists egl x11 gl
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
./openxr_core_test | tee openxr_core.log
grep -q "PASS openxr_core_test" openxr_core.log
make clean
rm -f openxr_core.log
openxr-haptics:
name: Desktop haptic results (Linux sanitizers, Windows build)
runs-on: ubuntu-latest
env:
APT_PKGS: gcc-mingw-w64-x86-64
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Run desktop haptics against scripted runtime results
working-directory: samples/input/openxr_haptics
shell: bash
run: |
set -eu
make clean
make SANITIZER=address,undefined check
make clean
make SANITIZER=thread check
make clean
make CC=x86_64-w64-mingw32-gcc all
make clean
openxr-loader-threads:
name: OpenXR loader under concurrent use (TSan, ASan+UBSan)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Run deps/openxr's loader from several threads
working-directory: samples/openxr/loader_threads
shell: bash
run: |
set -eu
# The loader shares its runtime, active instance, recorder and
# messenger tables and property set between threads with no
# lock. Threads enumerate, create, reinitialize and log against
# a stand-in runtime while the main thread cycles instances and
# messengers; a race or a use-after-free in any of it fails.
make clean
make SANITIZER=thread check
make clean
make SANITIZER=address,undefined check
make clean
openxr-desktop:
name: Desktop headset output with the in-tree loader
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libx11-dev libxext-dev libxrandr-dev libxinerama-dev libxxf86vm-dev libxv-dev libxkbcommon-dev libwayland-dev wayland-protocols libdrm-dev libgbm-dev libasound2-dev libpulse-dev libudev-dev libusb-1.0-0-dev libvulkan-dev libdbus-1-dev zlib1g-dev
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build RetroArch with OpenXR
shell: bash
run: |
set -eu
# OpenXR is opt-in; the vendored Khronos loader is built into
# the tree, so nothing has to be installed. Qt has to go: the
# menu harness below replaces main(), which lives in ui_qt.o
# with Qt enabled.
# The screens' windows too, which video_screens_test runs.
./configure --disable-qt --enable-openxr --enable-video_windows
grep -q '^HAVE_OPENXR = 1' config.mk
grep -q '^HAVE_VIDEO_WINDOWS = 1' config.mk
make -j$(nproc)
# Vulkan's headset host and the desktop GL drivers', side by
# side.
test -f obj-unix/release/gfx/common/vulkan_openxr.o
test -f obj-unix/release/gfx/common/gl_openxr.o
test -f obj-unix/release/gfx/common/openxr_binding_gl.o
- name: Build and run video_screens_test
shell: bash
run: |
set -eu
python3 samples/settings/video_screens/build.py \
--output-dir "$RUNNER_TEMP/video-screens"
- name: Build and run stereo_headset_test
shell: bash
run: |
set -eu
# The Stereo 3D & Screens list, with Headset Output off and
# on under each driver that has a headset path, against the
# shipping menu objects.
samples/menu/stereo_headset/build.sh
./samples/menu/stereo_headset/stereo_headset_test
make -C samples/menu/stereo_headset clean
- name: Run the headset end-to-end runner's own tests
shell: bash
run: |
set -eu
# samples/openxr/e2e/run.py needs a runtime and a GPU; its
# case selection and its OpenGL lanes do not.
python3 -m unittest discover -s samples/openxr/e2e -p 'test_*.py'
- name: Build the OpenXR test layer and the video_views core
shell: bash
run: |
set -eu
# The API layer the Monado end-to-end check records through,
# against the vendored headers, and the core it drives.
make -C samples/openxr/test_layer clean && make -C samples/openxr/test_layer -j$(nproc) all
test -f samples/openxr/test_layer/libxr_test_layer.so
make -C samples/cores/video_views clean && make -C samples/cores/video_views -j$(nproc) all
test -f samples/cores/video_views/video_views_libretro.so
make -C samples/openxr/test_layer clean
make -C samples/cores/video_views clean
openxr-desktop-gl:
name: Desktop headset output on OpenGL alone, without Vulkan
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libx11-dev libxext-dev libxrandr-dev libxinerama-dev libxxf86vm-dev libxv-dev libxkbcommon-dev libwayland-dev wayland-protocols libdrm-dev libgbm-dev libasound2-dev libpulse-dev libudev-dev libusb-1.0-0-dev libdbus-1-dev zlib1g-dev
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 10
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build RetroArch with OpenXR and no Vulkan
shell: bash
run: |
set -eu
# The gl and glcore drivers' headset output has to configure,
# build and link without Vulkan.
./configure --disable-qt --enable-openxr --disable-vulkan \
--enable-video_windows
grep -q '^HAVE_OPENXR = 1' config.mk
grep -q '^HAVE_VIDEO_WINDOWS = 1' config.mk
grep -q '^HAVE_VULKAN = 0' config.mk
make -j$(nproc)
test -f obj-unix/release/gfx/common/openxr_frame.o
test -f obj-unix/release/gfx/common/gl_openxr.o
test ! -e obj-unix/release/gfx/common/vulkan_openxr.o
- name: Build and run video_screens_test
shell: bash
run: |
set -eu
python3 samples/settings/video_screens/build.py \
--output-dir "$RUNNER_TEMP/video-screens"
- name: Build and run stereo_headset_test
shell: bash
run: |
set -eu
# Headset Output under glcore and gl, with no vulkan driver
# to list it under.
samples/menu/stereo_headset/build.sh
./samples/menu/stereo_headset/stereo_headset_test
make -C samples/menu/stereo_headset clean
+40 -93
View File
@@ -24,19 +24,12 @@ on:
- 'tasks/task_overlay.c'
- 'led/drivers/led_overlay.c'
- 'gfx/gfx_surface.*'
- 'gfx/gfx_surface_player.*'
- 'libretro-common/formats/video_player.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'gfx/drivers/gl2.c'
- 'menu/menu_driver.c'
- 'input/drivers/x11_input.c'
- 'samples/input/overlay_on_screen/**'
- 'input/input_driver_choice.c'
- 'gfx/drivers_context/x_ctx.c'
- 'gfx/common/x11_common.c'
- 'samples/input/x11_smoke/**'
- 'samples/input/windows_wine_smoke/smoke_core.c'
- '.github/workflows/Linux-overlay-on-screen.yml'
pull_request:
paths:
@@ -45,19 +38,12 @@ on:
- 'tasks/task_overlay.c'
- 'led/drivers/led_overlay.c'
- 'gfx/gfx_surface.*'
- 'gfx/gfx_surface_player.*'
- 'libretro-common/formats/video_player.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'gfx/drivers/gl2.c'
- 'menu/menu_driver.c'
- 'input/drivers/x11_input.c'
- 'samples/input/overlay_on_screen/**'
- 'input/input_driver_choice.c'
- 'gfx/drivers_context/x_ctx.c'
- 'gfx/common/x11_common.c'
- 'samples/input/x11_smoke/**'
- 'samples/input/windows_wine_smoke/smoke_core.c'
- '.github/workflows/Linux-overlay-on-screen.yml'
workflow_dispatch:
@@ -75,41 +61,52 @@ jobs:
overlay-on-screen:
name: Run retroarch under Xvfb and look at the overlay
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential zlib1g-dev ccache python3 xvfb x11-apps xdotool libgl1-mesa-dri libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev libxtst6 libxxf86vm-dev libxrandr-dev libxinerama-dev libgl-dev libegl-dev
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
build-essential zlib1g-dev ccache python3 \
xvfb x11-apps libgl1-mesa-dri \
libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev libxtst6 \
libxxf86vm-dev libxrandr-dev libxinerama-dev \
libgl-dev libegl-dev && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
build-essential zlib1g-dev ccache python3 \
xvfb x11-apps libgl1-mesa-dri \
libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev libxtst6 \
libxxf86vm-dev libxrandr-dev libxinerama-dev \
libgl-dev libegl-dev
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -122,7 +119,7 @@ jobs:
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build RetroArch (X11 + OpenGL, the rest off)
@@ -159,36 +156,6 @@ jobs:
# modes.
timeout 180 python3 samples/input/overlay_on_screen/overlay_on_screen_test.py ./retroarch
- name: Run overlay_apng_on_screen_test (an animated image plays and loops, threaded off and on)
shell: bash
run: |
set -eu
timeout 180 python3 samples/input/overlay_on_screen/overlay_apng_on_screen_test.py ./retroarch
- name: Run overlay_apng_press_on_screen_test (a two-frame image shows its pressed frame, threaded off and on)
shell: bash
run: |
set -eu
timeout 180 python3 samples/input/overlay_on_screen/overlay_apng_press_on_screen_test.py ./retroarch
- name: Run overlay_stick_on_screen_test (a movable stick follows the finger and returns, threaded off and on)
shell: bash
run: |
set -eu
# A movable stick's geometry is sent only when it moves; the
# picture shows nothing a move needed was left out.
timeout 180 python3 samples/input/overlay_on_screen/overlay_stick_on_screen_test.py ./retroarch
- name: Run statistics_on_screen_test (threaded video off, then on)
shell: bash
run: |
set -eu
# This build has no video filters, and the statistics have
# to show all the same: they are drawn with the OSD font,
# which reaches the video state through a binding video init
# makes whatever the build leaves out.
timeout 180 python3 samples/gfx/statistics_on_screen/statistics_on_screen_test.py ./retroarch
- name: Run overlay_menu_mouse_test (display and input packs, threaded off and on)
shell: bash
run: |
@@ -209,23 +176,3 @@ jobs:
# as does one named with _led, and a pack that names its LEDs
# is not mapped.
timeout 300 python3 samples/input/overlay_on_screen/overlay_led_hidden_test.py ./retroarch
- name: Run the X11 input scenarios (keys pressed in the window)
shell: bash
run: |
set -eu
# The same build, on a virtual display of its own, with the
# X11 input driver: keys are pressed in the window and a small
# core says in the log what reached it - before and after a
# fullscreen toggle restarts the video driver, with threaded
# video and without. See samples/input/x11_smoke/run.sh.
timeout 600 samples/input/x11_smoke/run.sh
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
+34 -43
View File
@@ -19,21 +19,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-pace-shadow.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-pace-shadow.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -49,41 +37,44 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
env:
APT_PKGS: build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm
# Line tables are all a sanitizer report needs. configure and
# make take these in place of DEBUG=1's -O0 -g, adding their own.
CFLAGS: -O0 -g1
CXXFLAGS: -O0 -g1
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 20
run: sh .github/workflows/scripts/apt-install.sh $APT_PKGS
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checkout
uses: actions/checkout@v5
- name: Configure
# Non-Qt, as the harness requires (with Qt, main() lives in
-57
View File
@@ -1,57 +0,0 @@
name: CI QNX input drivers (stand-in SDK)
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-qnx-standin.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-qnx-standin.yml'
# ci_paths: end
workflow_dispatch:
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:
qnx-standin:
name: QNX input drivers compile against stand-ins for the SDK
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Compile qnx_input.c and qnx_joypad.c
shell: bash
run: |
set -eu
# The BlackBerry 10 SDK cannot be fetched here, so nothing
# built the QNX port and its input driver stopped compiling
# unseen. This compiles the two input files - declarations
# and syntax, nothing linked or run - against stand-ins for
# the SDK's headers. See the script for what that does and
# does not catch.
tools/qnx_standin_check.sh
+34 -39
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-qt-companion.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-qt-companion.yml'
# ci_paths: end
permissions:
contents: read
@@ -44,37 +32,44 @@ jobs:
# core's shader accessors are compiled out). That is deliberate - it
# is the one configuration the other jobs never build.
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config zlib1g-dev qt6-base-dev libgl-dev
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 20
run: |
pkgs="build-essential pkg-config zlib1g-dev qt6-base-dev libgl-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Configure
run: |
./configure --enable-qt --disable-x11 --disable-wayland \
+86 -567
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-samples-audio.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-samples-audio.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -35,41 +23,49 @@ jobs:
samples-audio:
name: Build and run samples/audio
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libasound2-dev libsdl2-dev libopenal-dev libpipewire-0.3-dev libpulse-dev pulseaudio ffmpeg gcc-mingw-w64-x86-64 wine64 ccache
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential libasound2-dev libsdl2-dev libopenal-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -79,10 +75,11 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build and run mixer_lock_test (ASan + UBSan, TSan)
@@ -136,21 +133,6 @@ jobs:
TSAN_OPTIONS=halt_on_error=1 timeout 600 ./thread_handshake_test
echo "[pass] thread_handshake_test (TSan)"
- name: Build and run mmdevice_active_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/mmdevice_active
run: |
set -eu
# The open-endpoint table the WASAPI notifications consult,
# set from two threads and matched from a third, none of
# which has touched it before.
make clean && make -j$(nproc) all SANITIZER=address,undefined
timeout 300 ./mmdevice_active_test
echo "[pass] mmdevice_active_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./mmdevice_active_test
echo "[pass] mmdevice_active_test (TSan)"
- name: Build and run graph_clock_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/graph_clock
@@ -260,24 +242,6 @@ jobs:
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./alsa_lifecycle_test
echo "[pass] alsa_lifecycle_test (TSan)"
- name: Build and run alsa_chmap_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/alsa_chmap
run: |
set -eu
# The shipping ALSA driver against the null PCM, with the
# channel map, the channel counts the card takes and writei
# scripted via -Wl,--wrap: a card is handed the frontend's
# channels in its own order - its map's, or ALSA's FL FR RL
# RR FC LFE SL SR without one - by write() and through a lent
# mmap span, reports the layout it has, and steps 7.1 down to
# 5.1 or quad before stereo. A short writei must not lose the
# frame stride.
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
timeout 120 ./alsa_chmap_test
echo "[pass] alsa_chmap_test (ASan)"
- name: Build and run pipeline_stall_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/pipeline_stall
@@ -325,7 +289,7 @@ jobs:
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./upmix_test
echo "[pass] upmix_test (ASan)"
- name: Build and run discrete_multichannel_test (plain, ASan + UBSan, TSan)
- name: Build and run discrete_multichannel_test (plain, ASan + UBSan)
shell: bash
working-directory: samples/audio/discrete_multichannel
run: |
@@ -341,26 +305,12 @@ jobs:
# 5.1 core reaches a Dolby Digital decoder as AC-3 bursts
# that decode back to its own channels. Includes the
# shipping audio_driver.c.
# The builds in turn, the runs at once: each run is one
# thread, so a runner's second core takes another.
# Under ThreadSanitizer only the lane with a core submitting
# from a thread of its own beside the main thread's frame
# ends, pauses and fast-forward changes: the fast-forward
# measurement is the submitter's, and no other thread may
# write it.
. "$GITHUB_WORKSPACE/.github/workflows/scripts/run-parallel.sh"
make clean && make -j$(nproc) all
mv discrete_multichannel_test discrete_multichannel_test_plain
make clean && make -j$(nproc) all SANITIZER=thread
mv discrete_multichannel_test discrete_multichannel_test_tsan
./discrete_multichannel_test
echo "[pass] discrete_multichannel_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
par "discrete_multichannel_test" ./discrete_multichannel_test_plain
par "discrete_multichannel_test (ASan)" env ASAN_OPTIONS=detect_leaks=0 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./discrete_multichannel_test
par "discrete_multichannel_test (TSan: core thread)" env DM_ONLY=inlinethread \
TSAN_OPTIONS=halt_on_error=1 ./discrete_multichannel_test_tsan
par_wait
rm -f discrete_multichannel_test_plain discrete_multichannel_test_tsan
ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./discrete_multichannel_test
echo "[pass] discrete_multichannel_test (ASan)"
- name: Build and run embedded_alsa_test (the embedded ALSA driver, mock kernel device)
shell: bash
@@ -407,6 +357,8 @@ jobs:
working-directory: samples/audio/bitstream
run: |
set -eu
sudo apt-get update -qq
sudo apt-get install -y -qq ffmpeg
# audio/audio_bitstream.c: a coded stream on its way to a
# receiver, which the PCM pipeline has no place for. Real
# DTS and AC-3 from ffmpeg, handed over frame by frame:
@@ -463,201 +415,22 @@ jobs:
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./qsa_test
echo "[pass] qsa_test (ASan)"
- name: Build and run ctr_audio_test (the 3DS CSND and NDSP drivers against a scripted device)
shell: bash
working-directory: samples/audio/ctr_audio
run: |
set -eu
# audio/drivers/ctr_csnd_audio.c and ctr_dsp_audio.c against a
# stand-in <3ds.h> whose system tick and channel position are
# the device: buffer_size() and write_avail() in bytes of what
# write() takes, and a write longer than the ring taking half
# of it - ASan is what sees a copy run past the ring.
make clean && make -j$(nproc) all
./ctr_audio_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./ctr_audio_test
echo "[pass] ctr_audio_test (ASan)"
- name: Build and run switch_audio_test (the Switch audout driver against a scripted service)
shell: bash
working-directory: samples/audio/switch_audio
run: |
set -eu
# audio/drivers/switch_audio.c's libnx build against a
# stand-in <switch.h> whose audout service queues buffers and
# plays them out on the test's word: write_avail() must be
# what a write takes, across the released buffers, and
# buffer_size() every buffer carrying its share of the
# latency setting.
make clean && make -j$(nproc) all
./switch_audio_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./switch_audio_test
echo "[pass] switch_audio_test (ASan)"
- name: Build and run switch_audren_test (the Switch audren driver's renderer ownership, ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/switch_audren
run: |
set -eu
# audio/drivers/switch_libnx_audren_audio.c's libnx build
# against a stand-in <switch.h> whose renderer thread plays a
# wave buffer a frame. libnx's audrv is not thread-safe and
# the driver takes no lock: every renderer call must come from
# the writer's thread while another reads write_avail(), a
# write_avail() on the writer's own thread must see what the
# renderer played, non-blocking writes must keep taking audio,
# and stop and start must pause and resume the voice. TSan
# reports two threads in the renderer as a race on the
# stand-in's wave buffer list.
make clean && make -j$(nproc) all
./switch_audren_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./switch_audren_test
echo "[pass] switch_audren_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 ./switch_audren_test
echo "[pass] switch_audren_test (TSan)"
- name: Build and run wiiu_ax_test (the Wii U AX driver's callback against its writer)
shell: bash
working-directory: samples/audio/wiiu_ax
run: |
set -eu
# audio/drivers/wiiu_audio.c against the tree's own Wii U
# headers, with stand-in AX and OS functions behind them: the
# frame callback on one thread and the writer on another keep
# the count of buffered frames in one atomic word, and every
# frame accepted must be buffered or counted played. TSan is
# what sees a field the two share without ordering.
make clean && make -j$(nproc) all
./wiiu_ax_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./wiiu_ax_test
echo "[pass] wiiu_ax_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./wiiu_ax_test
echo "[pass] wiiu_ax_test (TSan)"
make clean
- name: Build and run xenon360_test (the libxenon driver against a scripted sound queue)
shell: bash
working-directory: samples/audio/xenon360
run: |
set -eu
# audio/drivers/xenon360_audio.c against stand-in libxenon
# headers: buffer_size() is the latency setting, write_avail()
# what a write takes, the queue never past it, and a write
# longer than the staging buffer goes in passes - ASan is what
# sees a pass overrun it.
make clean && make -j$(nproc) all
./xenon360_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./xenon360_test
echo "[pass] xenon360_test (ASan)"
- name: Build and run audioworklet_test (the web driver's write against its own ring)
shell: bash
working-directory: samples/audio/audioworklet
run: |
set -eu
# audio/drivers/audioworklet.c, #included by the test and
# built against the tree's emscripten stand-ins: write()
# returns the bytes it took, the ring holds exactly that, and
# frames a write gives up on are counted, not logged.
make clean && make -j$(nproc) all
./audioworklet_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./audioworklet_test
echo "[pass] audioworklet_test (ASan)"
- name: Build and run rwebaudio_test (the web driver's channels, C and JavaScript halves)
shell: bash
working-directory: samples/audio/rwebaudio
run: |
set -eu
# audio/drivers/rwebaudio.c against a stand-in for its
# JavaScript half: frames of the layout the page took go out
# one plane per channel, and every byte count is in frames of
# that layout. Then os/emscripten/library_rwebaudio.js itself
# under Node with a mock AudioContext: the destination is
# widened only past stereo and only as far as its
# maxChannelCount allows, and a stereo one is left as it was.
make clean && make -j$(nproc) check
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./rwebaudio_test
echo "[pass] rwebaudio_test (ASan)"
- name: Build and run pipewire_write_test (the PipeWire driver's write against its own ring)
shell: bash
working-directory: samples/audio/pipewire_write
run: |
set -eu
# audio/drivers/pipewire.c, #included by the test and built
# against the system's PipeWire headers, with the graph as a
# loop wait that plays a quantum: a write longer than the
# ring's mark takes what fits, or blocking goes in parts, in
# whole frames, and the write path logs nothing.
make clean && make -j$(nproc) all
./pipewire_write_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./pipewire_write_test
echo "[pass] pipewire_write_test (ASan)"
- name: Build and run wasapi_mic_test (the WASAPI microphone's fetch against a scripted capture client)
shell: bash
working-directory: samples/audio/wasapi_mic
run: |
set -eu
# audio/drivers/wasapi.c's text against the shared fake WASAPI
# with a capture client added: a shared-mode FIFO set shorter
# than one engine packet still takes every packet, and a
# packet with no room waits for the FIFO to be read.
make clean && make -j$(nproc) all
./wasapi_mic_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./wasapi_mic_test
echo "[pass] wasapi_mic_test (ASan)"
- name: Build and run oss_report_test (the OSS driver's reports on a device that cannot answer)
shell: bash
working-directory: samples/audio/oss_report
run: |
set -eu
# audio/drivers/oss.c, #included by the test, over Linux's
# soundcard.h: a device that has gone away reports no room and
# no size, and a second of frames asking logs nothing.
make clean && make -j$(nproc) all
./oss_report_test
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./oss_report_test
echo "[pass] oss_report_test (ASan)"
# RetroFW's jz4760 driver plays whole 16-byte DMA units only.
make clean && make -j$(nproc) all RETROFW=1 SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./oss_report_test
echo "[pass] oss_report_test (RetroFW, ASan)"
- name: Build and run live_drivers_test (a live PulseAudio server, a null ALSA PCM)
shell: bash
working-directory: samples/audio/live_drivers
run: |
set -eu
sudo apt-get update -qq
sudo apt-get install -y -qq libasound2-dev libpulse-dev pulseaudio
# A server with a null sink, and an ALSA config naming a null
# PCM: the real drivers against the real libraries, no
# hardware. Pulse's telemetry is cached from the server
# thread's callbacks and its writer takes no mainloop lock;
# ALSA is run once as the device reports
# thread's callbacks; ALSA is run once as the device reports
# itself and once told it cannot pause, the fallback from
# snd_pcm_pause to snd_pcm_drop. With the threaded pipeline a
# plug PCM opens for mmap and lends its buffer; a plug over a
# file plugin reads the lent bytes back.
# snd_pcm_pause to snd_pcm_drop.
export XDG_RUNTIME_DIR=/tmp/xdg
mkdir -p "$XDG_RUNTIME_DIR/pulse"
printf '%s\n' 'pcm.nullpcm { type null }' \
'pcm.plugnull { type plug slave.pcm "nullpcm" }' \
'pcm.filenull { type file slave.pcm "nullpcm" file "/tmp/ra_live_drivers_lend.raw" format raw }' \
'pcm.plugfile { type plug slave.pcm "filenull" }' > "$HOME/.asoundrc"
printf 'pcm.nullpcm { type null }\n' > "$HOME/.asoundrc"
pulseaudio --daemonize=no --exit-idle-time=-1 --disallow-exit -n \
-L "module-null-sink sink_name=nullsink rate=48000 channels=2" \
-L "module-native-protocol-unix auth-anonymous=1 socket=$XDG_RUNTIME_DIR/pulse/native" \
@@ -670,11 +443,6 @@ jobs:
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./live_drivers_test
echo "[pass] live_drivers_test (ASan)"
# Pulse's writer hands audio to the server's thread through a
# ring and an eventcount, which is what TSan is for.
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1:suppressions=$PWD/tsan.supp ./live_drivers_test
echo "[pass] live_drivers_test (TSan)"
kill $PA_PID || true
- name: Build and run binaural_test (plain, ASan + UBSan)
@@ -714,39 +482,38 @@ jobs:
# ratio at a bound and the pipe overflows behind it. Real time,
# so a loaded runner can shift the mean; the tolerance is ten
# times the settled residual.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x pipeline_rate_control_test
ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1 timeout 120 \
./pipeline_rate_control_test
echo "[pass] pipeline_rate_control_test (ASan)"
# A core late by 60 ms every 2 s, audio sync off: the silence is
# the stalls' own and no more, the late audio is not kept, and
# rate control is not pinned against a backlog. And with sync on:
# the writer waits, nothing is dropped.
ASAN_OPTIONS=detect_leaks=0 timeout 120 ./pipeline_rate_control_test 12 4 jitter
ASAN_OPTIONS=detect_leaks=0 timeout 120 ./pipeline_rate_control_test 12 4 sync-jitter
echo "[pass] pipeline_rate_control_test (late core, ASan)"
# The 64 ms default buffer, sync off, a steady core and a late one:
# the consumer's chunks are whole publishes and the pipe's fill
# swings by one with the phase; nothing is dropped from a steady
# core at any phase.
ASAN_OPTIONS=detect_leaks=0 timeout 120 ./pipeline_rate_control_test 16 4 big
ASAN_OPTIONS=detect_leaks=0 timeout 120 ./pipeline_rate_control_test 16 4 big-jitter
echo "[pass] pipeline_rate_control_test (64 ms device, ASan)"
# The producer held 4 ms every five seconds, as a loaded runner
# holds it: a publish pushed across a sink window boundary. The
# estimate must settle and apply about zero, not the shift.
ASAN_OPTIONS=detect_leaks=0 timeout 120 ./pipeline_rate_control_test 16 4 big-stall
echo "[pass] pipeline_rate_control_test (stalled producer, ASan)"
# A float core on a float ring into a float device: a signal a
# tenth of an int16 LSB high arrives as published, not as zero.
# Every run is seconds of audio against a device that drains
# in real time, on almost no CPU: all eight at once, so the
# step takes as long as the longest of them.
. "$GITHUB_WORKSPACE/.github/workflows/scripts/run-parallel.sh"
make clean && make -j$(nproc) all SANITIZER=address,undefined
mv pipeline_rate_control_test pipeline_rate_control_test_asan
ASAN_OPTIONS=detect_leaks=0 timeout 120 ./pipeline_rate_control_test 16 4 float
echo "[pass] pipeline_rate_control_test (float core, ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
test -x pipeline_rate_control_test_asan && test -x pipeline_rate_control_test
A="env ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1 timeout 120 ./pipeline_rate_control_test_asan"
par "pipeline_rate_control_test (ASan)" $A
par "pipeline_rate_control_test (late core, ASan)" $A 12 4 jitter
par "pipeline_rate_control_test (late core, Audio Sync, ASan)" $A 12 4 sync-jitter
par "pipeline_rate_control_test (64 ms device, ASan)" $A 16 4 big
par "pipeline_rate_control_test (64 ms device, late core, ASan)" $A 16 4 big-jitter
par "pipeline_rate_control_test (stalled producer, ASan)" $A 16 4 big-stall
par "pipeline_rate_control_test (float core, ASan)" $A 16 4 float
par "pipeline_rate_control_test (TSan)" env TSAN_OPTIONS=halt_on_error=1 \
timeout 240 ./pipeline_rate_control_test
par_wait
rm -f pipeline_rate_control_test_asan
TSAN_OPTIONS=halt_on_error=1 timeout 240 ./pipeline_rate_control_test
echo "[pass] pipeline_rate_control_test (TSan)"
- name: Build and run resampler_reset_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/resampler_reset
@@ -936,30 +703,6 @@ jobs:
./coreaudio_ring_test
echo "[pass] coreaudio_ring_test (ASan)"
- name: Build and run sdl_lost_wakeup_test (the SDL2 driver against SDL's dummy device)
shell: bash
working-directory: samples/audio/sdl_lost_wakeup
run: |
set -eu
# The producer's waits and the capture parks are measured; the
# lend pair is asserted: whole-frame spans, published to a
# device that pulls them, refused while stopped.
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
SDL_AUDIODRIVER=dummy timeout 300 ./sdl_lost_wakeup_test 1
echo "[pass] sdl_lost_wakeup_test (ASan)"
- name: Build and run coreaudio_write_test (the shipping writer, lend included, on stubs)
shell: bash
working-directory: samples/audio/coreaudio_write
run: |
set -eu
# run.py lifts the writer, the render callback and the lend
# pair out of audio/drivers/coreaudio.c and drives them on a
# simulated device clock; no Apple framework is involved.
python3 run.py
echo "[pass] coreaudio_write_test"
- name: Build and run asio_clock_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/asio_clock
@@ -1011,38 +754,12 @@ jobs:
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./asio_ring_test
echo "[pass] asio_ring_test (ASan)"
python3 asio_lend.py
- name: Build and run asio_teardown_test (TSan, ASan, MinGW under wine)
shell: bash
working-directory: samples/audio/asio_teardown
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
# The ASIO teardown's wait for a callback still inside after
# ASIOStop, the driver's code pulled out of asio.c: it ends as
# the last callback leaves, never while one is inside, and at
# 200 ms for one that never leaves. A build whose last callback
# out does not notify must fail.
for san in thread address,undefined; do
make clean && make -j$(nproc) all SANITIZER=$san
timeout 60 ./asio_teardown_test
done
make clean && make -j$(nproc) all TEST_DEFINES=-DASIO_TEST_NO_OUT_NOTIFY
if timeout 60 ./asio_teardown_test; then
echo "negative build passed"; exit 1
fi
make clean && make -j$(nproc) all CC=x86_64-w64-mingw32-gcc LDFLAGS=-static
WINEDEBUG=-all timeout 120 make check CC=x86_64-w64-mingw32-gcc LDFLAGS=-static
make clean
echo "[pass] asio_teardown_test"
- name: Build and run dsound_pump_test (MinGW, under wine)
shell: bash
working-directory: samples/audio/dsound_pump
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
# audio/drivers/dsound.c end to end on wine's DirectSound, fed
# by an ALSA null PCM, which plays at real-time pace on a
# runner with no sound card. Pins that the pump - which now
@@ -1051,8 +768,13 @@ jobs:
# millisecond - still moves audio through blocking writes,
# fills silence when the writer stops, and lets free() return
# at once while it waits.
if ! command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1 \
|| ! command -v wine >/dev/null 2>&1; then
sudo apt-get install -y -qq gcc-mingw-w64-x86-64 wine64 \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30
fi
printf 'pcm.!default { type null }\nctl.!default { type hw card 0 }\n' > ~/.asoundrc
make clean && make -j$(nproc) all
make clean all
WINEDEBUG=-all timeout 300 make check
echo "[pass] dsound_pump_test (wine)"
@@ -1061,7 +783,6 @@ jobs:
working-directory: samples/audio/wdmks_loop
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
# audio/drivers/wdmks.c compiled whole, its WaveRT loop driven
# by hand: the test owns the driver's state, points the
# position register at a word of its own and moves the
@@ -1078,41 +799,15 @@ jobs:
# milliseconds where it reports none; and that gaps in the
# audio are counted once each, neither a start nor every
# sample of a pause.
make clean && make -j$(nproc) all
if ! command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1 \
|| ! command -v wine >/dev/null 2>&1; then
sudo apt-get install -y -qq gcc-mingw-w64-x86-64 wine64 \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30
fi
make clean all
WINEDEBUG=-all timeout 120 make check
echo "[pass] wdmks_loop_test (wine)"
- name: Check MMDevice notification targets on both thread backends
shell: bash
working-directory: samples/audio/mmdevice_notification
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
for threads in 0 1; do
make clean check THREADS=$threads SANITIZER=address,undefined
make clean THREADS=$threads CC=x86_64-w64-mingw32-gcc LDFLAGS=-static && make -j$(nproc) all THREADS=$threads CC=x86_64-w64-mingw32-gcc LDFLAGS=-static
WINEDEBUG=-all wine ./mmdevice_notification_test.exe
done
make clean
- name: Build and run xaudio_lend_test (wine)
shell: bash
working-directory: samples/audio/xaudio_lend
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
# The XAudio2 driver lends the free span at the head of its
# buffers (write_begin / write_end), so the frontend's output
# lands in the buffer XAudio2 plays instead of being copied
# in by write(). On wine's XAudio2: a lend stays within the
# free room and the allocation, lends and writes make one
# stream, write_end publishes all it is given without
# waiting, an abandoned lend takes nothing, and lent audio
# plays at the pace written audio does.
make clean && make -j$(nproc) all
REQUIRE_XAUDIO=1 WINEDEBUG=-all timeout 120 make check
echo "[pass] xaudio_lend_test (wine)"
- name: Build and run wasapi_exclusive_pacing_test (ASan + UBSan, then TSan)
shell: bash
working-directory: samples/audio/wasapi_exclusive_pacing
@@ -1128,24 +823,14 @@ jobs:
# thread and the drain-first shared write this run gave 3-10% of
# periods unanswered; the first smaller-period attempt without the
# pump gave 75%.
# Each scenario is seconds of a fake device on the wall clock,
# on next to no CPU: every scenario under both sanitizers at
# once, so the step takes as long as one scenario.
. "$GITHUB_WORKSPACE/.github/workflows/scripts/run-parallel.sh"
make clean && make -j$(nproc) all SANITIZER=address,undefined
mv wasapi_exclusive_pacing_test wasapi_exclusive_pacing_test_asan
test -x wasapi_exclusive_pacing_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 120 \
./wasapi_exclusive_pacing_test 3
echo "[pass] wasapi_exclusive_pacing_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
test -x wasapi_exclusive_pacing_test_asan && test -x wasapi_exclusive_pacing_test
n=$(PACING_SCENARIO=count ./wasapi_exclusive_pacing_test_asan)
for sc in $(seq 0 $((n - 1))) rest; do
par "wasapi_exclusive_pacing_test $sc (ASan)" env PACING_SCENARIO=$sc \
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 \
timeout 120 ./wasapi_exclusive_pacing_test_asan 3
par "wasapi_exclusive_pacing_test $sc (TSan)" env PACING_SCENARIO=$sc \
timeout 180 ./wasapi_exclusive_pacing_test 3
done
par_wait
rm -f wasapi_exclusive_pacing_test_asan
timeout 180 ./wasapi_exclusive_pacing_test 3
echo "[pass] wasapi_exclusive_pacing_test (TSan)"
- name: Build and run sink_rate_test (ASan + UBSan)
shell: bash
@@ -1260,108 +945,6 @@ jobs:
echo "AVX unavailable on this runner; scalar/SSE tests ran above."
fi
- name: Build and run sinc kernel dispatch test (C89, ASan + UBSan)
working-directory: samples/audio/sinc_dispatch
run: |
# A baseline build carries the AVX and AVX-512 kernels through
# per-function targets and runs each one the runner supports
# against the scalar kernel; the -mavx build must agree.
make -j$(nproc) check SANITIZER=address,undefined
if grep -qw avx /proc/cpuinfo; then
make clean
make -j$(nproc) check CC="gcc -mavx" SANITIZER=address,undefined
fi
- name: Build and run sinc fast-forward test (C89, ASan + UBSan, MinGW)
working-directory: samples/audio/sinc_fastforward
run: |
# Live ratios under the table's design are decimated first:
# rejection as a table built for that ratio, the nominal path
# untouched, the output bound, crossfaded stage changes.
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
. "$GITHUB_WORKSPACE/.github/workflows/scripts/run-parallel.sh"
# Each build its own binary, then the runs at once: each is one
# thread, so the runner's cores take them side by side.
make clean
make TARGET=sff_asan SANITIZER=address,undefined
par "sinc_fastforward_test (ASan)" ./sff_asan
if grep -qw avx /proc/cpuinfo; then
make TARGET=sff_avx CC="gcc -mavx" SANITIZER=address,undefined
par "sinc_fastforward_test (AVX, ASan)" ./sff_avx
fi
make TARGET=sff_mingw CC=x86_64-w64-mingw32-gcc
par "sinc_fastforward_test (MinGW, wine)" env WINEDEBUG=-all \
timeout 300 wine ./sff_mingw.exe
par_wait
rm -f sff_asan sff_avx sff_mingw.exe
- name: Build and run sinc sibling test (C89, ASan + UBSan, MinGW)
working-directory: samples/audio/sinc_sibling
run: |
# Siblings share their parent's tables: a fresh stream either
# way, own state only, either free order.
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
. "$GITHUB_WORKSPACE/.github/workflows/scripts/run-parallel.sh"
make clean
make TARGET=sibling_asan SANITIZER=address,undefined
make TARGET=sibling_mingw CC=x86_64-w64-mingw32-gcc
par "sinc_sibling_test (ASan)" ./sibling_asan
par "sinc_sibling_test (MinGW, wine)" env WINEDEBUG=-all \
timeout 300 wine ./sibling_mingw.exe
par_wait
rm -f sibling_asan sibling_mingw.exe
- name: Build and run mic_handshake_test (ASan + UBSan)
working-directory: samples/audio/mic_handshake
run: |
# The shipping capture worker against a clocked fake device, and
# only the resampler the microphone flush uses being built.
make clean
make -j$(nproc) SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
timeout 300 ./mic_handshake_test 1
- name: Build and run pipeline_format_test (ASan + UBSan)
working-directory: samples/audio/pipeline_format
run: |
# Real init and one batch through each format and transport;
# the integer front pair exists only behind its hint.
make -j$(nproc) check SANITIZER=address,undefined
- name: Build and run pipeline_rate_change_test (ASan + UBSan, mingw)
working-directory: samples/audio/pipeline_rate_change
run: |
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
# A core rate change taken by the running driver: one device
# open, the tone at its pitch on both sides, the ring grown
# where the new rate needs it, time stretch refused.
make -j$(nproc) check SANITIZER=address,undefined
make clean
WINEDEBUG=-all timeout 300 make check CC=x86_64-w64-mingw32-gcc \
LDFLAGS="-lm -static" RUN="wine ./pipeline_rate_change_test.exe"
- name: Build and run unity_identity_test (plain, ASan + UBSan)
working-directory: samples/audio/unity_identity
run: |
# The unity passthrough end to end: an s16 batch at a pinned
# ratio of 1.0 reaches an s16 device with zero conversions,
# counted through linker wraps; the fallbacks still convert.
make -j$(nproc) check
make clean
make -j$(nproc) check SANITIZER=address,undefined
- name: Build and run lend_write_test (plain, ASan + UBSan)
working-directory: samples/audio/lend_write
run: |
# The driver lend pair: the pipeline produces its output in
# the driver's own buffer, bit-identical to the written
# stream, with write() never called while a lend is live.
make -j$(nproc) check
make clean
make -j$(nproc) check SANITIZER=address,undefined
- name: Build and run extra-channel capacity test (ASan + UBSan)
working-directory: samples/audio/extra_capacity
run: |
@@ -1369,71 +952,7 @@ jobs:
make clean
make -j$(nproc) check SIMD_MASK=RESAMPLER_SIMD_SSE SANITIZER=address,undefined
- name: Build and run the pipeline fill cap lane (plain)
shell: bash
working-directory: samples/audio/pipeline_clocked
run: |
set -eu
# The threaded pipeline against a device that drains on a
# clock, with Audio Sync the only thing pacing the core: the
# ring sits full and every publish waits behind it. With
# audio_pipeline_fill_cap the queue has to come down to the
# device's buffer and no more than a publish past it, where a
# blocking inline write leaves it, without the device running
# dry. With Audio Sync off it has to take the queue down too,
# with a core up to a frame late not reaching the device as
# silence. And display-paced with Audio Sync on, rate control
# has to hold the queue where the frame-synchronous path
# holds it. With audio the only clock, rate control has to
# leave the ratio alone, inline and threaded, and still hold
# the fill when a present blocks behind the runloop's back.
# And neither leaving fast-forward nor resuming from a pause
# may hold the core while a queue plays out, threaded or
# inline (#19940).
# Plain, not sanitized: it is the clock that is measured,
# and a sanitizer's slowdown is a host that starves the
# consumer whatever the cap does. Underruns with the cap are
# retried, since a host that takes the consumer off its core
# shows the same with the cap off; only a cap that never runs
# clean fails.
# Its lanes run in real time on next to no CPU, so they run
# at once, one setting each: the step takes as long as the
# longest setting, about 12 s, not the longest case.
. "$GITHUB_WORKSPACE/.github/workflows/scripts/run-parallel.sh"
make clean && make -j$(nproc)
test -x pipeline_clocked_test
for lane in audio_paced_16 audio_paced_32 audio_paced_64 \
setpoint_16 setpoint_32 setpoint_64 \
rate_control_32 rate_control_64 sync_off \
ff_exit_1 ff_exit_2 ff_exit_3 ff_exit_4 ff_exit_5; do
par "pipeline_clocked_test (fill cap: $lane)" \
env PACED_ONLY=$lane timeout 300 ./pipeline_clocked_test 3
done
par_wait
- name: Build and run resampler option tests (C89, ASan + UBSan)
working-directory: samples/audio/resampler_options
run: |
make -j$(nproc) check SANITIZER=address,undefined
- name: Build and run CoreMIDI input queue test (ASan + UBSan, TSan)
working-directory: samples/midi/coremidi_queue
run: |
# midi/drivers/coremidi_queue.h is the macOS driver's lock-free
# input queue; it builds and runs anywhere.
make check SANITIZER=address,undefined
make clean
make check SANITIZER=thread
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
+58 -169
View File
@@ -9,8 +9,6 @@ on:
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
- 'camera/drivers/**'
- 'samples/camera/**'
- 'samples/cores/**'
- '.github/workflows/Linux-samples-cores.yml'
pull_request:
@@ -21,8 +19,6 @@ on:
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
- 'camera/drivers/**'
- 'samples/camera/**'
- 'samples/cores/**'
- '.github/workflows/Linux-samples-cores.yml'
workflow_dispatch:
@@ -41,53 +37,49 @@ jobs:
samples-cores:
name: Build and run samples/cores
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential pkg-config ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libv4l-dev libasound2-dev ccache libavdevice-dev libavfilter-dev libpipewire-0.3-dev mesa-vulkan-drivers
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential pkg-config ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Select software Vulkan for CPU fixtures
run: |
set -eu
for icd in /usr/share/vulkan/icd.d/lvp_icd*.json; do
if [ -f "$icd" ]; then
printf 'VK_ICD_FILENAMES=%s\n' "$icd" >> "$GITHUB_ENV"
exit 0
fi
done
echo "Lavapipe ICD is missing" >&2
exit 1
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -97,10 +89,11 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build and run camera ffmpeg_live_test (plain, ASan + UBSan, TSan)
@@ -108,73 +101,32 @@ jobs:
working-directory: samples/camera/ffmpeg_live
run: |
set -eu
sudo apt-get update -qq
sudo apt-get install -y -qq libavdevice-dev libavfilter-dev
# The camera driver against lavfi: built with its input
# format set to libavfilter, a filter graph is the device and
# the whole pipeline runs with no camera attached - avformat
# opens the source, the poll thread reads, the decoder
# decodes, swscale converts and poll() takes the newest
# finished frame.
# decodes, swscale converts and poll() takes the frame out
# under the buffer's lock.
#
# The cases are the ones the threading has to get right and
# that no eyeball on a webcam would show: start and stop
# repeatedly, stop while the thread is mid-frame, free
# without stopping, poll before starting, a source that
# does not exist, a poll that must show the last frame
# decoded, and a slow poll the thread must not wait on. Leak
# checking is on: a packet or plane kept per frame or per
# start is a leak report.
make clean && make -j$(nproc) all
# without stopping, poll before starting, and a source that
# does not exist.
make clean all
./ffmpeg_live_test
echo "[pass] ffmpeg_live_test"
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
make clean all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
timeout 600 ./ffmpeg_live_test
echo "[pass] ffmpeg_live_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1:suppressions=../../cores/ffmpeg_audio_pipe/tsan.supp \
timeout 600 ./ffmpeg_live_test
echo "[pass] ffmpeg_live_test (TSan)"
- name: Build and run camera pipewire_poll_test (plain, ASan + UBSan)
shell: bash
working-directory: samples/camera/pipewire_poll
run: |
set -eu
# The pipewire camera driver's poll against a scripted
# stream, the pw_stream calls link-wrapped: an empty queue
# returns at once, and every buffer the poll takes - valid,
# corrupted or without CPU data - is queued back. The check
# target bounds the run: a poll that waits for a frame is
# the failure.
make clean check
echo "[pass] pipewire_poll_test"
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
timeout 60 ./pipewire_poll_test
echo "[pass] pipewire_poll_test (ASan)"
- name: FFmpeg hardware-context replacement (plain, ASan + UBSan)
working-directory: samples/cores/ffmpeg_hw_context
run: |
set -eu
make clean
make check
make clean
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 \
make check SANITIZER=address,undefined
- name: FFmpeg subtitle hand-off to the renderer (plain, ASan + UBSan, TSan)
working-directory: samples/cores/ffmpeg_ass_events
run: |
set -eu
make clean
make check
make clean
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 \
make check SANITIZER=address,undefined
make clean
TSAN_OPTIONS=halt_on_error=1 make check SANITIZER=thread
- name: Build and run ffmpeg_sweep_test (plain, ASan + UBSan, TSan)
shell: bash
working-directory: samples/cores/ffmpeg_sweep
@@ -189,48 +141,21 @@ jobs:
# empty or absent, then teardown while the decode thread is
# still working.
#
# With leak detection: every load and unload in it, the
# decoder probing included, must give back its codec
# contexts and hardware devices. The libav* TSan
# suppressions are the audio-pipe lane's, for the same
# reason.
make clean && make -j$(nproc) all
# Leak detection off: libavutil's HW-device probing keeps a
# few objects, as the audio-pipe lane already has it. The
# libav* TSan suppressions are the same ones and for the
# same reason.
make clean all
./ffmpeg_sweep_test
echo "[pass] ffmpeg_sweep_test"
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
make clean all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=0:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 900 ./ffmpeg_sweep_test
echo "[pass] ffmpeg_sweep_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1:suppressions=../ffmpeg_audio_pipe/tsan.supp \
timeout 900 ./ffmpeg_sweep_test
echo "[pass] ffmpeg_sweep_test (TSan)"
# The standalone core's own makefiles: a link with
# --no-undefined is the check their source lists are whole,
# and a dry run with GL (no GL headers here) the check that
# the GL build's list resolves. The sample's objects share
# paths with the core's libretro-common ones: cleaned first.
make clean
make -n -C ../../../cores/libretro-ffmpeg OPENGL=1 >/dev/null
make -C ../../../cores/libretro-ffmpeg -j2 OPENGL=0 HAVE_SSA=0
make -C ../../../cores/libretro-ffmpeg clean OPENGL=0 HAVE_SSA=0
echo "[pass] standalone ffmpeg core links"
- name: Build and run ffmpeg_finished_wait_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/cores/ffmpeg_finished_wait
run: |
set -eu
# The main thread's wait for a finished video slot ends when
# the decode thread does, at the end of a clip, instead of
# holding retro_run() on a slot nothing will finish.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1 \
timeout 60 ./ffmpeg_finished_wait_test
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1:suppressions=../ffmpeg_audio_pipe/tsan.supp \
timeout 60 ./ffmpeg_finished_wait_test
echo "[pass] ffmpeg_finished_wait_test"
- name: Build and run ffmpeg_audio_pipe_test (ASan + UBSan, TSan)
shell: bash
@@ -245,13 +170,13 @@ jobs:
# teardown mid-stream, all on a watchdog. Needs the ffmpeg
# CLI to generate the clip. Leak detection off: libavutil's
# own HW-device probing allocates and keeps a few objects.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x ffmpeg_audio_pipe_test
ASAN_OPTIONS=detect_leaks=0:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 300 \
./ffmpeg_audio_pipe_test
echo "[pass] ffmpeg_audio_pipe_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
# The libav* libraries are uninstrumented, so TSan cannot see
# the atomics that order an AVBufferRef's reference count and
# reports the allocation and the release as a race. Only
@@ -260,39 +185,3 @@ jobs:
TSAN_OPTIONS=halt_on_error=1:suppressions=tsan.supp \
timeout 300 ./ffmpeg_audio_pipe_test
echo "[pass] ffmpeg_audio_pipe_test (TSan)"
- name: Build and run videoproc_audio_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/cores/videoproc_audio
run: |
set -eu
# cores/libretro-video-processor's ALSA capture handle between
# the frontend's audio thread, which keeps calling the core's
# audio callback, and the main thread opening and closing the
# device under it: no read on a closed handle - a close that
# lands mid-read included - and no lock taken by the callback.
# The device is ALSA's null PCM; the capture read is a
# stand-in.
make clean && make -j$(nproc) all
timeout 120 ./videoproc_audio_test
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
timeout 120 ./videoproc_audio_test
echo "[pass] videoproc_audio_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./videoproc_audio_test
echo "[pass] videoproc_audio_test (TSan)"
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
+45 -217
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-samples-formats.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-samples-formats.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -32,44 +20,52 @@ concurrency:
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
formats-core:
name: Core format decoders and containers
samples-formats:
name: Build and run samples/formats
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential ffmpeg clang ccache
timeout-minutes: 30
timeout-minutes: 10
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential ffmpeg"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -79,21 +75,13 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: HEVC hidden pictures and prior-output discard
run: make -C libretro-common/samples/formats/h265 output-flags-check SANITIZER=address,undefined
- name: HEVC parameter replacement and output ownership (TSan)
run: TSAN_OPTIONS=halt_on_error=1 make -C libretro-common/samples/formats/h265 -B output-flags-check SANITIZER=thread
- name: MP4 hidden-picture timestamps, seeks and partial input
run: make -C libretro-common/samples/formats/vp9 mp4-h26x-check SANITIZER=address,undefined
- name: Build and run dts_lpcm_test (plain, ASan + UBSan)
shell: bash
working-directory: samples/formats/dts_lpcm
@@ -124,10 +112,10 @@ jobs:
# decoder is for: every frame repacked to the plain core,
# put in the IEC 61937 burst its sample count calls for, and
# read back out of that burst byte for byte.
make clean && make -j$(nproc) all
make clean all
./dts_lpcm_test
echo "[pass] dts_lpcm_test"
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./dts_lpcm_test
echo "[pass] dts_lpcm_test (ASan)"
@@ -164,7 +152,7 @@ jobs:
# paths and report a pass. That count is kept per format, not
# just in total, so one decoder quietly ceasing to accept its
# seed cannot hide behind the other three.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x image_decode_fuzz_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 \
timeout 120 ./image_decode_fuzz_test
@@ -229,168 +217,8 @@ jobs:
# begin on, it must accept before the whole file has arrived
# (or partial decoding is silently off), and it must be
# monotonic in the prefix length.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x image_avail_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 \
timeout 120 ./image_avail_test
echo "[pass] image_avail_test"
- name: AV1 picture tools, frame prefixes, tiles and container packets (ASan + UBSan)
working-directory: libretro-common/samples/formats/av1
run: |
make check SANITIZER=address,undefined
python3 fixtures.py
python3 tile_fixtures.py
python3 frame_fixtures.py
python3 picture_fixtures.py
python3 reference_fixtures.py
python3 grain_fixtures.py
python3 state_fixtures.py
- name: Vulkan AV1 parameters against real streams (ASan + UBSan)
working-directory: samples/gfx/vulkan_video_caps
run: |
make av1_params_test SANITIZER=address,undefined
python3 av1_fixtures.py
- name: Build and run video_hdr_fp16_test (ASan + UBSan + LSan)
shell: bash
working-directory: samples/formats/video_hdr_fp16
run: |
set -eu
# HDR10 video to linear scRGB half floats: HEVC Main10 in MP4
# and VP9 profile 2 in WebM, tagged PQ, decode flat grey onto
# the PQ EOTF when asked into the caller's frame; their
# SDR-tagged twins, and any stream decoding into its own
# canvas, keep the 32-bit paths. Fixtures made with ffmpeg
# (libx265, libvpx-vp9) from known 10-bit grey.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 \
timeout 120 ./video_hdr_fp16_test
- name: Build and run image_tile_gx_test (ASan + UBSan + LSan)
shell: bash
working-directory: samples/formats/image_tile_gx
run: |
set -eu
# The GameCube/Wii GX RGBA8 tiling the gx driver's overlays
# are sampled in, which runs nowhere but on the console. It
# is checked against the layout's definition and against
# the band conversion it replaced, over every size up to
# 70x44 so widths and heights off a multiple of four - where
# the source pitch and the tile width part ways - are all
# covered.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
test -x image_tile_gx_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 \
timeout 120 ./image_tile_gx_test
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
vp9-matroska:
name: VP9 and Matroska codec conformance
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential ffmpeg clang ccache
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Enable ccache
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -z
- name: VP9 sessions and WebM GPU dispatch (ASan + UBSan)
working-directory: libretro-common/samples/formats/vp9
run: |
make check stream-check h26x-check h26x-color-check pixel-check SANITIZER=address,undefined
make stack-check CC=gcc
make stack-check CC=clang
H26X_TEST_THREADS=4 make h26x-check h26x-color-check SANITIZER=address,undefined
- name: Matroska concurrent decode and output ownership (TSan)
working-directory: libretro-common/samples/formats/vp9
run: |
make -B rwebm_h26x_stream_test rwebm_h26x_hw_test SANITIZER=thread
H26X_TEST_THREADS=4 TSAN_OPTIONS=halt_on_error=1 make h26x-check SANITIZER=thread
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
samples-formats:
name: Build and run samples/formats
runs-on: ubuntu-latest
needs: [formats-core, vp9-matroska]
if: always()
timeout-minutes: 1
steps:
- name: Require both format suites
env:
FORMATS_RESULT: ${{ needs.formats-core.result }}
CODECS_RESULT: ${{ needs.vp9-matroska.result }}
run: |
test "$FORMATS_RESULT" = success
test "$CODECS_RESULT" = success
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+58 -124
View File
@@ -4,43 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/network/cheevos_login/**'
- 'samples/network/gdrive_backup/**'
- 'samples/network/net_http_semantics/**'
- 'samples/network/nfs_backup/**'
- 'samples/network/s3_backup/**'
- 'samples/network/smb_backup/**'
- 'samples/network/webdav_backup/**'
- 'samples/network/webdav_options/**'
- 'samples/network/webdav_reauth/**'
- '.github/workflows/Linux-samples-network.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/network/cheevos_login/**'
- 'samples/network/gdrive_backup/**'
- 'samples/network/net_http_semantics/**'
- 'samples/network/nfs_backup/**'
- 'samples/network/s3_backup/**'
- 'samples/network/smb_backup/**'
- 'samples/network/webdav_backup/**'
- 'samples/network/webdav_options/**'
- 'samples/network/webdav_reauth/**'
- '.github/workflows/Linux-samples-network.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -57,41 +23,49 @@ jobs:
samples-network:
name: Build and run samples/network
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libmbedtls-dev libbearssl-dev ccache
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential libmbedtls-dev libbearssl-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -101,10 +75,11 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build and run webdav_options_test (ASan + UBSan, TSan)
@@ -124,13 +99,13 @@ jobs:
# WebDAV methods, HTTP/2 lowercase field names, plain HTTP
# with and without PUT, empty and NULL header lists, and
# whole-token matching (PROPFINDX must not match PROPFIND).
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x webdav_options_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./webdav_options_test
echo "[pass] webdav_options_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./webdav_options_test
echo "[pass] webdav_options_test (TSan)"
@@ -152,13 +127,13 @@ jobs:
# A malformed challenge (a value with no closing quote, a
# trailing unquoted parameter) must be refused, not crash the
# parser or send it reading past the end of the line.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x webdav_reauth_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./webdav_reauth_test
echo "[pass] webdav_reauth_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./webdav_reauth_test
echo "[pass] webdav_reauth_test (TSan)"
@@ -177,13 +152,13 @@ jobs:
# back up", a failed backup stopping the upload, destructive
# sync and the server manifest skipping the backup, and COPY
# and PUT each getting their own Digest retry.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x webdav_backup_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./webdav_backup_test
echo "[pass] webdav_backup_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./webdav_backup_test
echo "[pass] webdav_backup_test (TSan)"
@@ -202,13 +177,13 @@ jobs:
# failed copy (including a 200 with an <Error> body) stopping
# the delete or upload, and destructive sync and the server
# manifest skipping the copy.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x s3_backup_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./s3_backup_test
echo "[pass] s3_backup_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./s3_backup_test
echo "[pass] s3_backup_test (TSan)"
@@ -229,43 +204,16 @@ jobs:
# the old file intact with no temporary file left, no backup
# for destructive sync, a new file or the manifest, an empty
# upload and the configured subdirectory.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x smb_backup_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./smb_backup_test
echo "[pass] smb_backup_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./smb_backup_test
echo "[pass] smb_backup_test (TSan)"
- name: Build and run nfs_backup_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/network/nfs_backup
run: |
set -eu
# Includes network/cloud_sync/nfs.c and runs it against an
# in-memory export (fake_nfs.c) keeping net_nfs3.c's status
# contract. A download is written beside the local file and
# renamed over it once complete; only the server answering
# NOENT reads as "not there"; an upload is one RENAME over the
# old file, kept as <path>-<time>[-n] with destructive sync
# off. Covers failed opens and partial reads leaving the local
# save intact, unanswered stat/unlink failing instead of
# reporting a missing file or a delete, failed write, backup
# and final rename leaving the old file and no temporary, the
# manifest skipping the backup, refused over-long names, the
# subdirectory and a concurrent MKDIR.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
test -x nfs_backup_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./nfs_backup_test
echo "[pass] nfs_backup_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./nfs_backup_test
echo "[pass] nfs_backup_test (TSan)"
- name: Build and run gdrive_backup_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/network/gdrive_backup
@@ -281,13 +229,13 @@ jobs:
# copy and on the PATCH each refreshing the token once (the
# PATCH retry repeating only the PATCH, not the backup), and
# destructive sync, a new file and the manifest skipping it.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x gdrive_backup_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./gdrive_backup_test
echo "[pass] gdrive_backup_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./gdrive_backup_test
echo "[pass] gdrive_backup_test (TSan)"
@@ -311,22 +259,22 @@ jobs:
# net_http must send the same upload a slice per update, plain
# and over TLS - it used to go out in one blocking send, a call
# of a second or more (spinning at 100% CPU on a plain socket).
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x cheevos_login_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 timeout 120 \
make check
echo "[pass] cheevos_login_test (BearSSL, ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 180 make check
echo "[pass] cheevos_login_test (BearSSL, TSan)"
make clean SSL_BACKEND=mbed SANITIZER=address,undefined && make -j$(nproc) all SSL_BACKEND=mbed SANITIZER=address,undefined
make clean all SSL_BACKEND=mbed SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 timeout 120 \
make check SSL_BACKEND=mbed
echo "[pass] cheevos_login_test (mbedTLS, ASan)"
# The built-in client, RetroArch's default backend.
make clean SSL_BACKEND=retro SANITIZER=address,undefined && make -j$(nproc) all SSL_BACKEND=retro SANITIZER=address,undefined
make clean all SSL_BACKEND=retro SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 timeout 120 \
make check SSL_BACKEND=retro
@@ -341,12 +289,12 @@ jobs:
mbed_ver=3.6.0
mbed_sha=3ecf94fcfdaacafb757786a01b7538a61750ebd85c4b024f56ff8ba1490fcd38
mbed_tar="$RUNNER_TEMP/mbedtls-$mbed_ver.tar.bz2"
if curl -fsSL --retry 8 --retry-all-errors --retry-max-time 300 --max-time 120 -o "$mbed_tar" \
if curl -fsSL --retry 3 --retry-delay 5 --max-time 120 -o "$mbed_tar" \
"https://github.com/Mbed-TLS/mbedtls/releases/download/v$mbed_ver/mbedtls-$mbed_ver.tar.bz2"; then
echo "$mbed_sha $mbed_tar" | sha256sum -c -
tar -xjf "$mbed_tar" -C "$RUNNER_TEMP"
make -C "$RUNNER_TEMP/mbedtls-$mbed_ver" -j"$(nproc)" lib >/dev/null
make clean SSL_BACKEND=mbed SANITIZER=address,undefined && make -j$(nproc) all SSL_BACKEND=mbed SANITIZER=address,undefined \
make clean all SSL_BACKEND=mbed SANITIZER=address,undefined \
MBEDTLS_DIR="$RUNNER_TEMP/mbedtls-$mbed_ver"
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 timeout 120 \
@@ -401,25 +349,11 @@ jobs:
echo "::error title=net_http lock::net_http.c must not take locks"
exit 1
fi
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 timeout 120 \
./net_http_semantics_test
echo "[pass] net_http_semantics_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./net_http_semantics_test
echo "[pass] net_http_semantics_test (TSan)"
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
+40 -163
View File
@@ -6,13 +6,6 @@ on:
- master
paths:
- 'record/**'
- 'libretro-common/net/net_rtmp*'
- 'libretro-common/include/net/net_rtmp*'
- 'libretro-common/formats/flv/**'
- 'libretro-common/include/formats/rflv_mux.h'
- 'libretro-common/samples/net/rtmp/**'
- 'libretro-common/samples/formats/flv/**'
- 'gfx/common/videotoolbox_encode*.h'
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
@@ -23,13 +16,6 @@ on:
- master
paths:
- 'record/**'
- 'libretro-common/net/net_rtmp*'
- 'libretro-common/include/net/net_rtmp*'
- 'libretro-common/formats/flv/**'
- 'libretro-common/include/formats/rflv_mux.h'
- 'libretro-common/samples/net/rtmp/**'
- 'libretro-common/samples/formats/flv/**'
- 'gfx/common/videotoolbox_encode*.h'
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
@@ -51,41 +37,49 @@ jobs:
samples-record:
name: Build and run samples/record
runs-on: ubuntu-latest
env:
APT_PKGS: mingw-w64 wine build-essential pkg-config ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev ccache
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential pkg-config libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -95,10 +89,11 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Build and run ffmpeg_pipeline_test (ASan + UBSan, TSan)
@@ -114,130 +109,12 @@ jobs:
# under contention, the full-queue wait, and the drain after
# the encoder thread is joined. Needs libavcodec with
# libx264rgb (Ubuntu's has it).
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x ffmpeg_pipeline_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 300 \
./ffmpeg_pipeline_test
echo "[pass] ffmpeg_pipeline_test (ASan)"
make clean SANITIZER=thread && make -j$(nproc) all SANITIZER=thread
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./ffmpeg_pipeline_test
echo "[pass] ffmpeg_pipeline_test (TSan)"
# The same run on a video ring that cannot be mirrored, as on
# a platform without a double mapping: frames that straddle
# the wrap go through the encoder side's scratch copy.
make clean SANITIZER=address,undefined PLAIN_RING=1 && make -j$(nproc) all SANITIZER=address,undefined PLAIN_RING=1
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 300 \
./ffmpeg_pipeline_test
echo "[pass] ffmpeg_pipeline_test (plain ring, ASan)"
- name: Native overlapped file output
working-directory: samples/record/file_win32
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make clean && make check SANITIZER=address,undefined
make clean && make check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
- name: Native MP4 mux (ASan + UBSan, mingw-w64)
shell: bash
working-directory: samples/record/mp4_mux
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make clean && make -j$(nproc) check SANITIZER=address,undefined
make clean && make -j$(nproc) check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
- name: Native FLV mux (ASan + UBSan, mingw-w64)
shell: bash
working-directory: libretro-common/samples/formats/flv
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make clean && make check stream-check SANITIZER=address,undefined
make clean && make check stream-check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
- name: RTMP protocol and sockets (ASan + UBSan, mingw-w64)
shell: bash
working-directory: libretro-common/samples/net/rtmp
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make clean && make check peer-check SANITIZER=address,undefined
make clean && make check peer-check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
- name: GPU PCM output pipeline (ASan + UBSan, TSan, mingw-w64)
working-directory: samples/record/gpu_av_output
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make clean && make -j$(nproc) check SANITIZER=address,undefined
make clean && make thread_test session_test vulkan_thread_test SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./thread_test
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./session_test
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./vulkan_thread_test
make clean && make -j$(nproc) check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
- name: GPU recording dispatcher (ASan + UBSan, TSan, mingw-w64)
working-directory: samples/record/gpu_dispatch
run: |
set -eu
make clean && make check SANITIZER=address,undefined
make clean && make dispatch_test session_integration SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./dispatch_test
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./session_integration
# one Wine server for the three tests: one each, a test that
# starts as the last server leaves is cut off before main()
wineserver -p
trap 'wineserver -k || true' EXIT
make clean && make check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
- name: Native recording frontend clock and PCM (ASan + UBSan, mingw-w64)
working-directory: samples/record/nvenc_frontend
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make clean && make check SANITIZER=address,undefined
make clean && make check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
# The Apple API stand-in checks ownership/configuration only. Native
# compilation and hardware encode run in MacOS-videotoolbox-encode.yml.
- name: VideoToolbox encode callback and session contracts
working-directory: samples/record/videotoolbox_encode
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make clean && make check thread_test worker_thread_test audio_thread_test av_session_thread_test SANITIZER=address,undefined
./thread_test
./worker_thread_test
./audio_thread_test
./av_session_thread_test
make clean && make thread_test worker_thread_test audio_thread_test av_session_thread_test SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./thread_test
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./worker_thread_test
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./audio_thread_test
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./av_session_thread_test
make clean && make check CC=x86_64-w64-mingw32-gcc EXE=.exe RUNNER=wine
make clean
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
+39 -149
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-samples-settings.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-samples-settings.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -32,92 +20,52 @@ concurrency:
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
ps3-user-paths:
name: PS3 per-user directories
runs-on: ubuntu-latest
timeout-minutes: 15
env:
APT_PKGS: gcc-mingw-w64-x86-64 wine64
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 15
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: Regression test
working-directory: samples/frontend/ps3_user_paths
run: |
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
# Each console user's own directory, the shared USRDIR layout
# when it cannot be used, a user's first boot copying the
# shared data, and one copy per imported configuration.
make clean
make -j$(nproc) SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=halt_on_error=1 ./ps3_user_paths_test
make clean
make -j$(nproc) CC=x86_64-w64-mingw32-gcc TARGET=ps3_user_paths_test.exe
WINEDEBUG=-all timeout 300 wine ./ps3_user_paths_test.exe
make clean TARGET=ps3_user_paths_test.exe
samples-settings:
name: Build and run samples/settings
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential ccache
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
@@ -127,35 +75,13 @@ jobs:
- name: Enable ccache
run: |
set -eu
command -v ccache >/dev/null 2>&1 || sudo apt-get install -y -qq ccache
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
ccache -M 250M
ccache -M 500M
ccache -z
- name: Settings definitions keep their keys and defaults
run: |
set -eu
python3 tools/settings_check_test.py
python3 tools/settings_check.py table --check tools/settings_table.reference
python3 tools/settings_check.py unity
- name: Settings lists have room for what they are given
shell: bash
run: |
set -eu
# configuration.c builds each list of settings into an array
# of a fixed size. One setting too many for its list wrote
# past the end of the array, and RetroArch died of heap
# corruption at startup: two per-port string settings did it
# to the string list. The lists now refuse what they have no
# room for; this counts, in the preprocessed source and for
# each build profile, what every list is given against the
# size it is allocated with, so that the next one is found
# here.
timeout 300 tools/check.sh tools/settings_capacity_check.c
echo "[pass] settings_capacity_check"
- name: Build and run pipeline_migration_test (ASan + UBSan)
shell: bash
working-directory: samples/settings/pipeline_migration
@@ -172,45 +98,9 @@ jobs:
# multi-character values are untouched. The rule under test
# is restated from config_load_file(), which needs most of the
# frontend to run; a change to one must be made in the other.
make clean SANITIZER=address,undefined && make -j$(nproc) all SANITIZER=address,undefined
make clean all SANITIZER=address,undefined
test -x pipeline_migration_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./pipeline_migration_test
echo "[pass] pipeline_migration_test (ASan)"
- name: Build and run cli_override_rows_test (ASan + UBSan)
shell: bash
working-directory: samples/settings/cli_override_rows
run: |
set -eu
# Each command-line override (--log-file, --check-frames,
# --port) must pin its own setting's row: config_save_file()
# skips the row carrying a set override, so on another row it
# dropped that setting and saved the command-line value.
make clean && make check SANITIZER=address,undefined
- name: Build and run float_rows_test (ASan + UBSan)
shell: bash
working-directory: samples/settings/float_rows
run: |
set -eu
# Built without the menu: the float settings that are not the
# menu's (aspect ratio, refresh rate, fast-forward ratio, ...)
# must still be loaded and saved, and no setting of any kind
# may be listed twice.
make clean && make check SANITIZER=address,undefined
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
File diff suppressed because it is too large. Load diff
+45 -32
View File
@@ -24,41 +24,44 @@ jobs:
name: Samples no other job runs
runs-on: ubuntu-latest
timeout-minutes: 30
env:
APT_PKGS: build-essential gcc-mingw-w64-x86-64 wine64
steps:
- name: Install dependencies
timeout-minutes: 20
run: |
pkgs="build-essential"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only -o Acquire::Retries=3 \
-o Acquire::http::Timeout=30 $pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y -o Acquire::Retries=3 \
-o Acquire::http::Timeout=30 $pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 }}
# Up front, bounded, for the samples cross-built with mingw-w64 and
# run under Wine: installed inside the loop, a mirror that stalled
# held the job, silent, until its 30 minutes ran out
- name: Install dependencies
timeout-minutes: 15
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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Run them
shell: bash
run: |
@@ -72,9 +75,12 @@ jobs:
#
# Samples that need a library the runner does not carry
# (SDL, FFmpeg, libusb) are skipped: their own workflows
# install what they need. mingw-w64 and Wine come from the
# install step, for the samples cross-built and run under Wine.
# install what they need. A sample cross-built with mingw-w64
# and run under Wine gets both installed here, the first time
# one turns up, so it runs rather than fails for want of a
# compiler.
fails=0
wine_ready=0
for mk in $(find samples libretro-common/samples -name Makefile | sort); do
dir=$(dirname "$mk")
name=$(basename "$dir")
@@ -86,6 +92,13 @@ jobs:
echo "-- skip $dir (needs a library this job does not install)"
continue
fi
if [ $wine_ready -eq 0 ] && grep -qE 'mingw32-|wine' "$mk"; then
sudo apt-get update -y -qq -o Acquire::Retries=3 \
-o Acquire::http::Timeout=30 >/dev/null || true
sudo apt-get install -y -qq gcc-mingw-w64-x86-64 wine64 \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30
wine_ready=1
fi
echo "== $dir"
if (cd "$dir" && make clean >/dev/null 2>&1 \
&& ASAN_OPTIONS=detect_leaks=1:allocator_may_return_null=1 \
@@ -49,9 +49,6 @@ jobs:
timeout-minutes: 15
steps:
- uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: state_rewind
run: make -C samples/state_rewind clean check
- name: runahead
@@ -65,9 +62,6 @@ jobs:
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
steps:
- uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: state_rewind (ASan + UBSan)
run: make -C samples/state_rewind clean check SANITIZER=address,undefined
- name: runahead (ASan + UBSan)
+34 -43
View File
@@ -18,21 +18,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-tsan-harness.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-tsan-harness.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -48,41 +36,44 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
env:
APT_PKGS: build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm
# Line tables are all a sanitizer report needs. configure and
# make take these in place of DEBUG=1's -O0 -g, adding their own.
CFLAGS: -O0 -g1
CXXFLAGS: -O0 -g1
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 dependencies
timeout-minutes: 20
run: sh .github/workflows/scripts/apt-install.sh $APT_PKGS
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checkout
uses: actions/checkout@v5
- name: Configure
# Non-Qt, as the harness requires (with Qt, main() lives in
-77
View File
@@ -1,77 +0,0 @@
name: CI Linux TSan [sample suites]
# The threaded sample suites no other lane runs under ThreadSanitizer.
# Their own steps build them under ASan, which cannot see a race: an
# unordered access between two threads passes there and is only found
# by a developer running TSan by hand. tools/tsan-samples.sh builds each
# suite in tools/tsan-samples.list with SANITIZER=thread and runs it with
# halt_on_error, so any report fails the job; the list says what is left
# out and why.
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-tsan-samples.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-tsan-samples.yml'
# ci_paths: end
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
linux-tsan-samples:
name: TSan, the threaded sample suites
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential zlib1g-dev libasound2-dev libsdl1.2-dev libsdl2-dev libwayland-dev ffmpeg
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Build and run each suite under TSan
run: tools/tsan-samples.sh
+37 -43
View File
@@ -27,25 +27,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-tsan-threaded-video.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux-tsan-threaded-video.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -59,39 +43,49 @@ jobs:
linux-tsan-threaded-video:
name: Build with TSan and run with threaded video
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm
timeout-minutes: 45
steps:
- name: Install dependencies
# Same set as Linux-asan-ubsan.yml. libtsan ships with the gcc
# on the runner image, so nothing sanitizer-specific is needed.
timeout-minutes: 20
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Configure
# Same trimmed surface as the ASan job, for the same reason:
# a finding should be a RetroArch bug rather than noise from a
-131
View File
@@ -1,131 +0,0 @@
name: CI Linux Vulkan resize
# The Vulkan driver through changes of the swapchain's size, run for
# real: a retroarch built with Vulkan and X11, on a virtual display
# with Mesa's software Vulkan driver, has its window resized four
# times, with the menu closed and open.
#
# When a swapchain is replaced for nothing but its size, the driver
# rebuilds the framebuffers on its images and keeps the rest - the
# pipelines, render passes, samplers, pools, buffers and frame
# textures it used to destroy and build again each time. This holds
# that every size change takes that path, that the picture afterwards
# is pixel for pixel the one a full rebuild draws, and that the
# Vulkan validation layers have nothing to say about either. Then
# the same with a two-pass shader preset: the shader chain, which used
# to reflect and compile every pass again on each swapchain change, is
# kept when only the size changed, and its picture is the one a full
# rebuild draws. See samples/gfx/vulkan_resize/run.sh.
on:
push:
branches:
- master
paths:
- 'gfx/drivers/vulkan.c'
- 'gfx/common/vulkan_common.*'
- 'gfx/drivers_context/x_vk_ctx.c'
- 'gfx/drivers_shader/shader_vulkan.*'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'samples/gfx/vulkan_resize/**'
- 'samples/input/windows_wine_smoke/smoke_core.c'
- '.github/workflows/Linux-vulkan-resize.yml'
pull_request:
paths:
- 'gfx/drivers/vulkan.c'
- 'gfx/common/vulkan_common.*'
- 'gfx/drivers_context/x_vk_ctx.c'
- 'gfx/drivers_shader/shader_vulkan.*'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'samples/gfx/vulkan_resize/**'
- 'samples/input/windows_wine_smoke/smoke_core.c'
- '.github/workflows/Linux-vulkan-resize.yml'
workflow_dispatch:
permissions:
contents: read
# Only pull requests cancel a superseded run. On master every push
# gets its own group (keyed by the commit), so a burst of pushes queues
# instead of cancelling the run for the commit before it.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
linux-vulkan-resize:
name: Run retroarch on software Vulkan and resize its window
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential ccache xvfb xdotool x11-apps python3 libx11-dev libx11-xcb-dev libxcb1-dev libxext-dev libxxf86vm-dev libxinerama-dev libxrandr-dev libxv-dev libudev-dev zlib1g-dev libvulkan-dev mesa-vulkan-drivers vulkan-validationlayers
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Build retroarch with Vulkan and X11
shell: bash
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
ccache -M 500M
ccache -z
# (--enable-vulkan makes configure look for the Vulkan
# loader to link against: libvulkan-dev above)
./configure --disable-qt --enable-vulkan --enable-x11 \
--disable-wayland --disable-sdl2 --disable-pulse \
--disable-alsa --disable-ffmpeg --disable-discord
make -j$(nproc) CC="ccache gcc" CXX="ccache g++"
ccache -s
test -x retroarch
- name: Resize the window on both paths
shell: bash
run: |
set -eu
timeout 600 samples/gfx/vulkan_resize/run.sh
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
File diff suppressed because it is too large. Load diff
-146
View File
@@ -1,146 +0,0 @@
name: CI Linux Wayland input
# RetroArch's Wayland input path, run for real: a retroarch built with
# Wayland and OpenGL is run under Weston - itself a window on a virtual
# X display, drawing in software - keys are pressed and the pointer is
# moved in it, and its log is read. It runs the small core of
# samples/input/windows_wine_smoke, which writes to the log what
# reaches it.
#
# What it holds: that the seat's events - keyboard, pointer - are
# handled on the frontend's thread and nowhere else, with threaded
# video and without. They are on an event queue of their own that only
# the input driver's poll dispatches; on the one queue there used to
# be, the video thread dispatched them as well. And that keys, the
# pointer, a fullscreen toggle and the keyboard focus leaving and
# coming back all still work that way. See
# samples/input/wayland_smoke/run.sh.
on:
push:
branches:
- master
paths:
- 'input/input_driver.c'
- 'input/input_driver.h'
- 'input/drivers/wayland_input.c'
- 'input/common/wayland_common.*'
- 'gfx/common/wayland_common.*'
- 'gfx/drivers_context/wayland_ctx.c'
- 'gfx/drivers_context/wayland_vk_ctx.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'samples/input/wayland_smoke/**'
- 'samples/input/windows_wine_smoke/smoke_core.c'
- '.github/workflows/Linux-wayland-input.yml'
pull_request:
paths:
- 'input/input_driver.c'
- 'input/input_driver.h'
- 'input/drivers/wayland_input.c'
- 'input/common/wayland_common.*'
- 'gfx/common/wayland_common.*'
- 'gfx/drivers_context/wayland_ctx.c'
- 'gfx/drivers_context/wayland_vk_ctx.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'samples/input/wayland_smoke/**'
- 'samples/input/windows_wine_smoke/smoke_core.c'
- '.github/workflows/Linux-wayland-input.yml'
workflow_dispatch:
permissions:
contents: read
# Only pull requests cancel a superseded run. On master every push
# gets its own group (keyed by the commit), so a burst of pushes queues
# instead of cancelling the run for the commit before it.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
linux-wayland-input:
name: Run retroarch under Weston and press keys
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential ccache weston xvfb xdotool x11-apps libwayland-dev wayland-protocols libxkbcommon-dev libdecor-0-dev libegl1-mesa-dev libgl1-mesa-dev libgl1-mesa-dri libudev-dev
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Build retroarch with Wayland and OpenGL (the rest off)
shell: bash
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
ccache -M 250M
ccache -z
# What the test runs has to be real: the Wayland context and
# input driver, OpenGL, the menu, threads. Everything else is
# build time.
./configure --disable-qt --disable-x11 --enable-wayland \
--disable-sdl --disable-sdl2 --disable-ffmpeg \
--disable-vulkan --disable-pulse --disable-discord \
--disable-networking --disable-cheevos \
--disable-glslang --disable-slang \
--disable-spirv_cross --disable-xmb \
--disable-materialui --disable-ozone \
--disable-7zip --disable-flac \
--disable-audiomixer --disable-translate \
--disable-accessibility --disable-crtswitchres \
--disable-langextra --disable-libretrodb \
--disable-video_filter --disable-dsp_filter
make -j$(nproc) CC="ccache gcc" CXX="ccache g++"
ccache -s
test -x retroarch
- name: Run the scenarios under Weston
shell: bash
run: |
set -eu
timeout 600 samples/input/wayland_smoke/run.sh
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-94
View File
@@ -1,94 +0,0 @@
name: CI builtin media player
on:
push:
branches: [master]
paths:
- 'cores/libretro-media/**'
- 'samples/cores/webm_player/**'
- 'samples/gfx/d3d11_video_decode/**'
- 'libretro-common/samples/formats/audio_transfer/**'
- 'libretro-common/samples/formats/audio_transfer_wma/**'
- 'libretro-common/formats/**'
- 'libretro-common/include/formats/**'
- '.github/workflows/Linux-webm-player.yml'
pull_request:
branches: [master]
paths:
- 'cores/libretro-media/**'
- 'samples/cores/webm_player/**'
- 'samples/gfx/d3d11_video_decode/**'
- 'libretro-common/samples/formats/audio_transfer/**'
- 'libretro-common/samples/formats/audio_transfer_wma/**'
- 'libretro-common/formats/**'
- 'libretro-common/include/formats/**'
- '.github/workflows/Linux-webm-player.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
player:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
APT_PKGS: build-essential ffmpeg gcc-mingw-w64-x86-64 wine64
steps:
- uses: actions/checkout@v5
- 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 }}
# Bounded, with the main archive tried when the mirror stalls: a
# plain apt-get install stalled on it took the job's 15 minutes
- name: Install dependencies
timeout-minutes: 15
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: Generate media
working-directory: samples/cores/webm_player
run: python3 mkfixtures.py
- name: Float MP3 progressive windows and rewind
working-directory: libretro-common/samples/formats/audio_transfer
run: |
set -eu
ffmpeg -nostdin -v error -y -f lavfi -i 'sine=frequency=997:sample_rate=44100:duration=8' -ac 2 -c:a libmp3lame -b:a 128k /tmp/rmp3-window.mp3
make -B -j2 audio_transfer_window_mp3_test TARGET=audio_transfer_window_mp3_test SAMPLE_OBJDIR=obj-mp3-window WINDOW_TEST_FLAGS='-DTEST_FLOAT -DKEEP=1024 -DLOOKAHEAD=2048 -DMARGIN=4096'
./audio_transfer_window_mp3_test /tmp/rmp3-window.mp3
- name: Metadata-only demuxed audio setup
run: |
make -j2 -C libretro-common/samples/formats/audio_transfer check-empty SANITIZER=address,undefined SAMPLE_OBJDIR=obj-player-meta
env:
ASAN_OPTIONS: detect_leaks=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
- name: Run the builtin core without FFmpeg
working-directory: samples/cores/webm_player
run: |
set -eu
make -j2 check SANITIZER=address,undefined SAMPLE_OBJDIR=obj-ci-asan TARGET=webm_player_ci_asan
make -j2 check AUDIO=0 SAMPLE_OBJDIR=obj-noaudio TARGET=webm_player_noaudio SANITIZER=address,undefined
make -j2 check MP4=0 SAMPLE_OBJDIR=obj-webm TARGET=webm_player_webm SANITIZER=address,undefined
make -j2 check THREADS=0 SAMPLE_OBJDIR=obj-nothreads TARGET=webm_player_nothreads SANITIZER=address,undefined
make -j2 check-wma SANITIZER=address,undefined SAMPLE_OBJDIR=obj-wma
make -j2 check-wma WMA=0 SANITIZER=address,undefined SAMPLE_OBJDIR=obj-wma-disabled
env:
ASAN_OPTIONS: detect_leaks=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
- name: Windows core host
working-directory: samples/cores/webm_player
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
make -j2 check CC=x86_64-w64-mingw32-gcc OS=Windows_NT EXE=.exe SAMPLE_OBJDIR=obj-win RUNNER=wine
make -j2 check-wma CC=x86_64-w64-mingw32-gcc OS=Windows_NT EXE=.exe SAMPLE_OBJDIR=obj-win RUNNER=wine
+2 -23
View File
@@ -3,19 +3,7 @@ name: CI Linux (i686)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Linux.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -31,14 +19,11 @@ concurrency:
jobs:
build:
# The 32-bit xenial image resolves no host on an Ubuntu 26.04 runner,
# public resolvers or not: since ubuntu-latest moved, its runs stop at
# checkout. The other container jobs, all 64-bit, are unaffected.
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-i386-ubuntu:xenial-gcc9
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- name: Check Out Repo
@@ -59,12 +44,6 @@ jobs:
make -j$(getconf _NPROCESSORS_ONLN) clean
make -j$(getconf _NPROCESSORS_ONLN) info all
- name: Hidden symbol check
run: |
# libretro-common's MD5 and krb5 keep their system namesakes'
# names; exported, libssl and cores bind to them.
.github/workflows/scripts/hidden-symbols-check.sh
- name: Stack frame sweep
run: |
set -eu
+7 -63
View File
@@ -3,23 +3,7 @@ name: CI Windows (MSVC)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/MSVC.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/MSVC.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -41,14 +25,14 @@ jobs:
timeout-minutes: 90
strategy:
matrix:
version: [2022-UWP, 2019, 2022]
version: [UWP, 2019, 2022]
configuration: [Debug, Release]
platform: [x64]
exclude:
- version: 2022-UWP
- version: UWP
configuration: Debug
include:
- version: 2022-UWP
- version: UWP
configuration: ReleaseAngle
platform: x64
# Qt and Cg builds are excluded for now
@@ -59,7 +43,7 @@ jobs:
uses: microsoft/setup-msbuild@v1
- name: Compile RA
working-directory: "${{github.workspace}}/pkg/msvc"
working-directory: "${{github.workspace}}/pkg/msvc${{ matrix.version == 'UWP' && '-uwp' || ''}}"
run: |
msbuild -p:"Configuration=${{matrix.configuration}}" -p:"Platform=${{matrix.platform}}" .\RetroArch-msvc${{matrix.version}}.sln
@@ -73,48 +57,8 @@ jobs:
with:
name: retroarch-${{matrix.version}}-${{matrix.configuration}}-${{matrix.platform}}-${{ steps.slug.outputs.sha8 }}
path: |
${{ !endsWith(matrix.version, 'UWP') }}:
${{ matrix.version != 'UWP' }}:
pkg/msvc/${{matrix.platform}}/${{matrix.configuration}}/RetroArch-msvc${{matrix.version}}.exe
${{ endsWith(matrix.version, 'UWP') }}:
pkg/msvc/AppPackages/RetroArch-msvc${{matrix.version}}
${{ matrix.version == 'UWP' }}:
pkg/msvc-uwp/AppPackages/RetroArch-msvcUWP
msvc2026:
runs-on: windows-2025
timeout-minutes: 90
strategy:
matrix:
version: [2026-UWP, 2026]
configuration: [Debug, Release]
platform: [x64]
exclude:
- version: 2026-UWP
configuration: Debug
include:
- version: 2026-UWP
configuration: ReleaseAngle
platform: x64
# Qt and Cg builds are excluded for now
steps:
- uses: actions/checkout@v7
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
- name: Compile RA
working-directory: "${{github.workspace}}/pkg/msvc"
run: |
msbuild -p:"Configuration=${{matrix.configuration}}" -p:"Platform=${{matrix.platform}}" .\RetroArch-msvc${{matrix.version}}.sln
- name: Get short SHA
id: slug
shell: powershell
run: echo "sha8=$('${{github.sha}}'.Substring(0,8))" >> $env:GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
with:
name: retroarch-${{matrix.version}}-${{matrix.configuration}}-${{matrix.platform}}-${{ steps.slug.outputs.sha8 }}
path: |
${{ !endsWith(matrix.version, 'UWP') }}:
pkg/msvc/${{matrix.platform}}/${{matrix.configuration}}/RetroArch-msvc${{matrix.version}}.exe
${{ endsWith(matrix.version, 'UWP') }}:
pkg/msvc/AppPackages/RetroArch-msvc${{matrix.version}}
+31 -61
View File
@@ -3,19 +3,7 @@ name: CI Windows (MSYS2)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/MSYS2.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/MSYS2.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -41,12 +29,8 @@ jobs:
runner: windows-latest
# New ARM64 build (native Windows on ARM)
# MSYS2's runtime runs emulated on these runners, so configure
# runs its checks one at a time here instead of in parallel
# background workers.
- sys: CLANGARM64
runner: windows-11-arm
qb_jobs: 1
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
@@ -59,58 +43,44 @@ jobs:
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
update: true
- name: Install packages
shell: msys2 {0}
run: |
# A mirror that stalls or rate-limits (HTTP 429) fails pacman's
# whole transaction; what it fetched stays in the cache, so a
# retry fetches only the rest, one file at a time after a
# growing wait so a shared runner's rate limit can clear.
# A package that fails its checksum is deleted, but pacman
# fetches it again from the same first mirror, so each retry
# also moves every mirror list's first server to the end.
# Runtime updates belong to setup-msys2 above, which can restart
# its shell. These retries install dependencies only.
p=$MINGW_PACKAGE_PREFIX
pkgs="base-devel git $p-gettext $p-gobject-introspection
$p-graphite2 $p-p11-kit $p-qt6-base $p-x264 $p-cc"
for i in 1 2 3 4 5; do
pacman -S --noconfirm --needed $pkgs && exit 0
[ $i = 5 ] && break
echo "package install failed (attempt $i); retrying in $((30 * i))s, next mirror, serial downloads"
sed -i -e '/^#*ParallelDownloads/d' -e '/^\[options\]/a ParallelDownloads = 1' /etc/pacman.conf
for m in /etc/pacman.d/mirrorlist.*; do
awk '/^Server/ && !s { s = $0; next } { print } END { if (s) print s }' "$m" > "$m.tmp" && mv "$m.tmp" "$m"
done
sleep $((30 * i))
done
exit 1
install: >-
base-devel
git
pacboy: >-
gettext:p
gobject-introspection:p
graphite2:p
p11-kit:p
qt6:p
qt6-3d:p
qt6-charts:p
qt6-datavis3d:p
qt6-imageformats:p
qt6-location:p
qt6-lottie:p
qt6-networkauth:p
qt6-quick3dphysics:p
qt6-quicktimeline:p
qt6-remoteobjects:p
qt6-scxml:p
qt6-sensors:p
qt6-serialbus:p
qt6-speech:p
qt6-tools:p
qt6-translations:p
qt6-virtualkeyboard:p
qt6-webchannel:p
qt6-websockets:p
x264:p
cc:p
- name: Configure and build RetroArch
shell: msys2 {0}
run: |
echo "Building RetroArch in ${{ matrix.sys }} on ${{ matrix.runner }}"
QB_JOBS=${{ matrix.qb_jobs }} ./configure
./configure
make -j"$(nproc)" info all
- name: Native modal message pump regression
shell: msys2 {0}
run: |
set -eu
flags=''
if cc --version | grep -qi clang; then flags="-Wno-c99-extensions -Wno-c11-extensions"; fi
cc $flags -std=c89 -pedantic -Wall -Wextra -Werror -Wno-unused-function -Wframe-larger-than=4096 -Ilibretro-common/include samples/gfx/win32_window_proc/modal_frame_test.c -o modal_frame_test.exe -lgdi32 -luser32
rc=0
./modal_frame_test.exe || rc=$?
if [ "$rc" = 77 ] && [ "${{ matrix.sys }}" = CLANGARM64 ]; then
echo "::notice::Modal continuity unavailable; checking safe fallback"
./modal_frame_test.exe --fallback
else
test "$rc" = 0
fi
- name: Collect DLLs and binaries
shell: msys2 {0}
run: |
+2 -60
View File
@@ -18,23 +18,7 @@ name: CI macOS PowerPC (cross)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/MacOS-PPC-Cross.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/MacOS-PPC-Cross.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -56,7 +40,7 @@ jobs:
timeout-minutes: 60
container:
image: ghcr.io/variantxyz/gcc-powerpc-apple-darwin8:build-gcc-14.2-MacOSXSDK10.5
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
strategy:
fail-fast: false
matrix:
@@ -81,54 +65,12 @@ jobs:
--disable-glslang --disable-crtswitchres --disable-al \
--disable-cdrom
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ matrix.deployment_target }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-${{ matrix.deployment_target }}-
- name: Set up ccache
run: |
# Best effort: without ccache, ccache-make.sh runs plain make.
command -v ccache > /dev/null || {
s=$(command -v sudo || true)
for i in 1 2 3; do
$s timeout 90 apt-get -yq update \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 &&
$s timeout 120 apt-get -yq install --no-install-recommends \
ccache > /dev/null && break
echo "installing ccache failed (attempt $i); retrying in 10s"
sleep 10
done
}
echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> "$GITHUB_ENV"
echo "CCACHE_MAXSIZE=250M" >> "$GITHUB_ENV"
if command -v ccache > /dev/null; then
CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" ccache -z
fi
- name: Compile RA
run: |
bash .github/workflows/scripts/ccache-make.sh ARCH=ppc -j$(getconf _NPROCESSORS_ONLN)
make ARCH=ppc -j$(getconf _NPROCESSORS_ONLN)
file retroarch
$TARGET-otool -l retroarch | grep -A2 LC_VERSION_MIN_MACOSX
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv || ccache -s
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ matrix.deployment_target }}-${{ github.sha }}
- name: Audit imports against the 10.4u SDK
if: matrix.deployment_target == '10.4'
run: |
@@ -1,99 +0,0 @@
name: CI macOS task queue samples
# The task_queue samples run on Linux and under Wine in
# Linux-libretro-common-samples.yml, which never builds the GCD runner
# Apple builds use. This runs each one with Apple clang on the threaded
# runner, and those with a GCD=1 build again on GCD: plain, under
# ASan+UBSan and under TSan.
on:
push:
branches: [master]
paths:
- 'libretro-common/queues/task_queue.c'
- 'libretro-common/include/queues/**'
- 'libretro-common/rthreads/**'
- 'libretro-common/include/rthreads/**'
- 'libretro-common/include/retro_atomic.h'
- 'libretro-common/include/retro_timers.h'
- 'libretro-common/include/features/features_cpu.h'
- 'libretro-common/include/time/rtime.h'
- 'libretro-common/features/**'
- 'libretro-common/time/rtime.c'
- 'libretro-common/samples/queues/task_queue_*/**'
- 'libretro-common/samples/sample_objdir.mk'
- '.github/workflows/MacOS-task-queue-samples.yml'
pull_request:
paths:
- 'libretro-common/queues/task_queue.c'
- 'libretro-common/include/queues/**'
- 'libretro-common/rthreads/**'
- 'libretro-common/include/rthreads/**'
- 'libretro-common/include/retro_atomic.h'
- 'libretro-common/include/retro_timers.h'
- 'libretro-common/include/features/features_cpu.h'
- 'libretro-common/include/time/rtime.h'
- 'libretro-common/features/**'
- 'libretro-common/time/rtime.c'
- 'libretro-common/samples/queues/task_queue_*/**'
- 'libretro-common/samples/sample_objdir.mk'
- '.github/workflows/MacOS-task-queue-samples.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
task-queue-macos:
name: task_queue samples on macOS, threaded and GCD
runs-on: macos-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
- name: Build and run the task_queue samples
shell: bash
working-directory: libretro-common/samples/queues
env:
TSAN_OPTIONS: halt_on_error=1 second_deadlock_stack=1
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
run: |
set -u
set -o pipefail
# macOS has no timeout(1): perl's alarm bounds each run.
fails=0
runs=0
for d in task_queue_*; do
t=$(sed -nE 's/^TARGET[[:space:]]*:?=[[:space:]]*//p' "$d/Makefile")
runners=0
if grep -qF 'ifeq ($(GCD),1)' "$d/Makefile"; then
runners="0 1"
fi
for g in $runners; do
for san in '' address,undefined thread; do
label="$t, GCD=$g, ${san:-plain}"
printf '\n[build] %s\n' "$label"
if ! ( cd "$d" && make clean >/dev/null && make all GCD=$g SANITIZER=$san ); then
printf '::error title=macOS build failed::%s does not build\n' "$label"
fails=$((fails+1))
continue
fi
printf '[run] %s\n' "$label"
if ( cd "$d" && perl -e 'alarm shift; exec @ARGV or die "exec $ARGV[0]: $!\n"' 300 "./$t" ); then
printf '[pass] %s\n' "$label"
runs=$((runs+1))
else
rc=$?
printf '::error title=Test failed on macOS::%s exited with status %d\n' "$label" "$rc"
fails=$((fails+1))
fi
done
done
( cd "$d" && make clean >/dev/null )
done
printf '\n Ran: %d\n Failed: %d\n' "$runs" "$fails"
[[ $fails -eq 0 ]]
@@ -1,197 +0,0 @@
name: CI VideoToolbox hardware encode
on:
push:
branches: [master]
paths:
- '.github/workflows/MacOS-videotoolbox-encode.yml'
- 'gfx/common/videotoolbox_encode*.h'
- 'libretro-common/formats/h265/rh265_sps_crop.c'
- 'libretro-common/include/formats/rh265_sps_crop.h'
- 'record/drivers/record_metal.*'
- 'record/drivers/record_avfoundation*'
- 'record/record_driver.*'
- 'gfx/drivers/metal.m'
- 'Makefile.common'
- 'griffin/griffin*'
- 'record/record_gpu_capture_metal.*'
- 'record/record_gpu_session_metal.*'
- 'record/record_gpu_dispatch_metal.*'
- 'record/record_gpu_worker_vt*'
- 'record/record_audio_queue.*'
- 'record/record_avfoundation_worker*'
- 'record/record_avfoundation_session*'
- 'record/record_mux_avfoundation.*'
- 'record/shaders/capture_metal.*'
- 'record/shaders/generate_metal.py'
- 'samples/record/videotoolbox_encode/**'
- 'samples/record/metal_frontend/**'
- 'libretro-common/include/retro_atomic.h'
pull_request:
paths:
- '.github/workflows/MacOS-videotoolbox-encode.yml'
- 'gfx/common/videotoolbox_encode*.h'
- 'libretro-common/formats/h265/rh265_sps_crop.c'
- 'libretro-common/include/formats/rh265_sps_crop.h'
- 'record/drivers/record_metal.*'
- 'record/drivers/record_avfoundation*'
- 'record/record_driver.*'
- 'gfx/drivers/metal.m'
- 'Makefile.common'
- 'griffin/griffin*'
- 'record/record_gpu_capture_metal.*'
- 'record/record_gpu_session_metal.*'
- 'record/record_gpu_dispatch_metal.*'
- 'record/record_gpu_worker_vt*'
- 'record/record_audio_queue.*'
- 'record/record_avfoundation_worker*'
- 'record/record_avfoundation_session*'
- 'record/record_mux_avfoundation.*'
- 'record/shaders/capture_metal.*'
- 'record/shaders/generate_metal.py'
- 'samples/record/videotoolbox_encode/**'
- 'samples/record/metal_frontend/**'
- 'libretro-common/include/retro_atomic.h'
workflow_dispatch:
permissions:
contents: read
jobs:
encode:
runs-on: macos-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
- name: Install independent test decoder
run: command -v ffmpeg >/dev/null && command -v ffprobe >/dev/null || brew install ffmpeg
- name: Native encoder and Metal device inventory
if: ${{ !cancelled() }}
run: ENCODER_DEVICE_ARTIFACT="$RUNNER_TEMP/metal-vt-devices.json" python3 samples/record/videotoolbox_encode/device_run.py
- name: Portable ownership and failure contracts
working-directory: samples/record/videotoolbox_encode
run: make check thread_test worker_thread_test audio_thread_test av_session_thread_test && ./thread_test && ./worker_thread_test && ./audio_thread_test && ./av_session_thread_test
- name: Native AAC property ABI and advertised rates
run: make -C samples/record/videotoolbox_encode native-audio-check
- name: Native hardware encoder and independent pixels
run: |
rc=0
python3 samples/record/videotoolbox_encode/run.py --native || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Some required hardware encode cases unavailable; native encode acceptance is incomplete"
exit 0
fi
exit "$rc"
- name: Native Metal to VideoToolbox queue-worker pipeline
if: ${{ !cancelled() }}
run: |
rc=0
PIPELINE_ARTIFACT_DIR="$RUNNER_TEMP/metal-vt-evidence" python3 samples/record/videotoolbox_encode/pipeline_run.py || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Native pipeline hardware unavailable; integrated recording acceptance is incomplete"
exit 0
fi
exit "$rc"
- name: Independent native Metal capture pixels and ownership
if: ${{ !cancelled() }}
run: |
rc=0
python3 samples/record/videotoolbox_encode/capture_run.py || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Metal capture device unavailable; native capture acceptance is incomplete"
exit 0
fi
exit "$rc"
- name: Native compressed MP4 and AAC worker mux
if: ${{ !cancelled() }}
run: |
rc=0
PIPELINE_ARTIFACT_DIR="$RUNNER_TEMP/metal-vt-mux-evidence" python3 samples/record/videotoolbox_encode/pipeline_run.py --mux || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Native mux hardware unavailable; A/V acceptance is incomplete"
exit 0
fi
exit "$rc"
- name: Native owned recording session
if: ${{ !cancelled() }}
run: |
rc=0
PIPELINE_ARTIFACT_DIR="$RUNNER_TEMP/metal-vt-session-evidence" python3 samples/record/videotoolbox_encode/pipeline_run.py --session || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Native owned session hardware unavailable; controller acceptance is incomplete"
exit 0
fi
exit "$rc"
- name: Native renderer-device cold recording startup
if: ${{ !cancelled() }}
run: |
rc=0
PIPELINE_ARTIFACT_DIR="$RUNNER_TEMP/metal-vt-cold-evidence" python3 samples/record/videotoolbox_encode/pipeline_run.py --cold || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Renderer-device encoder unavailable; cold startup acceptance is incomplete"
exit 0
fi
exit "$rc"
- name: Native dedicated recording dispatcher
if: ${{ !cancelled() }}
run: |
rc=0
PIPELINE_ARTIFACT_DIR="$RUNNER_TEMP/metal-vt-dispatch-evidence" python3 samples/record/videotoolbox_encode/pipeline_run.py --dispatch || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Dispatcher hardware unavailable; recording dispatch acceptance is incomplete"
exit 0
fi
exit "$rc"
- name: Preserve native pipeline evidence
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: metal-vt-pipeline-evidence
path: |
${{ runner.temp }}/metal-vt-evidence
${{ runner.temp }}/metal-vt-mux-evidence
${{ runner.temp }}/metal-vt-session-evidence
${{ runner.temp }}/metal-vt-cold-evidence
${{ runner.temp }}/metal-vt-dispatch-evidence
${{ runner.temp }}/metal-vt-devices.json
if-no-files-found: warn
frontend-build:
runs-on: macos-latest
timeout-minutes: 40
steps:
- uses: actions/checkout@v6
- name: Configure native Metal recording frontend
run: |
set -eu
./configure --enable-metal --enable-avf --enable-threads --enable-configfile --enable-webmplayer \
--disable-qt --disable-ffmpeg --disable-discord --disable-cheevos \
--disable-networking --disable-sdl2 --disable-sdl --disable-translate \
--disable-update_cores --disable-update_assets --disable-online_updater \
--disable-cdrom --disable-7zip --disable-ssl
for feature in HAVE_METAL HAVE_AVF HAVE_THREADS HAVE_CONFIGFILE HAVE_WEBMPLAYER; do
grep -Eq "^#define $feature 1" config.h
done
- name: Build and link real frontend with native recording enabled
run: |
set -eu
make -j"$(sysctl -n hw.ncpu)" MINVERFLAGS="-mmacosx-version-min=$(sw_vers -productVersion)"
test -x retroarch
nm retroarch | grep '_record_metal_gpu_capture'
- name: Independent real frontend GPU recording
run: |
set -eu
command -v ffmpeg >/dev/null && command -v ffprobe >/dev/null || brew install ffmpeg
cc -dynamiclib -std=gnu89 -Ilibretro-common/include samples/record/metal_frontend/core.c -o "$RUNNER_TEMP/metal-record-core.dylib" -lm
python3 samples/record/metal_frontend/run.py --retroarch ./retroarch --core "$RUNNER_TEMP/metal-record-core.dylib" --output-dir "$RUNNER_TEMP/metal-frontend-recordings"
- uses: actions/upload-artifact@v6
if: always()
with:
name: metal-frontend-recordings
path: ${{ runner.temp }}/metal-frontend-recordings
if-no-files-found: warn
frontend-contracts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Source-clock capture and backpressure under sanitizers
run: make -C samples/record/metal_frontend check SANITIZER=address,undefined
@@ -1,83 +0,0 @@
name: CI VideoToolbox HEVC and Metal
on:
push:
branches: [master]
paths:
- '.github/workflows/MacOS-videotoolbox-hevc.yml'
- 'samples/gfx/videotoolbox_hevc/**'
- 'samples/gfx/metal_frame/**'
- 'gfx/common/videotoolbox_hevc*.h'
- 'gfx/common/metal_frame*.h'
- 'gfx/common/metal_hevc_driver.h'
- 'gfx/common/metal_vp9_driver.h'
- 'gfx/common/metal_decoder_snapshot.h'
- 'gfx/common/videotoolbox_vp9*.h'
- 'samples/gfx/videotoolbox_vp9/**'
- 'libretro-common/formats/vp9/**'
- 'libretro-common/formats/mp4/rmp4_video.c'
- 'libretro-common/formats/webm/rwebm_video.c'
- 'gfx/drivers/metal.m'
- 'gfx/drivers/metal.h'
- 'gfx/drivers/metal_shaders/Shaders.metal'
- 'gfx/video_driver.h'
- 'gfx/video_defines.h'
- 'libretro-common/formats/h265/**'
- 'libretro-common/rthreads/**'
- 'libretro-common/include/**'
pull_request:
paths:
- '.github/workflows/MacOS-videotoolbox-hevc.yml'
- 'samples/gfx/videotoolbox_hevc/**'
- 'samples/gfx/metal_frame/**'
- 'gfx/common/videotoolbox_hevc*.h'
- 'gfx/common/metal_frame*.h'
- 'gfx/common/metal_hevc_driver.h'
- 'gfx/common/metal_vp9_driver.h'
- 'gfx/common/metal_decoder_snapshot.h'
- 'gfx/common/videotoolbox_vp9*.h'
- 'samples/gfx/videotoolbox_vp9/**'
- 'libretro-common/formats/vp9/**'
- 'libretro-common/formats/mp4/rmp4_video.c'
- 'libretro-common/formats/webm/rwebm_video.c'
- 'gfx/drivers/metal.m'
- 'gfx/drivers/metal.h'
- 'gfx/drivers/metal_shaders/Shaders.metal'
- 'gfx/video_driver.h'
- 'gfx/video_defines.h'
- 'libretro-common/formats/h265/**'
- 'libretro-common/rthreads/**'
- 'libretro-common/include/**'
workflow_dispatch:
permissions:
contents: read
jobs:
videotoolbox-hevc:
runs-on: macos-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- name: VideoToolbox HEVC hardware decode and pixel ownership
run: |
rc=0
python3 samples/gfx/videotoolbox_hevc/run.py --native --metal || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::HEVC hardware decode or Metal shared events unavailable; native bridge check did not complete"
exit 0
fi
exit "$rc"
- name: VideoToolbox VP9 hardware decode, MP4/WebM and Metal pixels
if: ${{ !cancelled() }}
run: |
rc=0
python3 samples/gfx/videotoolbox_vp9/run.py --native --pipeline || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::VP9 hardware decode or Metal unavailable; native acceptance did not complete"
exit 0
fi
exit "$rc"
- name: Metal movie import, history and GPU pixel acceptance
if: ${{ !cancelled() }}
run: python3 samples/gfx/metal_frame/run.py --native
+3 -31
View File
@@ -3,19 +3,7 @@ name: CI macOS
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/MacOS.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/MacOS.yml'
# ci_paths: end
permissions:
contents: read
@@ -65,16 +53,6 @@ jobs:
fi
exit "$rc"
- name: Retained Metal frame lease on the native GPU
run: |
rc=0
python3 samples/gfx/metal_frame/run.py --native || rc=$?
if [ "$rc" = 77 ]; then
echo "::warning::Metal shared events unavailable; lease GPU check did not run"
exit 0
fi
exit "$rc"
- name: iCloud Drive cloud sync driver
run: |
set -o pipefail
@@ -132,9 +110,6 @@ jobs:
steps:
- uses: actions/checkout@v6
- name: Match the runner's library deployment target
run: echo "MACOSX_DEPLOYMENT_TARGET=$(sw_vers -productVersion)" >> "$GITHUB_ENV"
- name: Configure and build (Makefile, no Qt)
run: |
set -o pipefail
@@ -142,14 +117,11 @@ jobs:
--disable-networking --disable-sdl2 --disable-sdl --disable-translate \
--disable-update_cores --disable-update_assets --disable-online_updater \
--disable-cdrom --disable-7zip --disable-ssl 2>&1 | tail -5
make -j$(sysctl -n hw.ncpu) MINVERFLAGS="-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" GFX_INSTRUMENT=1 2>&1 | grep -E "error|warning: unused" || true
make -j$(sysctl -n hw.ncpu) GFX_INSTRUMENT=1 2>&1 | grep -E "error|warning: unused" || true
test -x retroarch
- name: Harness on Metal (RGB565 core, then XRGB8888)
env:
# Hosted macOS timers cannot reliably meet the synthetic 120 Hz grid.
HARNESS_SKIP_PHASE_GRID: '1'
run: |
set -o pipefail
SAN=none GFX_INSTRUMENT=1 DRIVER=metal CYCLES=1 make -C samples/gfx/threaded_video MINVERFLAGS="-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" check-driver
HARNESS_CORE_XRGB8888=1 SAN=none GFX_INSTRUMENT=1 DRIVER=metal CYCLES=1 make -C samples/gfx/threaded_video MINVERFLAGS="-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" check-driver
SAN=none GFX_INSTRUMENT=1 DRIVER=metal CYCLES=1 make -C samples/gfx/threaded_video check-driver
HARNESS_CORE_XRGB8888=1 SAN=none GFX_INSTRUMENT=1 DRIVER=metal CYCLES=1 make -C samples/gfx/threaded_video check-driver
+1 -17
View File
@@ -3,23 +3,7 @@ name: CI Miyoo ARM32
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Miyoo.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Miyoo.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-dingux:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
+4 -45
View File
@@ -33,21 +33,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Msg-Hash-Packed-Check.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Msg-Hash-Packed-Check.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -67,9 +55,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checker self-test
shell: bash
run: |
@@ -83,7 +68,7 @@ jobs:
# from intl/, so this reports the same thing whether or not
# the shipped headers currently pass - it is measuring the
# checker, not the tree.
tools/check.sh tools/msg_hash_packed_check.c --selftest
python3 tools/msg_hash_packed_check.py --selftest
- name: Tree check
shell: bash
@@ -95,7 +80,7 @@ jobs:
# the chunk, for a non-final chunk of a split row), no row may
# hold an embedded NUL, and the sizeof() check must still add
# up to the members it guards.
tools/check.sh tools/msg_hash_packed_check.c
python3 tools/msg_hash_packed_check.py
- name: Format parity self-test
shell: bash
@@ -109,7 +94,7 @@ jobs:
# argument taken from the table directly and through a local,
# and must not see a string that is copied, passed as a value,
# or split on a placeholder rather than formatted.
tools/check.sh tools/msg_hash_format_check.c --selftest
python3 tools/msg_hash_format_check.py --selftest
- name: Format parity tree check
shell: bash
@@ -122,30 +107,4 @@ jobs:
# That last set is measured from the call sites rather than
# assumed from the namespace: ninety rows reach a printf-family
# format argument today and twenty-nine of them are not MSG_*.
tools/check.sh tools/msg_hash_format_check.c
- name: Internal headers survive translation conversion
run: python3 tools/intl_conversion_check.py
- name: Label macros current
shell: bash
run: |
set -eu
# msg_hash_lbl_str.h names each label's member of the packed
# label blob and is generated from the same rows the blob is
# built from; a row added, renamed or guarded without rerunning
# the generator would leave a macro pointing at a stale or
# missing member, or fall back to a literal that duplicates
# the blob's bytes. Regenerating must be a no-op.
python3 tools/gen_lbl_str.py
git diff --exit-code -- msg_hash_lbl_str.h
- name: Sublabel map sorted
shell: bash
run: |
set -eu
# The sublabel binder looks rows up by binary search; a row
# out of order is never found and its entry loses its
# sublabel without any build failing.
python3 tools/sublabel_map_check.py --selftest
python3 tools/sublabel_map_check.py
python3 tools/msg_hash_format_check.py
+2 -17
View File
@@ -4,21 +4,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Overlap-Copy-Check.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Overlap-Copy-Check.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -38,9 +26,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checker self-test
shell: bash
run: |
@@ -52,7 +37,7 @@ jobs:
# allowlist suppresses audited same-base copies but can
# never suppress an exact alias, and stale allowlist
# entries are reported.
tools/check.sh tools/overlap_copy_check.c --selftest
python3 tools/overlap_copy_check.py --selftest
- name: Tree check
shell: bash
@@ -66,4 +51,4 @@ jobs:
# on Linux/Windows, so nothing else in CI can catch this
# class before it ships to Mac users. Audited-intentional
# same-buffer copies live in tools/overlap_copy_allow.list.
tools/check.sh tools/overlap_copy_check.c
python3 tools/overlap_copy_check.py
-133
View File
@@ -1,133 +0,0 @@
name: CI PS2 runtime
# Runs PS2 builds of samples/frontend/ps2_whole_file under Play!'s
# headless AutoTest (null GS), so file I/O is exercised on the console's
# own runtime - ps2sdk's libcglue and fileXio over the host: device -
# rather than a host libc standing in for it. The ELF is built in the
# same image as the PS2 release build; AutoTest is built from a pinned
# Play! commit and cached on it.
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/frontend/ps2_whole_file/**'
- '.github/workflows/PS2-runtime.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- 'samples/frontend/ps2_whole_file/**'
- '.github/workflows/PS2-runtime.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
# Play! commit AutoTest is built from; move deliberately.
PLAY_REF: 1f27232772e484bfb79364b751b84f41f4c87481
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
container:
image: reallibretroretroarch/libretro-build-ps2:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
steps:
- uses: actions/checkout@v4
- name: Build ps2_whole_file
working-directory: samples/frontend/ps2_whole_file
run: make PS2=1
- uses: actions/upload-artifact@v4
with:
name: ps2-runtime-elfs
path: samples/frontend/ps2_whole_file/ps2_whole_file_test.elf
run:
needs: build
runs-on: ubuntu-latest
timeout-minutes: 45
env:
APT_PKGS: cmake ninja-build zlib1g-dev libbz2-dev libssl-dev
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v5
with:
repository: jpd002/Play-
ref: ${{ env.PLAY_REF }}
submodules: recursive
path: Play
- 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 build dependencies
timeout-minutes: 10
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 }}
- uses: actions/cache@v4
with:
path: Play/build
key: play-autotest-${{ runner.os }}-${{ env.PLAY_REF }}
- name: Build AutoTest
run: |
cmake -S Play -B Play/build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DBUILD_PLAY=OFF -DBUILD_TESTS=ON
cmake --build Play/build --target autotest
- uses: actions/download-artifact@v4
with:
name: ps2-runtime-elfs
path: run
- name: Run under AutoTest
shell: bash
run: |
set -euo pipefail
# AutoTest runs every .elf in the directory and writes its EE
# stdout to <name>.result; it reports a pass only against a
# .reference file, so the verdict is the harness's own lines.
# host: maps to ~/.local/share/Play Data Files/vfs/host.
timeout 600 Play/build/tools/AutoTest/autotest run
cat run/ps2_whole_file_test.result
if grep -q '^FAIL' run/ps2_whole_file_test.result; then exit 1; fi
grep -qx 'ps2_whole_file_test: PASS' run/ps2_whole_file_test.result
+1 -17
View File
@@ -3,23 +3,7 @@ name: CI PS2
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PS2.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PS2.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-ps2:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
+1 -17
View File
@@ -3,23 +3,7 @@ name: CI PS3/PSL1GHT
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PS3-PSL1GHT.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PS3-PSL1GHT.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-psl1ght:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
-30
View File
@@ -3,23 +3,7 @@ name: CI PS4/ORBIS
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PS4-ORBIS.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PS4-ORBIS.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -46,20 +30,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
# Authenticated pulls avoid the shared per-IP anonymous rate limit;
# without the secrets (fork pull requests) the pull stays anonymous
- name: Log in to Docker Hub
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
if [ -n "$DOCKERHUB_USERNAME" ] && [ -n "$DOCKERHUB_TOKEN" ]; then
echo "$DOCKERHUB_TOKEN" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin
fi
- name: Compile RA
run: |
docker run --rm --user root -v "$PWD":/src -w /src "$ORBIS_IMAGE" bash -c '
+2 -18
View File
@@ -3,23 +3,7 @@ name: CI PSP
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PSP.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PSP.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,14 +23,14 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-psp:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile bootstrap
run: |
cd os/psp1/kernel_functions_prx
cd bootstrap/psp1/kernel_functions_prx
make -j$(getconf _NPROCESSORS_ONLN) clean
make -j$(getconf _NPROCESSORS_ONLN)
+2 -61
View File
@@ -3,23 +3,7 @@ name: CI PSVita
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PSVita.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/PSVita.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-vita:latest-20260905
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
@@ -49,53 +33,10 @@ jobs:
make -f Makefile.vita.salamander -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.vita.salamander -j$(getconf _NPROCESSORS_ONLN)
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Set up ccache
run: |
# Best effort: without ccache, ccache-make.sh runs plain make.
command -v ccache > /dev/null || {
s=$(command -v sudo || true)
for i in 1 2 3; do
$s timeout 90 apt-get -yq update \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 &&
$s timeout 120 apt-get -yq install --no-install-recommends \
ccache > /dev/null && break
echo "installing ccache failed (attempt $i); retrying in 10s"
sleep 10
done
}
echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> "$GITHUB_ENV"
echo "CCACHE_MAXSIZE=250M" >> "$GITHUB_ENV"
if command -v ccache > /dev/null; then
CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" ccache -z
fi
- name: Compile RA
run: |
make -f Makefile.vita -j$(getconf _NPROCESSORS_ONLN) clean
bash .github/workflows/scripts/ccache-make.sh -f Makefile.vita -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 HAVE_VITAGLES=1 info all
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv || ccache -s
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
make -f Makefile.vita -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 HAVE_VITAGLES=1 info all
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
-65
View File
@@ -1,65 +0,0 @@
name: CI prune caches
# Every master push saves a ccache per job under a key ending in the
# commit, and only the newest of each is ever restored. The older ones
# fill the repository's cache store, which then evicts the newest cache
# of any workflow that has not run for a few hours. This keeps only the
# newest entry for each job and branch.
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Prune-caches.yml'
# ci_paths: end
schedule:
- cron: '23 * * * *'
workflow_dispatch:
permissions:
actions: write
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
prune:
name: Delete superseded caches
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Delete all but the newest cache of each job
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
run: |
set -eu
# Only ccache keys ending in a commit, with the commit cut off;
# jq does it, as some mawk versions have no {n} in a regex.
gh api --paginate \
"repos/$REPO/actions/caches?per_page=100&sort=created_at&direction=desc" \
--jq '.actions_caches[]
| select(.key | test("^ccache-.*-[0-9a-f]{40}$"))
| [.id, .ref, (.key | sub("-[0-9a-f]{40}$"; "")), .size_in_bytes]
| @tsv' \
> caches.tsv
# Newest first: a cache is superseded once a newer one of the
# same key on the same branch has been seen. A cache saved
# while paging can list one twice, so each id counts once.
awk -F '\t' '!ids[$1]++ && seen[$2 FS $3]++ { print $1 "\t" $4 }' \
caches.tsv > prune.tsv
awk -F '\t' '{ n++; s += $2 } END {
printf "%d commit-keyed ccaches, %d superseded (%.2f GB)\n",
NR0, n, s / 1e9 }' \
NR0="$(wc -l < caches.tsv)" prune.tsv
cut -f1 prune.tsv | while read -r id; do
gh api -X DELETE "repos/$REPO/actions/caches/$id" > /dev/null || \
echo "could not delete cache $id (gone already?)"
done
+4 -13
View File
@@ -31,18 +31,12 @@ on:
push:
paths:
- 'menu/drivers/rgui.c'
- 'tools/rgui_pixfmt_check.c'
- 'tools/rgui_pixfmt_harness.inc'
- 'tools/check_common.h'
- 'tools/check.sh'
- 'tools/rgui_pixfmt_check.py'
- '.github/workflows/RGUI-Pixel-Format-Check.yml'
pull_request:
paths:
- 'menu/drivers/rgui.c'
- 'tools/rgui_pixfmt_check.c'
- 'tools/rgui_pixfmt_harness.inc'
- 'tools/check_common.h'
- 'tools/check.sh'
- 'tools/rgui_pixfmt_check.py'
- '.github/workflows/RGUI-Pixel-Format-Check.yml'
workflow_dispatch:
@@ -63,9 +57,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checker self-test
shell: bash
run: |
@@ -79,7 +70,7 @@ jobs:
# either way, so the self-test reports the same thing
# whether or not the tree is currently fixed - it is
# measuring the checker, not the tree.
tools/check.sh tools/rgui_pixfmt_check.c --selftest --cc gcc
python3 tools/rgui_pixfmt_check.py --selftest --cc gcc
- name: Tree check
shell: bash
@@ -91,4 +82,4 @@ jobs:
# an empty and a full field; the field must be monotonic in
# the input; and the dithered twin must cover the same bits
# and stay within one level of the plain converter.
tools/check.sh tools/rgui_pixfmt_check.c --cc gcc
python3 tools/rgui_pixfmt_check.py --cc gcc
+1 -17
View File
@@ -3,23 +3,7 @@ name: CI RS90 Odbeta MIPS32
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/RS90.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/RS90.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-dingux:odbeta
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
+2 -20
View File
@@ -30,21 +30,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Removed-Member-Check.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Removed-Member-Check.yml'
# ci_paths: end
workflow_dispatch:
permissions:
@@ -67,12 +55,6 @@ jobs:
# Both ends of the range have to be present, and a pull
# request's base can be behind by any amount.
fetch-depth: 0
# The history without its file contents: the diff fetches
# the few it reads. A fifth of the clone.
filter: blob:none
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checker self-test
shell: bash
@@ -89,7 +71,7 @@ jobs:
# The fixtures are handed to the checker directly rather than
# taken from the tree, so this reports the same thing whether
# or not the tree currently passes - it measures the checker.
tools/check.sh tools/removed_member_check.c --selftest
python3 tools/removed_member_check.py --selftest
- name: Range check
shell: bash
@@ -119,7 +101,7 @@ jobs:
# Every struct member the range removes, minus the ones the
# tree still declares somewhere, against every .c .h .m .mm
# .cpp .hpp and .inc reader of one.
tools/check.sh tools/removed_member_check.c --range "$base..$head"
python3 tools/removed_member_check.py --range "$base..$head"
env:
PR_BASE: ${{ github.event.pull_request.base.sha }}
PR_HEAD: ${{ github.event.pull_request.head.sha }}
+1 -17
View File
@@ -3,23 +3,7 @@ name: CI RetroFW MIPS32
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/RetroFW.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/RetroFW.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-dingux:odbeta
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
@@ -1,56 +0,0 @@
name: CI Sample object directories
on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Samples-Objdir-Check.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/Samples-Objdir-Check.yml'
# ci_paths: end
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
sample-objdir-check:
name: Every sample builds its objects in its own directory
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Checker self-test
shell: bash
run: |
set -eu
tools/check.sh tools/sample_objdir_check.c --selftest
- name: Tree check
shell: bash
run: |
set -eu
# unity_identity once linked the ASan objects mic_handshake
# left beside the shared sources.
tools/check.sh tools/sample_objdir_check.c
+3 -11
View File
@@ -8,14 +8,6 @@ on:
push:
tags:
- "v*.*"
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/SourceRelease.yml'
# ci_paths: end
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
@@ -31,9 +23,6 @@ jobs:
with:
submodules: recursive
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: archive
id: archive
run: |
@@ -45,6 +34,9 @@ jobs:
mv * /tmp/$PKGNAME
mv /tmp/$PKGNAME .
rm -rf $PKGNAME/pkg || true
rm -rf $PKGNAME/wii/libogc || true
rm -rf $PKGNAME/deps/glslang/glslang/Test || true
rm -rf $PKGNAME/deps/SPIRV-Cross/reference || true
rm -rf $PKGNAME/gfx/include/userland || true
find $PKGNAME/ -type f -name '*.a' -delete || true
find $PKGNAME/ -type f -name '*.lib' -delete || true
+2 -61
View File
@@ -3,23 +3,7 @@ name: CI Switch/libnx
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Switch-libnx.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Switch-libnx.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,58 +23,15 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-libnx-devkitpro:v4-10-0
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: actions/checkout@v4
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Set up ccache
run: |
# Best effort: without ccache, ccache-make.sh runs plain make.
command -v ccache > /dev/null || {
s=$(command -v sudo || true)
for i in 1 2 3; do
$s timeout 90 apt-get -yq update \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 &&
$s timeout 120 apt-get -yq install --no-install-recommends \
ccache > /dev/null && break
echo "installing ccache failed (attempt $i); retrying in 10s"
sleep 10
done
}
echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> "$GITHUB_ENV"
echo "CCACHE_MAXSIZE=250M" >> "$GITHUB_ENV"
if command -v ccache > /dev/null; then
CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" ccache -z
fi
- name: Compile RA
run: |
make -f Makefile.libnx -j$(getconf _NPROCESSORS_ONLN) clean
bash .github/workflows/scripts/ccache-make.sh -f Makefile.libnx -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv || ccache -s
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
make -f Makefile.libnx -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
+4 -63
View File
@@ -3,23 +3,7 @@ name: CI Wii
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Wii.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Wii.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -38,8 +22,8 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: devkitpro/devkitppc:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
image: reallibretroretroarch/libretro-build-devkitpro:latest
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
@@ -47,52 +31,9 @@ jobs:
- name: Compile Salamander
run: |
make -f Makefile.wii.salamander -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.wii.salamander -j$(getconf _NPROCESSORS_ONLN)
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Set up ccache
run: |
# Best effort: without ccache, ccache-make.sh runs plain make.
command -v ccache > /dev/null || {
s=$(command -v sudo || true)
for i in 1 2 3; do
$s timeout 90 apt-get -yq update \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 &&
$s timeout 120 apt-get -yq install --no-install-recommends \
ccache > /dev/null && break
echo "installing ccache failed (attempt $i); retrying in 10s"
sleep 10
done
}
echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> "$GITHUB_ENV"
echo "CCACHE_MAXSIZE=250M" >> "$GITHUB_ENV"
if command -v ccache > /dev/null; then
CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" ccache -z
fi
make -f Makefile.wii.salamander -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0
- name: Compile RA
run: |
make -f Makefile.wii -j$(getconf _NPROCESSORS_ONLN) clean
bash .github/workflows/scripts/ccache-make.sh -f Makefile.wii -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv || ccache -s
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: .ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
make -f Makefile.wii -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1 info all
+1 -17
View File
@@ -3,23 +3,7 @@ name: CI WiiU
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/WiiU.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/WiiU.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,7 +23,7 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-wiiu:latest
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
-16
View File
@@ -3,23 +3,7 @@ name: CI Windows ARM64 (MSVC)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Windows-ARM64.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Windows-ARM64.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
release:
+2 -46
View File
@@ -3,23 +3,7 @@ name: CI Windows i686 (MXE)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Windows-i686-MXE.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Windows-i686-MXE.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,42 +23,14 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-mxe-win32-cross:gcc16
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Compile RA
run: |
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
ccache -M 250M
ccache -z
export MOC=/usr/lib/mxe/usr/i686-w64-mingw32.shared/qt5/bin/moc
CC="ccache i686-w64-mingw32.shared-gcc" \
CXX="ccache i686-w64-mingw32.shared-g++" \
./configure --host=i686-w64-mingw32.shared
./configure --host=i686-w64-mingw32.shared
make clean
make -j$(getconf _NPROCESSORS_ONLN)
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-208
View File
@@ -1,208 +0,0 @@
name: CI Windows raw input under Wine
# The Windows build's raw input path, run for real. The other winraw
# tests take the drivers apart and stand in for the frontend around
# them; this one cross-builds retroarch.exe with mingw-w64, runs it
# under Wine on a virtual display with the GDI video driver, the raw
# input driver and the raw input joypad driver, presses keys in its
# window and reads its log.
#
# It runs a small core that writes to the log what reaches it. Four
# scenarios, each: two keys, a fullscreen toggle (which restarts the
# GDI video driver), the two keys again, quit with Escape - and in each
# the core must have seen its button and its key events before the
# restart and after it. Read by the poll and kept across the restart
# (the default); restarted with the video driver
# (RETROARCH_INPUT_KEEP=0); threaded video off; and DirectInput.
# In all of those the window is left up across both restarts and
# taken back; two more destroy it with the driver as before
# (RETROARCH_WINDOW_KEEP=0) and leave it up without taking it (=2).
# Those use the GDI video driver. Two more use OpenGL on Wine's
# software rasteriser: the fullscreen toggle restyling the window in
# place, and - with that turned off - restarting on the kept window.
# See samples/input/windows_wine_smoke/run.sh.
#
# Wine is not Windows: what this holds is that the frontend, the pump,
# the two drivers and the driver restart fit together, on every commit
# that touches them. What only Windows answers - whether its raw input
# reaches a window on a thread without the focus, what a real
# controller sends - was tried by hand when the path was made.
on:
push:
branches:
- master
paths:
- 'input/input_driver.c'
- 'input/input_driver.h'
- 'input/input_driver_choice.c'
- 'input/drivers/winraw_input.c'
- 'input/drivers/winraw_mouse_pending.h'
- 'input/drivers/winraw_mouse_buttons.h'
- 'input/drivers_joypad/winraw_joypad.c'
- 'gfx/common/win32_common.c'
- 'gfx/common/win32_msg_route.h'
- 'gfx/common/win32_ime.h'
- 'samples/input/win32_ime/**'
- 'gfx/display_servers/dispserv_win32.c'
- 'gfx/drivers/gdi_gfx.c'
- 'gfx/drivers_context/wgl_ctx.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'ui/drivers/ui_win32.c'
- 'retroarch.c'
- 'runloop.c'
- 'samples/input/windows_wine_smoke/**'
- '.github/workflows/Windows-wine-input.yml'
pull_request:
paths:
- 'input/input_driver.c'
- 'input/input_driver.h'
- 'input/input_driver_choice.c'
- 'input/drivers/winraw_input.c'
- 'input/drivers/winraw_mouse_pending.h'
- 'input/drivers/winraw_mouse_buttons.h'
- 'input/drivers_joypad/winraw_joypad.c'
- 'gfx/common/win32_common.c'
- 'gfx/common/win32_msg_route.h'
- 'gfx/common/win32_ime.h'
- 'samples/input/win32_ime/**'
- 'gfx/display_servers/dispserv_win32.c'
- 'gfx/drivers/gdi_gfx.c'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'ui/drivers/ui_win32.c'
- 'retroarch.c'
- 'runloop.c'
- 'samples/input/windows_wine_smoke/**'
- '.github/workflows/Windows-wine-input.yml'
workflow_dispatch:
permissions:
contents: read
# Only pull requests cancel a superseded run. On master every push
# gets its own group (keyed by the commit), so a burst of pushes queues
# instead of cancelling the run for the commit before it.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
windows-wine-input:
name: Run retroarch.exe under Wine and press keys
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential ccache gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 wine64 xvfb xdotool libgl1-mesa-dri
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Build and run win32_ime_test under Wine
shell: bash
run: |
set -eu
# The window has its input context (the IME) only while a line
# of text is open: gfx/common/win32_ime.h, driven from another
# thread as the frontend does, the window asked on its own.
Xvfb :97 -screen 0 640x480x24 > /dev/null 2>&1 &
trap 'kill $! 2>/dev/null; wineserver -k >/dev/null 2>&1 || true' EXIT
export DISPLAY=:97
make -C samples/input/win32_ime check
make -C samples/input/win32_ime clean
- name: Build and run winusb_hid_test under Wine
shell: bash
run: |
set -eu
# The WinUSB HID driver with the real pad handlers and a
# stand-in for winusb.dll: a DualShock 3 started by HID class
# requests on the control pipe, the newest report its reader
# has had taken at the poll, its Bluetooth address read and
# set, and a pad that goes or a driver that stops letting the
# reader go.
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
make -C samples/input/winusb_hid check
make -C samples/input/winusb_hid clean
- name: Build retroarch.exe with mingw-w64 (GDI and raw input, the rest off)
shell: bash
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
ccache -M 250M
ccache -z
# What the test runs has to be real: the Win32 window code,
# the GDI and OpenGL drivers, the raw input drivers, the
# menu, threads. Everything else is build time.
./configure --host=x86_64-w64-mingw32 \
--disable-qt --disable-vulkan --disable-ffmpeg \
--disable-networking --disable-cheevos \
--disable-glslang --disable-slang \
--disable-spirv_cross --disable-xmb \
--disable-materialui --disable-ozone \
--disable-7zip --disable-flac \
--disable-audiomixer --disable-translate \
--disable-accessibility --disable-langextra \
--disable-libretrodb --disable-discord \
--disable-d3d9 --disable-d3d10 --disable-d3d11 \
--disable-d3d12 --disable-sdl \
--disable-sdl2 --disable-video_filter \
--disable-dsp_filter --disable-crtswitchres
make -j$(nproc) CC="ccache x86_64-w64-mingw32-gcc" \
CXX="ccache x86_64-w64-mingw32-g++"
ccache -s
test -f retroarch.exe
- name: Run the scenarios under Wine
shell: bash
run: |
set -eu
# Stop wineserver on exit so it cannot hold the step's output
# open.
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
timeout 900 samples/input/windows_wine_smoke/run.sh
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-246
View File
@@ -1,246 +0,0 @@
name: CI Windows menus under Wine
# Ozone, XMB, MaterialUI and RGUI as each Direct3D driver and both GL
# drivers draw them. Cross-builds retroarch.exe with mingw-w64, starts
# it with no content under Wine on a virtual display for each menu on
# each driver, reads the screen once it holds still and compares it
# with D3D11's block by block. A solid quad sampling the wrong texture
# (d3d9_hlsl's batched quads read the font atlas) or a gradient split
# along the other diagonal (both D3D9 drivers' single quads) moves
# whole blocks; the drivers' own text and edge differences do not.
# See samples/gfx/menu_wine/run.py. Then a core writes its frames into
# the framebuffer d3d9_hlsl lends it - still, cropped, and through the
# driver growing its textures - checked against D3D11's copy
# (samples/gfx/menu_wine/swfb.py).
on:
push:
paths:
- 'gfx/drivers/d3d*.c'
- 'gfx/drivers/gl2.c'
- 'gfx/drivers/gl3.c'
- 'gfx/drivers/d3d_shaders/**'
- 'gfx/common/d3d*'
- 'gfx/common/gl*'
- 'gfx/gfx_display.*'
- 'gfx/font_driver.*'
- 'gfx/font_layout.h'
- 'gfx/drivers_font/**'
- 'gfx/drivers_font_renderer/**'
- 'menu/drivers/**'
- 'menu/menu_driver.*'
- 'samples/gfx/menu_wine/**'
- 'samples/gfx/d3d12_menu_mapping/**'
- 'samples/gfx/threaded_video/harness_core.c'
- 'samples/gfx/d3d9_ex/**'
- '.github/workflows/Windows-wine-menu.yml'
pull_request:
paths:
- 'gfx/drivers/d3d*.c'
- 'gfx/drivers/gl2.c'
- 'gfx/drivers/gl3.c'
- 'gfx/drivers/d3d_shaders/**'
- 'gfx/common/d3d*'
- 'gfx/common/gl*'
- 'gfx/gfx_display.*'
- 'gfx/font_driver.*'
- 'gfx/font_layout.h'
- 'gfx/drivers_font/**'
- 'gfx/drivers_font_renderer/**'
- 'menu/drivers/**'
- 'menu/menu_driver.*'
- 'samples/gfx/menu_wine/**'
- 'samples/gfx/d3d12_menu_mapping/**'
- 'samples/gfx/threaded_video/harness_core.c'
- 'samples/gfx/d3d9_ex/**'
- '.github/workflows/Windows-wine-menu.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
windows-wine-menu:
name: Menus on D3D8, D3D9, D3D10, D3D11, D3D12 and GL under Wine
runs-on: ubuntu-24.04
env:
APT_PKGS: build-essential ccache gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64-tools wine64 xvfb xauth imagemagick libgl1-mesa-dri mesa-vulkan-drivers libvulkan1 autoconf automake libtool flex bison pkg-config libvulkan-dev spirv-headers python3
timeout-minutes: 90
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Build vkd3d's shader compiler for Windows
shell: bash
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
v="$RUNNER_TEMP/vkd3d"
git clone -q --depth 1 --branch vkd3d-2.1 \
https://gitlab.winehq.org/wine/vkd3d.git "$v"
cd "$v"
./autogen.sh > /dev/null
mkdir -p inc lib build
ln -s /usr/include/vulkan inc/vulkan
ln -s /usr/include/vk_video inc/vk_video
ln -s /usr/include/spirv inc/spirv
printf 'LIBRARY vulkan-1.dll\nEXPORTS\nvkGetInstanceProcAddr\n' \
> lib/vulkan-1.def
x86_64-w64-mingw32-dlltool -d lib/vulkan-1.def \
-l lib/libvulkan-1.a
cd build
../configure -q --host=x86_64-w64-mingw32 --disable-tests \
--disable-demos WIDL=x86_64-w64-mingw32-widl \
CPPFLAGS="-I$v/inc" LDFLAGS="-L$v/lib"
make -j$(nproc) > /dev/null
cp .libs/libvkd3d-utils-1.dll "$GITHUB_WORKSPACE/D3DCompiler_47.dll"
cp .libs/libvkd3d-shader-1.dll .libs/libvkd3d-1.dll \
"$GITHUB_WORKSPACE/"
- name: Build retroarch.exe with mingw-w64 (D3D8, D3D9, D3D10, D3D11, D3D12, GL)
shell: bash
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
ccache -M 250M
./configure --host=x86_64-w64-mingw32 \
--disable-qt --disable-vulkan --disable-ffmpeg \
--disable-cheevos --disable-discord --enable-d3d8 \
--disable-sdl --disable-sdl2
make -j$(nproc) CC="ccache x86_64-w64-mingw32-gcc" \
CXX="ccache x86_64-w64-mingw32-g++"
ccache -s
for f in libstdc++-6.dll libgcc_s_seh-1.dll; do
cp "$(ls /usr/lib/gcc/x86_64-w64-mingw32/*-win32/$f | head -n 1)" .
done
- name: Menus on every driver, compared with D3D11 (Wine, Xvfb, llvmpipe)
shell: bash
run: |
set -eu
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
export LIBGL_ALWAYS_SOFTWARE=1
WINEDEBUG=-all timeout 120 xvfb-run -a sh -c 'wineboot -i && wineserver -w'
python3 samples/gfx/menu_wine/run.py ./retroarch.exe \
"$RUNNER_TEMP/menu-wine" d3d11 d3d10 d3d12 d3d9_hlsl d3d8 gl glcore
- name: D3D12 menu component mapping on the GPU (Wine)
shell: bash
run: |
set -eu
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
export LIBGL_ALWAYS_SOFTWARE=1
CC=x86_64-w64-mingw32-gcc RUNNER=wine \
xvfb-run -a python3 samples/gfx/d3d12_menu_mapping/run.py
CC=x86_64-w64-mingw32-gcc RUNNER=wine REQUIRE_D3D11=1 \
xvfb-run -a python3 samples/gfx/d3d_failure_paths/gpu.py
CC=x86_64-w64-mingw32-gcc RUNNER=wine REQUIRE_D3D11=1 \
xvfb-run -a python3 samples/gfx/d3d_failure_paths/lend_gpu.py
CC=x86_64-w64-mingw32-gcc RUNNER=wine REQUIRE_D3D11=1 \
xvfb-run -a python3 samples/gfx/d3d_failure_paths/sw_lend_gpu.py
CC=x86_64-w64-mingw32-gcc RUNNER=wine REQUIRE_D3D10=1 \
xvfb-run -a python3 samples/gfx/d3d_failure_paths/sw_lend10_gpu.py
- name: A core writing into the framebuffer d3d9_hlsl lends it (Wine)
shell: bash
run: |
set -eu
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
(cd samples/gfx/threaded_video && x86_64-w64-mingw32-gcc -O1 \
-shared -I../../../libretro-common/include -I../../../gfx/include \
-o ../../../harness_core.dll harness_core.c)
python3 samples/gfx/menu_wine/swfb.py ./retroarch.exe \
./harness_core.dll "$RUNNER_TEMP/menu-wine/swfb" d3d9_hlsl
python3 samples/gfx/menu_wine/swfb.py ./retroarch.exe \
./harness_core.dll "$RUNNER_TEMP/menu-wine/swfb-d3d10" d3d10
- name: D3D9 textures and frame memory on a Direct3D9Ex device and a plain one (Wine)
shell: bash
run: |
set -eu
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
# What reached the GPU, read back: the managed pool before Ex,
# default-pool textures with system-memory twins on it, and the
# frames it reads where they lie; then a device in the flip
# model, its frame latency and d3d9_present's ways to wait
make -C samples/gfx/d3d9_ex check
- name: d3d9_hlsl with Direct3D 9Ex Presentation, and without Ex (Wine)
shell: bash
run: |
set -eu
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
# The window in the flip model and the frame latency taken on
# Ex, the same screens; as before where there is no Ex
export SWFB_D3D9EX_PRESENT=2
python3 samples/gfx/menu_wine/swfb.py ./retroarch.exe \
./harness_core.dll "$RUNNER_TEMP/menu-wine/swfb-present" d3d9_hlsl
RETROARCH_D3D9EX=0 python3 samples/gfx/menu_wine/swfb.py \
./retroarch.exe ./harness_core.dll \
"$RUNNER_TEMP/menu-wine/swfb-present-legacy" d3d9_hlsl
- name: d3d9_hlsl without Direct3D9Ex, as a system without it has (Wine)
shell: bash
run: |
set -eu
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
export RETROARCH_D3D9EX=0
python3 samples/gfx/menu_wine/run.py ./retroarch.exe \
"$RUNNER_TEMP/menu-wine/legacy" d3d11 d3d9_hlsl
python3 samples/gfx/menu_wine/swfb.py ./retroarch.exe \
./harness_core.dll "$RUNNER_TEMP/menu-wine/swfb-legacy" d3d9_hlsl
- name: Preserve screens on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: windows-wine-menu-screens
path: |
${{ runner.temp }}/menu-wine/**/*.png
${{ runner.temp }}/menu-wine/**/*.log
if-no-files-found: ignore
- name: Save ccache
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-194
View File
@@ -1,194 +0,0 @@
name: CI Windows views under Wine
# Views on the GDI, D3D8, D3D9 HLSL, D3D10, D3D11 and D3D12 drivers, end
# to end: retroarch.exe cross-built with mingw-w64 runs the video_views
# test core under Wine, on a virtual display through Mesa's software
# rasterisers (D3D12 on Wine's vkd3d over lavapipe), and
# samples/cores/video_views/e2e/run.py checks the screen in each stereo
# mode, from the core's software frames and its D3D11 and D3D12
# textures, with the menu laid out per eye and the pointer over it.
# Wine's own shader compiler can't take the drivers' HLSL, so vkd3d's,
# from its release, is put in as D3DCompiler_47.dll.
on:
push:
branches:
- master
paths:
- 'gfx/common/d3d9_*'
- 'gfx/drivers/gdi_gfx.c'
- 'gfx/common/gdi_defines.h'
- 'gfx/drivers/d3d8.c'
- 'gfx/drivers/d3d9hlsl.c'
- 'gfx/drivers/d3d10.c'
- 'gfx/drivers/d3d11.c'
- 'gfx/drivers/d3d12.c'
- 'gfx/drivers/d3d_shaders/views_sm*.hlsl.h'
- 'gfx/video_views.*'
- 'gfx/video_views_draw.h'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'configuration.*'
- 'samples/settings/video_screens/**'
- 'samples/cores/video_views/**'
- '.github/workflows/Windows-wine-views.yml'
pull_request:
paths:
- 'gfx/common/d3d9_*'
- 'gfx/drivers/gdi_gfx.c'
- 'gfx/common/gdi_defines.h'
- 'gfx/drivers/d3d8.c'
- 'gfx/drivers/d3d9hlsl.c'
- 'gfx/drivers/d3d10.c'
- 'gfx/drivers/d3d11.c'
- 'gfx/drivers/d3d12.c'
- 'gfx/drivers/d3d_shaders/views_sm*.hlsl.h'
- 'gfx/video_views.*'
- 'gfx/video_views_draw.h'
- 'gfx/video_driver.c'
- 'gfx/video_thread_wrapper.*'
- 'configuration.*'
- 'samples/settings/video_screens/**'
- 'samples/cores/video_views/**'
- '.github/workflows/Windows-wine-views.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
windows-wine-views:
name: Views on GDI, D3D8, D3D9, D3D10, D3D11 and D3D12 under Wine
runs-on: ubuntu-24.04
env:
APT_PKGS: build-essential ccache gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64-tools wine64 xvfb xauth imagemagick libgl1-mesa-dri mesa-vulkan-drivers libvulkan1 autoconf automake libtool flex bison pkg-config libvulkan-dev spirv-headers python3
timeout-minutes: 150
steps:
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Build vkd3d's shader compiler for Windows
shell: bash
run: |
set -eu
. "$GITHUB_WORKSPACE/.github/workflows/scripts/wine-server.sh"
v="$RUNNER_TEMP/vkd3d"
git clone -q --depth 1 --branch vkd3d-2.1 \
https://gitlab.winehq.org/wine/vkd3d.git "$v"
cd "$v"
./autogen.sh > /dev/null
# Its headers from the host; vulkan-1.dll is loaded at run
# time, so an import library naming it does.
mkdir -p inc lib build
ln -s /usr/include/vulkan inc/vulkan
ln -s /usr/include/vk_video inc/vk_video
ln -s /usr/include/spirv inc/spirv
printf 'LIBRARY vulkan-1.dll\nEXPORTS\nvkGetInstanceProcAddr\n' \
> lib/vulkan-1.def
x86_64-w64-mingw32-dlltool -d lib/vulkan-1.def \
-l lib/libvulkan-1.a
cd build
../configure -q --host=x86_64-w64-mingw32 --disable-tests \
--disable-demos WIDL=x86_64-w64-mingw32-widl \
CPPFLAGS="-I$v/inc" LDFLAGS="-L$v/lib"
make -j$(nproc) > /dev/null
cp .libs/libvkd3d-utils-1.dll "$GITHUB_WORKSPACE/D3DCompiler_47.dll"
cp .libs/libvkd3d-shader-1.dll .libs/libvkd3d-1.dll \
"$GITHUB_WORKSPACE/"
- name: Build retroarch.exe with mingw-w64 (D3D8, D3D9, D3D10, D3D11, D3D12, slang)
shell: bash
run: |
set -eu
export CCACHE_DIR="$HOME/.ccache"
ccache -M 250M
# The screens' windows too, which video_screens_test runs.
./configure --host=x86_64-w64-mingw32 \
--disable-qt --disable-vulkan --disable-ffmpeg \
--disable-cheevos --disable-discord --enable-d3d8 \
--disable-sdl --disable-sdl2 --enable-video_windows
make -j$(nproc) CC="ccache x86_64-w64-mingw32-gcc" \
CXX="ccache x86_64-w64-mingw32-g++"
ccache -s
# The C and C++ runtimes it was linked against
for f in libstdc++-6.dll libgcc_s_seh-1.dll; do
cp "$(ls /usr/lib/gcc/x86_64-w64-mingw32/*-win32/$f | head -n 1)" .
done
make -C samples/cores/video_views DLL=1 CC=x86_64-w64-mingw32-gcc
- name: Build and run video_screens_test under Wine
shell: bash
run: |
set -eu
WINEDEBUG=-all xvfb-run -a python3 samples/settings/video_screens/build.py \
--output-dir "$RUNNER_TEMP/video-screens" --runner wine
- name: Views on GDI, D3D8, D3D9, D3D10, D3D11 and D3D12, end to end (Wine, Xvfb, llvmpipe, lavapipe)
shell: bash
run: |
set -eu
trap 'wineserver -k >/dev/null 2>&1 || true' EXIT
export LIBGL_ALWAYS_SOFTWARE=1
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/lvp_icd.json
# Initialize the prefix with a display and wait for setup to finish.
WINEDEBUG=-all timeout 120 xvfb-run -a sh -c 'wineboot -i && wineserver -w'
RA_E2E_WINE=1 python3 samples/cores/video_views/e2e/run.py \
./retroarch.exe "$RUNNER_TEMP/views-e2e" gdi d3d8 d3d9_hlsl d3d10 d3d11 d3d12
# And d3d9_hlsl on the device of a system without Direct3D9Ex
RETROARCH_D3D9EX=0 RA_E2E_WINE=1 python3 samples/cores/video_views/e2e/run.py \
./retroarch.exe "$RUNNER_TEMP/views-e2e-legacy" d3d9_hlsl
- name: Preserve views logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: windows-wine-views-logs
path: ${{ runner.temp }}/views-e2e/**/*.log
if-no-files-found: ignore
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
+2 -46
View File
@@ -3,23 +3,7 @@ name: CI Windows x64 (MXE)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Windows-x64-MXE.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/Windows-x64-MXE.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
@@ -39,42 +23,14 @@ jobs:
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-mxe-win64-cross:gcc16
options: --user root --dns 1.1.1.1 --dns 8.8.8.8
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
ccache-${{ github.workflow }}-${{ github.job }}-
- name: Compile RA
run: |
export CCACHE_DIR="$HOME/.ccache"
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
ccache -M 250M
ccache -z
export MOC=/usr/lib/mxe/usr/x86_64-w64-mingw32.shared/qt5/bin/moc
CC="ccache x86_64-w64-mingw32.shared-gcc" \
CXX="ccache x86_64-w64-mingw32.shared-g++" \
./configure --host=x86_64-w64-mingw32.shared
./configure --host=x86_64-w64-mingw32.shared
make clean
make -j$(getconf _NPROCESSORS_ONLN)
- name: ccache statistics
if: ${{ !cancelled() }}
continue-on-error: true
run: ccache -sv
- name: Save ccache
# Only master's pushes keep a cache: pull requests restore
# master's, so one push does not evict the next one's.
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ccache-${{ github.workflow }}-${{ github.job }}-${{ github.sha }}
-3
View File
@@ -27,9 +27,6 @@ jobs:
python-version: '3.10'
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Crowdin Sync
shell: bash
env:
-3
View File
@@ -29,9 +29,6 @@ jobs:
python-version: '3.10'
- name: Checkout
uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Crowdin Sync
shell: bash
env:
-101
View File
@@ -1,101 +0,0 @@
name: CI iOS 6 (armv7)
# The iOS 6 build - RetroArch_iOS6.xcodeproj's defines, ARC, armv7,
# a 6.0 deployment target - compiled against the iOS 9.3 SDK, the last
# that takes a 6.0 floor. No runner Xcode can build armv7 or anything
# below iOS 12 any more, so this runs clang on Linux against the SDK's
# headers, as the PowerPC leg does for old macOS. Every warning is an
# error: anything newer than iOS 6 has to be behind a runtime check,
# and -Wunguarded-availability is what says so.
#
# The checking is .github/workflows/scripts/ios-legacy-check.sh, which
# runs by hand the same way; this job fetches the SDK headers for it.
#
# SDK: theos/sdks, pinned to a commit; only the headers are checked out.
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/iOS-Legacy.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!.github/workflows/*.yml'
- '.github/workflows/iOS-Legacy.yml'
# ci_paths: end
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
SDKS_COMMIT: 0222fd5413cf4b9af096f37b4621afa2688572f7
SDK: iPhoneOS9.3.sdk
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-24.04
env:
APT_PKGS: clang-18
timeout-minutes: 30
steps:
- uses: actions/checkout@v5
- name: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- 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 clang
timeout-minutes: 10
run: |
sh .github/workflows/scripts/apt-install.sh $APT_PKGS
clang-18 --version | head -n 1
- 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: Fetch the iOS SDK headers
run: |
set -e
git init -q "$RUNNER_TEMP/sdks"
cd "$RUNNER_TEMP/sdks"
git remote add origin https://github.com/theos/sdks.git
git config core.sparseCheckout true
printf '%s\n' \
"/$SDK/usr/include/" \
"/$SDK/System/Library/Frameworks/*/Headers/" \
"/$SDK/System/Library/Frameworks/*/Frameworks/*.framework/Headers/" \
> .git/info/sparse-checkout
git fetch -q --depth 1 --filter=blob:none origin "$SDKS_COMMIT"
git checkout -q FETCH_HEAD
du -sh "$SDK"
- name: iOS 6.0
run: CC=clang-18 .github/workflows/scripts/ios-legacy-check.sh "$RUNNER_TEMP/sdks/$SDK" 6.0
-16
View File
@@ -3,23 +3,7 @@ name: CI iOS (13)
on:
push:
branches: [master]
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/iOS.yml'
# ci_paths: end
pull_request:
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/iOS.yml'
# ci_paths: end
permissions:
contents: read
+2 -6
View File
@@ -73,11 +73,11 @@ jobs:
working-directory: libretro-common
run: |
set -e
cc -std=gnu99 -O1 -g1 -Wall -DHAVE_THREADS -Iinclude \
cc -std=gnu99 -O1 -g -Wall -DHAVE_THREADS -Iinclude \
samples/rthreads/retro_procbarrier_test/retro_procbarrier_test.c \
rthreads/retro_procbarrier.c rthreads/rthreads.c \
-o retro_procbarrier_test ${{ matrix.libs }}
cc -std=gnu99 -O1 -g1 -Wall -DHAVE_THREADS -Iinclude \
cc -std=gnu99 -O1 -g -Wall -DHAVE_THREADS -Iinclude \
samples/rthreads/retro_asym_eventcount_test/retro_asym_eventcount_test.c \
rthreads/retro_asym_eventcount.c \
rthreads/retro_procbarrier.c rthreads/rthreads.c \
@@ -129,10 +129,6 @@ jobs:
rthreads\retro_procbarrier.c rthreads\rthreads.c ^
/Fe:retro_asym_eventcount_test.exe
if errorlevel 1 exit /b 1
cl /nologo /W3 /we4013 /O1 /TC /Iinclude ^
/DWINAPI_FAMILY=WINAPI_FAMILY_APP /D_WIN32_WINNT=0x0A00 ^
/c rthreads\retro_procbarrier.c /Fo:retro_procbarrier_uwp.obj
if errorlevel 1 exit /b 1
- name: Run every tier
shell: bash
+39 -44
View File
@@ -6,25 +6,9 @@ on:
push:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/retroarch.yml'
# ci_paths: end
pull_request:
branches:
- master
# ci_paths: generated by tools/ci_paths.py, do not edit
paths:
- '**'
- '!samples/**'
- '!libretro-common/samples/**'
- '!.github/workflows/*.yml'
- '.github/workflows/retroarch.yml'
# ci_paths: end
permissions:
contents: read
@@ -39,37 +23,48 @@ concurrency:
jobs:
linux-c89: # Smoketest build using most restrictive compiler and default options
runs-on: ubuntu-latest
env:
APT_PKGS: build-essential libxkbcommon-dev libx11-xcb-dev libvulkan-dev libpipewire-0.3-dev zlib1g-dev libfreetype-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev nvidia-cg-toolkit nvidia-cg-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 20
run: |
# libvulkan-dev brings the Vulkan driver, the slang shader stack
# (shader_vulkan.c, slang_process.c, glslang_util.c, slang_cache.c)
# and the Vulkan contexts into this lane; without it configure
# drops them and none of those C files ever meet -std=c89.
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev libvulkan-dev zlib1g-dev libfreetype6-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev nvidia-cg-toolkit nvidia-cg-dev libavcodec-dev libsdl2-dev libsdl-image1.2-dev libxml2-dev yasm"
if dpkg -s $pkgs >/dev/null 2>&1; then
echo "All packages already present on runner image; skipping apt."
exit 0
fi
for i in 1 2 3; do
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
# Fetch first, under a bound: a download is safe to stop and
# resumes, an install is not. A mirror that stalls is left for
# the main archive on the next attempt.
for i in 1 2 3; do
sudo timeout 240 apt-get install -y --download-only \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs && break
[ $i = 3 ] && exit 1
echo "package download failed or stalled (attempt $i); retrying from archive.ubuntu.com"
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do
[ -f "$f" ] || continue
sudo sed -i -e 's#mirror+file:/etc/apt/apt-mirrors.txt#http://archive.ubuntu.com/ubuntu/#g' \
-e 's#http://azure\.archive\.ubuntu\.com/ubuntu#http://archive.ubuntu.com/ubuntu#g' "$f"
done
sudo timeout 90 apt-get update -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 || true
done
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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 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: Link with lld
run: sh .github/workflows/scripts/use-lld.sh
- name: Configure
run: ./configure
- name: Build
@@ -77,4 +72,4 @@ jobs:
- name: Build Debug
run: |
make clean # making sure we don't have leftovers from previous build
CFLAGS="-O0 -g1" CXXFLAGS="-O0 -g1" make DEBUG=1 GL_DEBUG=1 C89_BUILD=1 info all
make DEBUG=1 GL_DEBUG=1 C89_BUILD=1 info all
@@ -1,20 +0,0 @@
#!/bin/sh
# The actions/cache key for apt-install.sh's cache: the packages asked
# for and the runner image. Jobs asking for the same packages share an
# entry, so the repository's cache holds each set once. A new runner
# image makes a new entry, seeded through the prefix by the last one's;
# apt-install.sh refreshes what no longer resolves.
# Off x86-64 the key also names the runner's architecture.
#
# apt-cache-key.sh "PACKAGE..." (writes key= and prefix= to
# GITHUB_OUTPUT)
set -eu
pkgs=$(printf '%s\n' $1 | sort -u | tr '\n' ' ')
hash=$(printf '%s' "$pkgs" | sha256sum | cut -c1-16)
arch=
[ "${RUNNER_ARCH:-X64}" = X64 ] || arch="$RUNNER_ARCH-"
prefix="apt-${ImageOS:-unknown}-$arch$hash-"
key="$prefix${ImageVersion:-unknown}"
echo "key=$key" >> "$GITHUB_OUTPUT"
echo "prefix=$prefix" >> "$GITHUB_OUTPUT"
echo "apt cache key: $key"
Loaded 100 of 11207 files, more files were not shown because too many files have changed in this diff. Show more