Compare commits

..
Author SHA1 Message Date
twinaphex 7b6e564ba3 (Mac) Make separate default core dirs based on architecture - note -
we will also have to write to a separate config file per architecture -
that will have to come next
2021-08-28 14:32:17 +02:00
8201 changed files with 1014486 additions and 1903539 deletions

No files matched your search

-16
View File
@@ -1,16 +0,0 @@
;;; Directory Local Variables
;;; See Info node `(emacs) Directory Variables' for more information.
(
(c-mode . ((standard-indent . 3)
(c-basic-offset . 3)
(c-file-offsets . ((arglist-intro . ++)
(arglist-cont-nonempty . ++)
(block-close . 0)
(block-open . 0)))
(eval . (setq-local c-cleanup-list
(cl-set-difference c-cleanup-list
'(brace-else-brace
brace-elseif-brace))))))
(objc-mode . ((c-basic-offset . 3)))
)
+35
View File
@@ -0,0 +1,35 @@
# First and foremost consider this:
- Only RetroArch bugs should be filed here. Not core bugs or game bugs
- This is not a forum or a help section, this is strictly developer oriented
## Description
[Description of the bug]
### Expected behavior
[What you expected to happen]
### Actual behavior
[What is actually happening]
### Steps to reproduce the bug
1. [First step]
2. [Second step]
3. [and so on...]
### Bisect Results
[Try to bisect and tell us when this started happening]
### Version/Commit
You can find this information under Information/System Information
- RetroArch: [version/commit]
### Environment information
- OS: [The operating system you're running]
- Compiler: [In case you are running local builds]
-100
View File
@@ -1,100 +0,0 @@
name: Bug report
description: This is not a forum or a help section, this is strictly developer oriented.
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Only RetroArch bugs should be filed here. Not core bugs or game bugs
options:
- label: This is a bug in RetroArch frontend
required: true
- label: I have searched the existing issues
- type: textarea
id: description
attributes:
label: Description
description: Description of the actual behavior of the bug
placeholder: What is actually happening
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: What you expected to happen
- type: textarea
id: reproduce_steps
attributes:
label: Steps to reproduce the bug
description: List all steps to reproduce the problem
placeholder: |
1. [First step]
2. [Second step]
3. [and so on...]
validations:
required: true
- type: input
id: version
attributes:
label: Version/Commit
description: You can find this information under Information/System Information
placeholder: 1.20.0 (Git ab3b175)
validations:
required: true
- type: input
id: bisecting
attributes:
label: Bisect Results
description: Did this work with any older RetroArch version? Can you point to a version (or even commit) where it broke?
placeholder: 43105ab
- type: dropdown
id: nigthly
attributes:
label: Present in the nightly version
description: Is the issue reproducible with current [nightly builds](https://buildbot.libretro.com/nightly/)?
options:
- I don't know
- Yes, this is reproduced in the nightly build
- No, looks like this is already resolved
default: 0
validations:
required: true
- type: input
id: platform
attributes:
label: Platform & operating system
description: The system you're running RetroArch on
placeholder: Linux aarch64, Windows 11 23H2, Android 14, PS Vita
validations:
required: true
- type: input
id: cores
attributes:
label: Affected Cores
description: List the affected cores and their versions here, if applicable. If the issue **only occurs with a single core** then the bug may not be with RetroArch; in that case, you should report it in that core's repository instead of here.
placeholder: bsnes (115), FCEUmm ((SVN) aebea87), Snes9x (1.63.229933ea)
- type: textarea
id: environment
attributes:
label: Environment information
description: Additional information about hardware and software
placeholder: |
* Window Manager: dwm/X11
* Affected video drivers: sdl2, glcore
* Installed through Flatpak
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Paste [RetroArch log](https://docs.libretro.com/guides/generating-retroarch-logs/) and/or [GDB backtrace](https://docs.libretro.com/development/retroarch/debugging/). This will be automatically formatted into code, so no need for backticks.
render: shell
@@ -1,6 +0,0 @@
---
name: Feature request
title: "[Feature Request] <FEATURE NAME>"
about: Is there something you'd like to see in RetroArch?
labels: feature request
---
-14
View File
@@ -1,14 +0,0 @@
blank_issues_enabled: true
contact_links:
- name: Libretro Forums
url: https://forums.libretro.com
about: A place to discuss all things libretro
- name: Discord
url: https://ra-link.web.app/discord
about: Join our Discord server for help
- name: RetroArch/libretro subreddit
url: https://www.reddit.com/r/RetroArch
about: Subreddit dedicated to RetroArch and the libretro API framework
- name: Documentation
url: https://docs.libretro.com
about: Official RetroArch documentation for users and developers
-1
View File
@@ -3,7 +3,6 @@
1. Rebase before opening a pull request
2. If you are sending several unrelated fixes or features, use a branch and a separate pull request for each
3. If possible try squashing everything in a single commit. This is particularly beneficial in the case of feature merges since it allows easy bisecting when a problem arises
4. RetroArch codebase follows C89 coding rules for portability across many old platforms check using `C89_BUILD=1`
## Description
-39
View File
@@ -1,39 +0,0 @@
name: CI 3DS
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-devkitpro:latest
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Compile Salamander
run: |
make -f Makefile.ctr.salamander -j$(getconf _NPROCESSORS_ONLN) USE_CTRULIB_2=1 clean
make -f Makefile.ctr.salamander -j$(getconf _NPROCESSORS_ONLN) USE_CTRULIB_2=1
- name: Compile RA
run: |
make -f Makefile.ctr -j$(getconf _NPROCESSORS_ONLN) USE_CTRULIB_2=1 clean
make -f Makefile.ctr -j$(getconf _NPROCESSORS_ONLN) USE_CTRULIB_2=1 HAVE_STATIC_DUMMY=1 info all
-50
View File
@@ -1,50 +0,0 @@
name: CI Android
on:
push:
branches: [master]
pull_request:
workflow_dispatch:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-22.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v5
- name: Set up JDK 25
uses: actions/setup-java@v4
with:
java-version: '25'
distribution: 'temurin'
- name: Compile RA
run: |
cd pkg/android/phoenix
./gradlew assembleDebug
find . -iname "*.apk" -exec ls -l "{}" \;
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: retroarch-android-${{ steps.slug.outputs.sha8 }}
path: |
pkg/android/phoenix/build/outputs/apk/normal/debug/phoenix-normal-debug.apk
pkg/android/phoenix/build/outputs/apk/aarch64/debug/phoenix-aarch64-debug.apk
-152
View File
@@ -1,152 +0,0 @@
name: CI Apple
# Umbrella workflow for Apple-specific checks that are not a plain
# "does it build" - the full builds live in MacOS.yml and iOS.yml.
#
# Add new jobs here rather than as new top-level workflows: things like
# build-graph integrity checks, xcconfig assertions, extra Apple
# targets, and anything else that is Apple-shaped but does not warrant
# its own entry in the Actions sidebar. Each job carries its own
# rationale in a comment above it.
on:
push:
branches: [master]
pull_request:
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-graph guard: the Bonjour/mDNS netplay discovery path.
#
# network/netplay/netplay_nsnetservice.m is a member of no target.
# It reaches the compiler only through griffin/griffin_objc.m, behind
#
# #if defined(HAVE_NETWORKING) && defined(HAVE_NETPLAYDISCOVERY) \
# && defined(HAVE_NETPLAYDISCOVERY_NSNET)
#
# and those macros arrive from pkg/apple/BaseConfig.xcconfig by way
# of an $(inherited) chain: the CI builds pass
# -xcconfig GitHubCI.xcconfig on the command line, which includes
# Metal.xcconfig, whose OTHER_CFLAGS[sdk=macosx*] assignment relies
# on $(inherited) to pull the project-level BaseConfig settings back
# in. Metal.xcconfig defines none of the three macros itself.
#
# Every link in that chain can be broken without breaking the build.
# Drop the file from griffin's include list, drop griffin_objc.m from
# a Sources phase, drop $(inherited) from Metal.xcconfig, or move the
# -D out of BaseConfig, and the file simply stops being compiled - CI
# stays green while an entire Apple-only source file goes unbuilt.
# That is not hypothetical: the file parses a remote peer's mDNS TXT
# records into fixed-size buffers, so it is exactly the sort of thing
# that should not be able to rot unnoticed.
#
# This asserts the preconditions rather than duplicating the build.
# The existing "CI macOS" and "CI iOS (13)" jobs already compile the
# file; what they cannot tell you is whether they still are.
# ------------------------------------------------------------------
netplay-discovery-guard:
name: Build graph - netplay mDNS discovery
runs-on: macos-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v6
# Source-level checks. These need no toolchain and give a precise
# message when the wiring, rather than the code, is what broke.
- name: griffin still imports the file
run: |
set -euo pipefail
if ! grep -q 'netplay_nsnetservice\.m' griffin/griffin_objc.m; then
echo "::error file=griffin/griffin_objc.m::netplay_nsnetservice.m is no longer imported; it is a member of no target, so nothing else compiles it"
exit 1
fi
- name: griffin_objc.m is still in both Sources build phases
run: |
set -euo pipefail
rc=0
for proj in RetroArch_Metal RetroArch_iOS13; do
pbx="pkg/apple/$proj.xcodeproj/project.pbxproj"
n=$(awk '/Begin PBXSourcesBuildPhase/,/End PBXSourcesBuildPhase/' "$pbx" \
| grep -c 'griffin_objc\.m in Sources' || true)
echo "$proj: griffin_objc.m appears in Sources x$n"
if [ "$n" -eq 0 ]; then
echo "::error file=$pbx::griffin_objc.m is not in any Sources build phase"
rc=1
fi
done
exit $rc
- name: The three guard macros survive the xcconfig chain
run: |
set -euo pipefail
rc=0
check() {
# $1 = human label, remaining args = xcodebuild selector
label="$1"; shift
echo "--- $label ---"
settings=$(xcodebuild -showBuildSettings "$@" \
-xcconfig pkg/apple/GitHubCI.xcconfig 2>/dev/null \
| grep -E '^\s*OTHER_CFLAGS =' || true)
if [ -z "$settings" ]; then
echo "::error::could not resolve OTHER_CFLAGS for $label"
rc=1
return
fi
echo "$settings" | tr ' ' '\n' | grep -E '^-DHAVE_NETPLAY|^-DHAVE_NETWORKING' || true
for macro in HAVE_NETWORKING HAVE_NETPLAYDISCOVERY HAVE_NETPLAYDISCOVERY_NSNET; do
if ! echo "$settings" | grep -qE -- "-D$macro([[:space:]]|=|$)"; then
echo "::error::$label does not define $macro - netplay_nsnetservice.m is NOT being compiled"
rc=1
fi
done
}
check "macOS (scheme RetroArch)" \
-workspace pkg/apple/RetroArch.xcworkspace \
-scheme RetroArch -config Release
check "iOS (scheme RetroArch iOS Release)" \
-workspace pkg/apple/RetroArch.xcworkspace \
-destination generic/platform=iOS \
-scheme "RetroArch iOS Release" -config Release
exit $rc
# ------------------------------------------------------------------
# tvOS. The one Apple target with no build job of its own, so a break
# in code it shares with iOS - netplay_nsnetservice.m included - ships
# unnoticed there. Not gating: unrelated problems in the tvOS scheme
# should not hold up the tree.
# ------------------------------------------------------------------
tvos:
name: tvOS build (non-gating)
runs-on: macos-latest
timeout-minutes: 60
continue-on-error: true
steps:
- uses: actions/checkout@v6
- name: Compile RA (tvOS)
run: |
set -o pipefail
xcodebuild -workspace pkg/apple/RetroArch.xcworkspace \
-destination generic/platform=tvOS -config Release \
-scheme "RetroArch tvOS Release" \
-xcconfig pkg/apple/GitHubCI.xcconfig \
CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO \
CODE_SIGN_IDENTITY="" PROVISIONING_PROFILE_SPECIFIER="" \
-derivedDataPath build
-45
View File
@@ -1,45 +0,0 @@
name: CI Compile Matrix [Codec Combinations]
on:
push:
branches:
- master
pull_request:
branches:
- master
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
compile-matrix: # every codec combination real builds select, not just this one
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 5
run: |
# The gl2 arms compile against the desktop GL and EGL headers,
# and the Dingux and RS90 video drivers against SDL 1.2's.
pkgs="build-essential libgl-dev libegl-dev libgles-dev libsdl1.2-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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Compile matrix
run: ./.github/workflows/scripts/compile-matrix.sh
@@ -1,171 +0,0 @@
name: CI cross-libc libretro-common/vfs samples
# libretro-common/samples runs on ubuntu-latest only, which means
# every VFS test in the tree is validated against exactly one C
# library. That is the wrong number for this code: file_stream.c and
# vfs_implementation.c sit directly on top of stdio and the file
# descriptor API, and the libraries disagree about both.
#
# glibc fread() reads straight into the caller's buffer once
# the request reaches the block size, whoever owns the
# buffer (libio/fileops.c, _IO_file_xsgetn).
# Apple libc the same bypass exists but is skipped when setvbuf()
# supplied the buffer - '__SMBF' is then clear - which is
# exactly what retro_vfs_file_open_impl() does
# (Libc/stdio/FreeBSD/fread.c, radar 5980080 / 6180417).
# UCRT not open source; behaviour is inferred and therefore
# worth measuring rather than assuming.
# msvcrt the older runtime MINGW64 links against, again
# different code from UCRT.
#
# The tests here assert behaviour, not performance, so a difference in
# any of the above shows up as a failure rather than a slowdown. The
# Windows entries matter most for the descriptor path, which opens
# with open()/_wopen() instead of fopen(mode "rb") and so depends on
# O_BINARY being in the flags; vfs_bulk_read_test's binary
# transparency case is the one that catches its absence.
on:
push:
branches:
- master
paths:
- 'libretro-common/streams/file_stream.c'
- 'libretro-common/vfs/**'
- 'libretro-common/include/vfs/**'
- 'libretro-common/include/streams/file_stream.h'
- 'libretro-common/samples/file/vfs/**'
- '.github/workflows/Cross-libc-vfs-samples.yml'
pull_request:
paths:
- 'libretro-common/streams/file_stream.c'
- 'libretro-common/vfs/**'
- 'libretro-common/include/vfs/**'
- 'libretro-common/include/streams/file_stream.h'
- 'libretro-common/samples/file/vfs/**'
- '.github/workflows/Cross-libc-vfs-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:
# glibc and Apple libc. Both take the descriptor path, since
# VFS_HAVE_FILE_MAPPING covers anything with mmap.
unix:
name: ${{ matrix.name }}
runs-on: ${{ matrix.runner }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- name: glibc (ubuntu-latest)
runner: ubuntu-latest
# LeakSanitizer exists here, so run it at full strictness.
asan_opts: detect_leaks=1
- name: Apple libc (macos-latest)
runner: macos-latest
# LeakSanitizer is not implemented on Darwin, and asking
# for it is fatal rather than ignored: the runtime prints
# "detect_leaks is not supported on this platform" and
# aborts. Leak coverage for these sources comes from the
# Linux leg above; this one is here for Apple's libc
# behaviour, which is what differs.
asan_opts: detect_leaks=0
steps:
- uses: actions/checkout@v5
- name: Build and run
shell: bash
working-directory: libretro-common/samples/file/vfs
run: |
set -euo pipefail
run_cfg() {
echo "==> $*"
make clean >/dev/null
make "$@" SANITIZER=address,undefined
ASAN_OPTIONS=${{ matrix.asan_opts }} ./vfs_bulk_read_test
./vfs_seek_contract_test
./vfs_mapped_ptr_test
./vfs_v5_metadata_test
}
# Mapping on (what the platform actually ships), mapping off
# with the descriptor path forced (what the consoles have),
# and neither (a target on no list, which must keep its
# buffered behaviour).
run_cfg MMAP=1
run_cfg MMAP=0 DESCRIPTOR_IO=1
run_cfg MMAP=0
- name: Thread sanitizer
# Not on macOS: TSan there reports on system libraries the
# runner image ships, which is noise this job cannot fix.
if: matrix.runner == 'ubuntu-latest'
shell: bash
working-directory: libretro-common/samples/file/vfs
run: |
set -euo pipefail
make clean >/dev/null
make SANITIZER=thread
./vfs_bulk_read_test
# UCRT and msvcrt, through MSYS2. Same C runtimes an MSVC-built
# RetroArch links against, so the runtime behaviour these tests
# check is the behaviour that ships; the MSVC job covers the
# compiler.
windows:
name: ${{ matrix.sys }} (windows-latest)
runs-on: windows-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
sys: [UCRT64, MINGW64]
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v5
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
update: true
install: >-
base-devel
pacboy: >-
toolchain:p
- name: Build and run
working-directory: libretro-common/samples/file/vfs
run: |
set -euo pipefail
# No sanitizers here: the MSYS2 toolchains do not ship a
# usable ASan runtime for this target, and the point of this
# job is which C runtime the calls land on, not memory
# safety - the Linux job covers that with the same sources.
#
# MMAP=0 is required, not cosmetic: -DHAVE_MMAP pulls in
# <sys/mman.h>, which does not exist here. The Win32
# file-mapping backend is selected by _WIN32 inside vfs.h
# rather than by that flag, so VFS_HAVE_FILE_MAPPING - and
# with it descriptor I/O and the mapped-pointer path - is on
# regardless.
make clean MMAP=0
make MMAP=0
./vfs_bulk_read_test.exe
./vfs_seek_contract_test.exe
# Win32 branches of the v5 metadata ops: attributes,
# SetFileTime, CopyFileW, find-data dirent_stat.
./vfs_v5_metadata_test.exe
# Exercises the Win32 CreateFileMapping/MapViewOfFile
# backend, which no other job in the tree reaches.
./vfs_mapped_ptr_test.exe
@@ -1,46 +0,0 @@
name: CI Context presentable() contract
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:
ctx-presentable-check:
name: gfx_ctx_driver_t presentable() consistency
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Checker self-test
shell: bash
run: |
set -eu
# 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.
python3 tools/ctx_presentable_check.py --selftest
- name: Tree check
shell: bash
run: |
set -eu
# Each context driver is compiled by one platform's CI, so a
# 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.
python3 tools/ctx_presentable_check.py
-44
View File
@@ -1,44 +0,0 @@
name: CI DOS/DJGPP
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-djgpp-build-container:latest
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile RA
run: |
make -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: RA-DOS-dummy-${{ steps.slug.outputs.sha8 }}
path: |
retrodos.exe
-34
View File
@@ -1,34 +0,0 @@
name: CI Emscripten
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-emscripten:latest
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Compile RA
run: |
emmake make -f Makefile.emscripten -j$(getconf _NPROCESSORS_ONLN) clean
emmake make -f Makefile.emscripten -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1
-34
View File
@@ -1,34 +0,0 @@
name: CI GameCube
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-devkitpro:latest
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Compile RA
run: |
make -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1 info all
-48
View File
@@ -1,48 +0,0 @@
name: CI Linux Headless [No Menu] (i686)
on:
push:
branches:
- master
pull_request:
branches:
- master
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-nomenu: # Smoketest build with no menu support compiled in
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: ./configure --disable-menu
- name: Build
run: make
-385
View File
@@ -1,385 +0,0 @@
name: CI Linux ASan + UBSan [No Menu]
# Builds full RetroArch with -fsanitize=address,undefined and runs
# headless smoke invocations. Three coverage tiers, in increasing
# order of how much of the binary they actually instrument:
#
# 1. --help and --features. Exit(0) directly after printing.
# Coverage scope: libc init, main(), frontend driver bootstrap,
# argv duplication, the getopt walk, and the print functions.
# Strict ASan + UBSan -- baseline confirmed clean (run #1).
#
# 2. Headless imageviewer core under Xvfb + sdl2 video driver +
# null audio driver, --max-frames=300 for a clean shutdown
# through the normal runloop teardown. Exercises core loading
# via dlopen, the imageviewer's stb_image-driven loader, the
# SDL2 + X11 + MIT-SHM rendering pipeline, the runloop, and
# cleanup-on-shutdown. Soft-fail (continue-on-error) on this
# first iteration: lots can go wrong (libGL leaks, driver
# init noise) that aren't RetroArch bugs but would fail the
# run if treated strictly. Sanitizer findings are still
# surfaced in step output for triage.
#
# The per-sample tests under .github/workflows/Linux-samples-gfx.yml,
# Linux-samples-tasks.yml, Linux-samples-audio.yml,
# Linux-samples-network.yml, Linux-samples-settings.yml, and
# Linux-libretro-{db,common}-samples.yml regression-test specific
# predicates that previously had bugs. This
# job is complementary -- it covers everything those harnesses can't
# reach because the code only runs from main(), and catches future
# heap-corruption / UB regressions across the whole code base for
# free as a side effect of any change that can be exercised by a
# headless run.
#
# Build configuration matches Linux-Headless.yml (--disable-menu) with
# additional --disable-discord --disable-cheevos --disable-networking
# to shrink the third-party surface on this first iteration. Each can
# be re-enabled once the baseline is green.
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
asan-ubsan:
name: Build with ASan+UBSan and run headless smoke
runs-on: ubuntu-latest
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: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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
# from a vendored third-party subsystem. The disabled
# subsystems will be re-enabled in follow-up patches as the
# baseline stays green. --enable-sdl2 is explicit because
# the imageviewer smoke step below selects sdl2 as the video
# driver; if its build deps were ever missing, a silent fall-
# back to a different driver would skew the smoke's coverage
# without warning.
run: |
./configure \
--disable-menu \
--disable-discord \
--disable-cheevos \
--disable-networking \
--enable-sdl2
- name: Build with -fsanitize=address,undefined
# The top-level Makefile (line 153) propagates SANITIZER into
# CFLAGS / CXXFLAGS / LDFLAGS for every translation unit and
# the final link. ASan defaults to abort-on-heap-corruption;
# UBSan recovery is controlled at runtime via UBSAN_OPTIONS
# (see the smoke-run steps below).
run: |
make -j$(getconf _NPROCESSORS_ONLN) \
SANITIZER=address,undefined
test -x retroarch
file retroarch
- name: Smoke run --help (ASan + UBSan strict)
# `--help` exits cleanly via exit(0) after printing the usage
# banner. Coverage scope: libc init, main(), frontend
# driver bootstrap, argv duplication, the getopt walk over
# the full option table, and retroarch_print_help() itself.
# Doesn't reach into core loading / video init / cleanup-on-
# shutdown; the imageviewer smoke step below covers those.
# ASan and UBSan both run in halt-on-error mode: the first
# run of this workflow (Apr 28 2026, run #1) reported zero
# distinct UBSan diagnostics across both --help and
# --features, so the baseline for these two surfaces is
# clean and we enforce it. If a future change introduces
# signed-overflow / alignment / shift-too-large UB along
# the option-parsing or print paths, this step will fail
# and the diagnostic line will be in the captured stderr.
env:
ASAN_OPTIONS: abort_on_error=1:detect_leaks=0:print_stacktrace=1:strict_string_checks=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
# Avoid noise from libGL / Mesa / Wayland symbol-resolution
# leaks at process shutdown; those are not RetroArch bugs.
LSAN_OPTIONS: exitcode=0
run: |
set -eu
timeout 30 ./retroarch --help > /tmp/help.out 2> /tmp/help.err || rc=$?
echo "exit=${rc:-0}"
echo "=== stdout (head) ==="
head -40 /tmp/help.out
echo "=== stderr ==="
cat /tmp/help.err
# ASan abort_on_error sends the process to exit code 1 + a
# SUMMARY: line on stderr. Treat any "AddressSanitizer:"
# or UBSan "runtime error:" marker as fatal regardless of
# exit code -- belt-and-suspenders to the runtime options
# in case a future sanitizer release changes its default
# exit semantics.
if grep -q "AddressSanitizer:" /tmp/help.err; then
echo "[FAIL] AddressSanitizer reported a finding"
exit 1
fi
if grep -q "runtime error:" /tmp/help.err; then
echo "[FAIL] UBSan reported a finding"
exit 1
fi
echo "[pass] retroarch --help under ASan+UBSan"
- name: Smoke run --features (ASan + UBSan strict)
# `--features` exits cleanly via exit(0) after printing the
# compile-time feature list. Coverage scope is the same as
# --help (libc init / main / frontend bootstrap / arg parse)
# plus retroarch_print_features(), which walks the static
# video / audio / input / camera / location / record / cheats
# / network / database / overlay / hid feature tables. Each
# such walk reads pointers into a static-string table -- low
# corruption surface but a useful sanity check that the link-
# time feature flags resolve consistently. Doesn't reach
# core loading or cleanup-on-shutdown. Like the --help step
# this enforces UBSan strict because the baseline is clean.
env:
ASAN_OPTIONS: abort_on_error=1:detect_leaks=0:print_stacktrace=1:strict_string_checks=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
LSAN_OPTIONS: exitcode=0
run: |
set -eu
timeout 30 ./retroarch --features > /tmp/features.out 2> /tmp/features.err || rc=$?
echo "exit=${rc:-0}"
echo "=== stdout (head) ==="
head -40 /tmp/features.out
echo "=== stderr ==="
cat /tmp/features.err
if grep -q "AddressSanitizer:" /tmp/features.err; then
echo "[FAIL] AddressSanitizer reported a finding"
exit 1
fi
if grep -q "runtime error:" /tmp/features.err; then
echo "[FAIL] UBSan reported a finding"
exit 1
fi
echo "[pass] retroarch --features under ASan+UBSan"
- name: Build imageviewer core under ASan + UBSan
# The standalone Makefile under cores/libretro-imageviewer/
# honours the same SANITIZER= knob as the top-level Makefile
# (added in the v9 Makefile cleanup, efae310). Building the
# core with sanitizers enabled means the stb_image-driven
# decode path is fully instrumented when RetroArch dlopens
# it -- ASan would otherwise only catch heap corruption via
# the global allocator interceptor and would miss stack-
# buffer-overflow / use-after-return inside stb_image
# itself. Same SANITIZER= value as the main build.
run: |
set -eu
cd cores/libretro-imageviewer
make clean
make SANITIZER=address,undefined
test -x image_core.so
file image_core.so
- name: Generate test PNG for imageviewer
# Tiny 8x8 solid-red PNG, 75 bytes. Hand-rolled via Python
# struct + zlib to avoid an apt dependency on imagemagick or
# similar. Python ships on every ubuntu-latest by default.
# Saved under /tmp because the workspace lives on a path
# GitHub Actions cleans up post-run anyway.
run: |
set -eu
python3 - <<'PY'
import struct, zlib
def chunk(name, data):
crc = zlib.crc32(name + data)
return struct.pack('>I', len(data)) + name + data + \
struct.pack('>I', crc)
sig = b'\x89PNG\r\n\x1a\n'
ihdr = chunk(b'IHDR',
struct.pack('>IIBBBBB', 8, 8, 8, 2, 0, 0, 0))
raw = b''
for _ in range(8):
raw += b'\x00' + b'\xff\x00\x00' * 8
idat = chunk(b'IDAT', zlib.compress(raw))
iend = chunk(b'IEND', b'')
with open('/tmp/test.png', 'wb') as f:
f.write(sig + ihdr + idat + iend)
PY
file /tmp/test.png
- name: Smoke run imageviewer headless under Xvfb (soft-fail)
# Loads cores/libretro-imageviewer/image_core.so against a
# tiny PNG, runs --max-frames=300 (~5s nominal at 60fps,
# ~15-25s under sanitizer overhead), then exits via the
# normal runloop teardown path. Covers what the --help and
# --features smokes can't: dlopen of a libretro core,
# retro_load_game, the stb_image decode path, the SDL2 +
# X11 + MIT-SHM rendering pipeline, the runloop, and full
# cleanup-on-shutdown.
#
# Why sdl2 specifically: the v10 first attempt selected
# xvideo (smaller, more self-contained, real YUV color
# tables). Run #1 of that workflow tripped on Xvfb
# exposing the XVideo extension but providing zero
# adaptors:
#
# [XVideo] XvQueryAdaptors() found 0 adaptors.
# [Video] Cannot open video driver. Exiting...
#
# That's correct defensive code in the xvideo driver, not
# a bug -- but it means xvideo can't be exercised on Xvfb
# without real video hardware, which the runner doesn't
# have. SDL2 over X11 / MIT-SHM works on Xvfb out of the
# box (verified via a standalone SDL_CreateRenderer probe
# before this patch landed). Coverage tradeoff: we lose
# xvideo's YUV color-conversion path but keep all the
# high-leverage surface (dlopen, core lifecycle, stb_image,
# runloop, video driver init, full cleanup).
#
# Soft-fail (continue-on-error: true) on this iteration.
# Reasoning: lots can go wrong here that aren't RetroArch
# bugs -- libGL / Mesa software-rasterizer leaks at
# shutdown, X11 driver init noise -- and forcing strict
# cleanliness before measuring the baseline would block
# merges on noise. Sanitizer findings ARE still surfaced
# in the step output for triage; they just don't fail
# the job. Once the baseline is characterised, this step
# can be flipped to strict the same way the --help step
# was in v8.
#
# Audio driver is "null" (no PulseAudio / ALSA dependency
# on the runner). Verbose output is on so the run captures
# the full log for triage.
continue-on-error: true
env:
# detect_leaks=0 because libGL / Mesa symbol-resolution
# plus X11 connection caches produce non-trivial leaks at
# process shutdown that aren't RetroArch bugs. Can be
# flipped on later with a suppression file. Heap
# corruption / UAF / double-free still abort under
# abort_on_error=1.
ASAN_OPTIONS: abort_on_error=1:detect_leaks=0:print_stacktrace=1:strict_string_checks=1
# halt_on_error=0 so a single signed-overflow somewhere
# in the runloop doesn't truncate the stderr log before
# we see the full picture. The grep below still
# surfaces every "runtime error:" line for triage.
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=0
LSAN_OPTIONS: exitcode=0
run: |
set -eu
# Start Xvfb on display :99. -screen geometry is small
# because the imageviewer doesn't care about resolution
# and we're trying to minimise X server memory. SDL2's
# X11 backend uses MIT-SHM (which Xvfb provides by
# default) for image transfer.
Xvfb :99 -screen 0 320x240x24 -nolisten tcp &
XVFB_PID=$!
# Ensure cleanup on any exit (including soft-fail ones).
trap "kill $XVFB_PID 2>/dev/null || true" EXIT
# Give Xvfb time to come up; xdpyinfo confirms MIT-SHM is
# available before we waste cycles trying to use it.
# Extension names in xdpyinfo output are indented with
# leading whitespace, hence ^[[:space:]]+.
for i in 1 2 3 4 5; do
if DISPLAY=:99 xdpyinfo -queryExtensions 2>/dev/null \
| grep -qE "^[[:space:]]+MIT-SHM\b"; then
break
fi
sleep 1
done
DISPLAY=:99 xdpyinfo -queryExtensions \
| grep -E "^[[:space:]]+MIT-SHM\b" || true
# Minimal config: sdl2 video, null audio. Everything
# else takes built-in defaults.
mkdir -p /tmp/asan-cfg
cat > /tmp/asan-cfg/retroarch.cfg <<EOF
video_driver = "sdl2"
audio_driver = "null"
video_threaded = "false"
video_fullscreen = "false"
video_windowed_fullscreen = "false"
EOF
# Run. --max-frames triggers a clean shutdown via the
# normal runloop teardown after N frames, which is what
# we want for cleanup-path coverage. Wall-clock timeout
# is a safety net at 60s; --max-frames at 300 should
# finish in well under that even with sanitizer overhead.
set +e
DISPLAY=:99 timeout 60 ./retroarch \
-c /tmp/asan-cfg/retroarch.cfg \
-L cores/libretro-imageviewer/image_core.so \
/tmp/test.png \
--max-frames=300 \
--verbose \
> /tmp/imageviewer.out 2> /tmp/imageviewer.err
rc=$?
set -e
echo "exit=${rc}"
echo "=== stdout (last 80) ==="
tail -80 /tmp/imageviewer.out || true
echo "=== stderr (last 200) ==="
tail -200 /tmp/imageviewer.err || true
# Surface sanitizer findings explicitly (informational --
# we do NOT exit 1 because this step is soft-fail). Once
# the baseline is characterised, this section will gate
# on findings the same way the --help / --features steps
# do.
if grep -q "AddressSanitizer:" /tmp/imageviewer.err; then
echo ""
echo "[INFO] AddressSanitizer reported finding(s):"
grep -A 2 "AddressSanitizer:" /tmp/imageviewer.err \
| head -40
fi
ub_count=$(grep -c "runtime error:" /tmp/imageviewer.err \
2>/dev/null || true)
if [ "${ub_count:-0}" != "0" ]; then
echo ""
echo "[INFO] UBSan reported ${ub_count} runtime error(s):"
grep -h "runtime error:" /tmp/imageviewer.err \
| sort -u | head -20
fi
echo "[done] imageviewer headless smoke (soft-fail)"
@@ -1,65 +0,0 @@
name: CI Linux native audio transport
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:
native-transport:
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
sanitizer: ['', 'address,undefined']
steps:
- uses: actions/checkout@v5
- name: Build the shipping frontend and real audio wrapper fixture
working-directory: samples/audio/pipeline_wakeups
run: make clean all SANITIZER='${{ matrix.sanitizer }}'
- name: Stereo tempo extremes and live controls
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-tempo check-live SANITIZER='${{ matrix.sanitizer }}'
- name: Native and mixed formats through 5.1 and 7.1
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-wide SANITIZER='${{ matrix.sanitizer }}'
- name: Live source layouts on a fixed device
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-layout SANITIZER='${{ matrix.sanitizer }}'
- name: Speed-linked low-pass control requests
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-speed-lpf SANITIZER='${{ matrix.sanitizer }}'
- name: Runloop speed-state requests
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-runloop SANITIZER='${{ matrix.sanitizer }}'
- name: Automatic producer controls and fallback
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-auto SANITIZER='${{ matrix.sanitizer }}'
@@ -1,69 +0,0 @@
name: CI Linux autoconfig regression
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
autoconf-tests:
name: Build and run the autoconfig regression suite
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 5
run: |
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
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: |
set -eu
# The suite drives the test input/joypad drivers with the
# null video/audio/menu drivers - no X11/Vulkan/menu needed.
# HAVE_TEST_DRIVERS is on by default; assert it survived
# configure so a silent drop turns into a clear failure
# rather than a skipped test.
./configure --disable-menu --disable-ffmpeg --disable-x11 --disable-wayland
grep -q '^HAVE_TEST_DRIVERS = 1' config.mk
- name: Build
run: make -j"$(nproc)"
- name: Run autoconfig regression suite
shell: bash
run: |
set -eu
test -x ./retroarch
./tests-other/test_autoconf.sh ./retroarch
-118
View File
@@ -1,118 +0,0 @@
name: CI driver vtables
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
driver-vtables:
name: Every driver against its interface
runs-on: ubuntu-latest
timeout-minutes: 15
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 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
run: |
set -eu
# A driver fills in a vtable of function pointers, and almost
# every one of them does it positionally and names nothing.
# So an entry added to the middle of one of those structures
# silently moves every entry after it in every driver that
# did not name its fields, and what the compiler then says is
# that a layout function is being installed as an underrun
# counter - which is an error only if you ask for it to be.
#
# That happened: frames_consumed_fallback went in between
# frames_consumed and underruns, three Windows drivers took
# the shift, and the break reached master because the check
# run before the commit was one file rather than all of them.
#
# This is that check. It compiles every driver it can on
# Linux - the rest need SDKs that are not here - and treats a
# mismatched function pointer as the error it is.
#
# The names are matched with digits in them as well: a driver
# called sdl3 or v4l2 or ps2 is exactly as positional as one
# that spells itself in letters, and six of them were being
# walked past. The display drivers fill in a vtable of the
# same shape, so they are here too.
#
# A static function nobody calls is in the same family and is
# caught here too: it is what a call site that was meant to
# be there and is not looks like from the compiler's side.
# That happened as well - the pump's scheduler class was
# taken but never given back, and the only sign was the
# helper that returns it going unused.
fail=0
defs="-DRARCH_INTERNAL -DHAVE_THREADS -DHAVE_MENU -DHAVE_CONFIGFILE"
defs="$defs -DHAVE_AUDIOMIXER -DHAVE_REWIND -DHAVE_RWAV"
have="-DHAVE_ALSA -DHAVE_PULSE -DHAVE_JACK -DHAVE_OSS -DHAVE_OPENAL"
have="$have -DHAVE_PIPEWIRE -DHAVE_TINYALSA -DHAVE_SDL2"
inc="-I. -Ilibretro-common/include -Ideps -Ideps/rcheevos/include"
inc="$inc $(pkg-config --cflags libpipewire-0.3 2>/dev/null || true)"
# Every file that fills one of these structures in, found by
# looking rather than by listing a directory: the Android
# build broke on audio/audio_thread_wrapper.c, which fills in
# an audio_driver_t and does not live under audio/drivers,
# and so was not in the list this job first carried.
files=$(grep -rl -E \
'audio_driver_t [a-z_0-9]+ *=|camera_driver_t [a-z_0-9]+ *=|record_driver_t [a-z_0-9]+ *=|microphone_driver_t [a-z_0-9]+ *=|gfx_display_ctx_driver_t [a-z_0-9]+ *=' \
--include='*.c' . | grep -v '^\./samples/' | sort)
echo "$files" | sed 's/^/ /'
echo
for f in $files; do
[ -f "$f" ] || continue
out=$(gcc -fsyntax-only -std=gnu99 -Wall \
-Werror=incompatible-pointer-types \
-Werror=unused-function \
$defs $have $inc "$f" 2>&1 || true)
# A driver whose platform SDK is not here does not compile
# at all, and that is not what this job is about: it is
# skipped, and only a pointer mismatch fails.
if printf '%s' "$out" | grep -qE "incompatible pointer type|defined but not used"; then
echo "=== $f"
printf '%s\n' "$out" | grep -E -A2 "incompatible pointer type|defined but not used"
fail=1
elif printf '%s' "$out" | grep -q ": error:"; then
echo "[skip] $f (needs an SDK that is not here)"
else
echo "[ok] $f"
fi
done
if [ "$fail" -ne 0 ]; then
echo
echo "A driver does not match the interface it fills in, or has a"
echo "static function nothing calls. An optional vtable entry belongs"
echo "at the end of the structure, where it cannot move the entries a"
echo "positional initialiser relies on; an uncalled helper usually"
echo "means the call site that was meant to use it is missing."
exit 1
fi
File diff suppressed because it is too large. Load diff
@@ -1,250 +0,0 @@
name: CI Linux libretro-common tests
# libretro-common/Makefile.test builds and runs the libcheck unit
# suites under -fsanitize=address -fsanitize=undefined. Nothing ran
# it, which is how three of its suites came to reference sources that
# had moved and one referenced a library it never linked: a suite that
# cannot be built reads exactly like a suite that passes.
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
libretro-common-tests:
name: Build and run libretro-common/Makefile.test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 8
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"
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
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: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run the unit test suites
shell: bash
working-directory: libretro-common
env:
# Keep wine quiet and out of $HOME; the first invocation
# creates the prefix.
WINEDEBUG: "-all"
WINEPREFIX: "/tmp/wineprefix"
run: |
set -eu
# 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
# win32-configs, so a bare make here builds the Windows A/W
# 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.
make -f Makefile.test unit-tests \
LIBCHECK_CFLAGS="$(pkg-config --cflags check)" \
CFLAGS="$(pkg-config --cflags check)"
echo "[pass] libretro-common unit test suites"
- name: Check VFS backend symbol parity
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# vfs_implementation_uwp.cpp replaces vfs_implementation.c on
# UWP rather than extending it, so a function added to the C
# backend and called from the shared file_stream.c compiles
# everywhere and fails to link on UWP alone - at the end of a
# long MSVC build, on a runner most contributors do not have.
# 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.
python3 tools/vfs_backend_parity.py
- name: Check companion backend feature parity
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# The Qt, Win32 and Cocoa desktop companions share one C core
# but each has its own presentation; a backend can quietly omit
# 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.
python3 tools/companion_parity.py
- name: Companion thumbnail engine regression test (plain, TSan, ASan)
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# The shared thumbnail engine every desktop companion draws
# through: real decoder, decode threads, cache, priority,
# cancel, shutdown, and one hover on a video (the still and
# the animation share one session). Under both sanitizers,
# since it is the one piece of threaded code in the
# companions.
tools/companion_thumbs_test.sh
tools/companion_thumbs_test.sh tsan
tools/companion_thumbs_test.sh asan
- name: Companion core regression test (plain, ASan)
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# The toolkit-free model every desktop companion drives:
# playlist listing and All Playlists, the thumbnail path rule,
# the file browser, the run / needs-core paths, launch
# options - against real .lpl fixtures, with RetroArch's
# state replaced by stubs.
tools/companion_core_test.sh
tools/companion_core_test.sh asan
tools/companion_core_test.sh tsan
- name: C89 / Win32 syntax gate on the companion sources
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# MSVC 2005 builds these as C89 through griffin. The gate's
# second pass needs a 32-bit mingw for the Windows-only unit
# (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 \
gfx/gfx_anim_preview.c
- name: Cocoa companion regression harness (GNUstep AppKit, headless)
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# The real ui/drivers/ui_cocoa_companion.m, compiled and linked
# against GNUstep's Foundation + AppKit with the real companion
# 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
# app on macOS, where Apple's is one).
tools/companion_cocoa_test.sh asan
- name: Win32 companion regression harness (mingw + Wine, headless)
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -eu
# The real ui/drivers/ui_win32_companion.c, built with mingw and
# 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: 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
@@ -1,195 +0,0 @@
name: CI Linux libretro-db samples
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
samples:
name: Build and run libretro-db/samples
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run samples
shell: bash
working-directory: libretro-db/samples
env:
# Build samples under AddressSanitizer + UndefinedBehaviorSanitizer.
# Both libretro-db sample tests support this via the SANITIZER=
# convention also used in samples/tasks/http/Makefile. ASan
# catches any reintroduced leak (intfstream_t in libretrodb_open
# / cursor_close, etc.) and any out-of-bounds memory access, so
# this is the regression-protective build for these tests.
MAKE_ARGS: "SANITIZER=address,undefined"
run: |
set -u
set -o pipefail
# Samples whose binary, when invoked with no arguments, runs a
# self-contained test and exits 0 on success / non-zero on
# failure. These are built AND executed.
declare -a RUN_TARGETS=(
rmsgpack_overflow_test
libretrodb_leak_test
)
# Per-binary run command (overrides ./<binary> if present).
declare -A RUN_ENV=()
# Samples that are build-only.
declare -a BUILD_ONLY_DIRS=(
)
# Samples that are currently broken at build time on a stock
# Ubuntu host and are therefore neither built nor run.
declare -a SKIP_DIRS=(
)
is_in() {
local needle=$1; shift
local h
for h in "$@"; do [[ "$h" == "$needle" ]] && return 0; done
return 1
}
fails=0
builds=0
runs=0
# Collect all Makefile directories (one or two levels deep).
mapfile -t MKDIRS < <(find . -name Makefile -printf '%h\n' | sort)
printf '\n==> %d sample directories found\n' "${#MKDIRS[@]}"
for d in "${MKDIRS[@]}"; do printf ' %s\n' "${d#./}"; done
printf '\n'
for d in "${MKDIRS[@]}"; do
rel=${d#./}
printf '========================================\n'
printf '[%s] %s\n' "$(is_in "$rel" "${SKIP_DIRS[@]}" && echo skip || echo build)" "$rel"
printf '========================================\n'
if is_in "$rel" "${SKIP_DIRS[@]}"; then
printf '[skip] %s is on the skip list\n\n' "$rel"
continue
fi
# Build
if ! ( cd "$d" && make clean all $MAKE_ARGS ); then
printf '\n::error title=Build failed::%s failed to build\n' "$rel"
fails=$((fails+1))
continue
fi
builds=$((builds+1))
# Skip run for build-only dirs
if is_in "$rel" "${BUILD_ONLY_DIRS[@]}"; then
printf '[skip-run] %s (build-only list)\n\n' "$rel"
continue
fi
# Extract targets from Makefile. Handles:
# TARGET := foo
# TARGETS = a b c
# TARGET_TEST := foo_test
# TARGET_TEST2 := foo_test2
mapfile -t targets < <(
grep -hE '^(TARGET|TARGETS|TARGET_TEST[0-9]*)[[:space:]]*[:?]?=' "$d/Makefile" \
| sed -E 's/^[^=]*=[[:space:]]*//' \
| tr -s ' \t' '\n' \
| grep -v '^$' \
| sort -u
)
for t in "${targets[@]}"; do
if ! is_in "$t" "${RUN_TARGETS[@]}"; then
printf '[skip-run] %s/%s (not in run allowlist)\n' "$rel" "$t"
continue
fi
bin="$d/$t"
if [[ ! -x "$bin" ]]; then
printf '::error title=Missing binary::%s was in the run allowlist but %s does not exist after build\n' "$t" "$bin"
fails=$((fails+1))
continue
fi
extra_env=${RUN_ENV[$t]:-}
printf '\n[run] %s\n' "$bin"
if ( cd "$d" && env $extra_env timeout 60 "./$t" ); then
printf '[pass] %s\n\n' "$t"
runs=$((runs+1))
else
rc=$?
printf '\n::error title=Test failed::%s exited with status %d\n' "$t" "$rc"
fails=$((fails+1))
fi
done
done
printf '========================================\n'
printf 'Summary\n'
printf '========================================\n'
printf ' Built: %d\n' "$builds"
printf ' Ran: %d\n' "$runs"
printf ' Failed: %d\n' "$fails"
if [[ $fails -gt 0 ]]; then
exit 1
fi
-176
View File
@@ -1,176 +0,0 @@
name: CI Linux menu harness
# The menu playlist navigation harness links the SHIPPING RetroArch
# objects with only main() replaced, so unlike every other sample it
# needs a full build of the program before it can be built at all.
#
# That is why it lives in its own workflow rather than in
# Linux-samples-tasks: a full build does not fit inside that job's
# ten-minute budget, and putting it there cancelled the whole job -
# every other sample with it - rather than just failing its own step.
# Here it can take the time it needs without being able to take
# anything else down with it.
#
# It also needs a NON-Qt build: with Qt enabled main() lives in
# ui_qt.o and drags the entire Qt UI in with it.
on:
push:
paths:
- 'menu/**'
- 'playlist.c'
- 'playlist.h'
- 'tasks/task_content*'
- 'samples/menu/playlist_nav/**'
- '.github/workflows/Linux-menu-harness.yml'
pull_request:
paths:
- 'menu/**'
- 'playlist.c'
- 'playlist.h'
- 'tasks/task_content*'
- 'samples/menu/playlist_nav/**'
- '.github/workflows/Linux-menu-harness.yml'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
menu-harness:
name: Build and run the menu navigation harness
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build RetroArch headless
shell: bash
run: |
set -eu
# The harness drives the menu with the null drivers, so
# everything that draws or talks to the network is dead
# weight here - and building it is the entire cost of this
# workflow. Disabling it takes the build from roughly ten
# minutes to about three, and avoids depending on graphics
# packages the runner may or may not carry: configure found
# X11 and xcb but not libX11-xcb, and the link failed on
# -lX11-xcb.
#
# Qt in particular has to go: with it enabled main() lives
# in ui_qt.o, and the harness replaces main().
./configure --disable-qt --disable-x11 \
--disable-opengl --disable-opengl_core \
--disable-opengl1 --disable-vulkan \
--disable-cheevos --disable-networking \
--disable-ffmpeg
make -j$(nproc)
- name: Build and run content_closing_test
shell: bash
run: |
set -eu
# The guard that keeps the frame loop out of a core being
# torn down (core_run() refusing retro_run() while
# content_closing is set) cannot fire in shipped code yet:
# closing is still synchronous, so no frame runs during it.
# It goes live in the change that first lets frames run
# during a close, and if it is wrong the symptom is a call
# into an unloaded dylib - so it is driven here directly,
# against the real core_run() in a real frontend, rather
# than going live untested.
#
# Shares the non-Qt build made above; adds about a second.
samples/runloop/content_closing/build.sh
./samples/runloop/content_closing/content_closing_test
make -C samples/runloop/content_closing clean
- name: Build and run menu_playlist_nav_test
shell: bash
run: |
set -eu
# Four field reports came out of the seam between the
# playlist reader and the menu - a stale playlist's entries
# under a new heading, then a blank list the back button
# could not leave, then a list that filled only after the
# user pressed something, then #19427's placeholder flashing
# on every completed read - and no oracle that stopped at
# the reader could see any of them.
#
# The harness installs a VFS through the seam the frontend
# uses for SAF, returning short reads WITH a per-read delay.
# Short reads alone reproduce SAF's syscall count but not
# its latency, and on local storage the whole playlist still
# fits inside one budget slice - which is exactly why none
# of the three reports reproduced on a desktop.
samples/menu/playlist_nav/build.sh
./samples/menu/playlist_nav/menu_playlist_nav_test
make -C samples/menu/playlist_nav clean
- name: Hot function budget
shell: bash
run: |
set -eu
# Code size and stack frame of the functions that run every
# frame, against a checked-in reference: a change that doubles
# either passes every lane in the suite and shows up only as a
# slower frame on someone's machine. Uses the release objects
# this job already built.
.github/workflows/scripts/hot-function-budget.sh
- name: Build and run threaded_video_test
shell: bash
run: |
set -eu
# The threaded video wrapper against the real runloop, on the
# same non-Qt menu build: the runtime toggle, reinit under the
# wrapper, the command mailbox, presenter repeats, and the
# font init/free marshalling - the last of which is where a
# deferred font free unbound the video thread's GL context on
# X11 and left every frame after it black. This build has no
# allocator sanitizer, so it is also the one job where the
# frame-path heap lane runs: it counts heap calls over three
# hundred frames, threaded and not, and the frame path makes
# none.
samples/gfx/threaded_video/build.sh
./samples/gfx/threaded_video/threaded_video_test 3
make -C samples/gfx/threaded_video clean
-91
View File
@@ -1,91 +0,0 @@
name: CI Linux pace shadow [debug harness]
# The pace decision - which sources hold the loop each iteration - is
# one pure function, runloop_pace_decide() in runloop.h, that every
# path of runloop_iterate() defers to. It began life shadowing the
# paths' own scattered decisions with a debug assertion that the two
# agreed; this job was created to run that assertion in CI, and it
# never fired, which is what let the paths defer.
#
# What the job still does: builds with DEBUG=1 under ASan and UBSan,
# so every retro_assert in the wrapper, the ring and the runloop is
# live, and runs the threaded-video harness through it - threaded and
# unthreaded, menu open and closed, display pacing on, the runtime
# toggles - then the pacing sample, whose menu table pins the decision
# row by row. The release harness job cannot see an assertion; this
# one can.
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:
linux-pace-shadow:
name: Debug build, harness with assertions live
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
# Non-Qt, as the harness requires (with Qt, main() lives in
# ui_qt.o). Menu enabled: the menu lanes are half the point.
run: |
./configure \
--disable-qt \
--disable-discord \
--disable-cheevos \
--disable-networking \
--disable-ffmpeg
- name: Build with DEBUG=1 and -fsanitize=address,undefined
run: |
make -j$(getconf _NPROCESSORS_ONLN) SANITIZER=address,undefined DEBUG=1
- name: Run the threaded-video harness with assertions live
shell: bash
run: |
set -eu
# SAN=address is the harness's default and links exactly the
# build above; CYCLES=2 runs each toggling lane twice.
SAN=address CYCLES=2 make -C samples/gfx/threaded_video check
make -C samples/gfx/threaded_video clean
- name: Run the pacing sample (the menu table)
shell: bash
run: |
set -eu
make -C samples/runloop/pacing check
make -C samples/runloop/pacing clean
-75
View File
@@ -1,75 +0,0 @@
name: CI Linux Qt companion (persistence)
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
qt-companion-persist:
# Builds a Qt-enabled RetroArch with the null video/audio/input
# drivers and runs tools/companion_qt_persist_test.sh: the desktop
# companion's window geometry and dock layout must reach
# retroarch.cfg when RetroArch quits with the companion window still
# open, and a saved layout must restore and re-save identically.
#
# The shader stacks are disabled explicitly: with no OpenGL/Vulkan
# dev packages on the runner this is a Qt build with NO shader stack
# at all, and it links (the shader-preset editor and the companion
# core's shader accessors are compiled out). That is deliberate - it
# is the one configuration the other jobs never build.
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: |
./configure --enable-qt --disable-x11 --disable-wayland \
--disable-opengl --disable-opengles --disable-vulkan \
--disable-sdl2 --disable-sdl --disable-alsa --disable-pulse \
--disable-ffmpeg --disable-networking --disable-cheevos \
--disable-discord --disable-cdrom --disable-flac --disable-mpv \
--disable-libusb --disable-udev --disable-v4l2 --disable-freetype \
--disable-caca --disable-sixel --disable-microphone --disable-ssl \
--disable-bluetooth --disable-wifi --disable-oss --disable-jack \
--disable-roar --disable-al --disable-xvideo --disable-kms \
--disable-egl --disable-dispmanx --disable-videocore \
--disable-crtswitchres --disable-update_cores --disable-hid \
--disable-dbus --disable-glsl --disable-slang --disable-cg \
--disable-glslang --disable-spirv_cross
- name: Build
run: make -j$(getconf _NPROCESSORS_ONLN)
- name: Companion persistence regression
timeout-minutes: 10
run: tools/companion_qt_persist_test.sh
-893
View File
@@ -1,893 +0,0 @@
name: CI Linux samples/audio
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
samples-audio:
name: Build and run samples/audio
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run mixer_lock_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/mixer_lock
run: |
set -eu
# Includes audio/audio_driver.c and drives the mixer's public
# entry points with a real state lock in place. The lock is a
# plain mutex, so any path that reaches a locking entry point
# while already holding it parks the thread against itself;
# loading the first menu sound did exactly that
# (libretro/RetroArch#19485). Every case runs on a watchdog:
# a reintroduced recursive acquisition aborts with a stack
# instead of hanging the job. Also covers the lock being
# released on out-of-range slots and a NULL stream name
# surviving removal.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x mixer_lock_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 120 \
./mixer_lock_test
echo "[pass] mixer_lock_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./mixer_lock_test
echo "[pass] mixer_lock_test (TSan)"
- name: Build and run thread_handshake_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/thread_handshake
run: |
set -eu
# Links audio/audio_thread_wrapper.c against a scripted
# driver. The wrapped thread parks in one of two waits and
# the main thread's block() needs stopped_ack from either; a
# stop() landing between start()'s signal and the thread's
# re-check used to leave it in the one wait that never
# acknowledged. Two thousand start/stop round-trips hit that
# window on the previous wrapper on every run. The scripted
# device can also stop returning from a call: a stop must
# then still complete once the call does, and must be
# reported exactly once meanwhile - prompt handshakes are
# asserted not to be reported.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x thread_handshake_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 300 \
./thread_handshake_test
echo "[pass] thread_handshake_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 600 ./thread_handshake_test
echo "[pass] thread_handshake_test (TSan)"
- name: Build and run graph_clock_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/graph_clock
run: |
set -eu
# The two conversions the JACK and PipeWire clock fits add.
# Neither a JACK server nor a PipeWire daemon can be started
# here, so unlike alsa_clock this mirrors the arithmetic
# rather than driving the drivers - a weaker check, said
# plainly, and aimed at the parts where being wrong is
# silent.
#
# JACK's current_frames is 32 bits and wraps in about a day
# at 48 kHz, sooner if the server was up before RetroArch
# started, since the counter is the server's. The difference
# is taken in 32 bits where the wrap cancels; widening first
# turns one wrap into a four-billion-frame jump. A run is
# started two seconds short of the wrap so it goes round
# mid-measurement.
#
# PipeWire's ticks are in units of pw_time.rate, a fraction
# that is 1/samplerate. The same physical drift has to read
# the same ppm at 44.1k and 48k, which is what the fraction
# is there for.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x graph_clock_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./graph_clock_test
echo "[pass] graph_clock_test (ASan)"
- name: Build and run alsa_clock_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/alsa_clock
run: |
set -eu
# The ALSA device-clock estimate, driving the shipping
# audio/drivers/alsa.c on a real PCM opened on the null
# device. The four libasound calls the estimate is built from
# are scripted via --wrap, so a device can be made to run at a
# chosen offset and the driver's own answer read back out of
# what it logs - what is asserted is the line a user sees.
#
# Two clocks are covered. The audio timestamp, where a driver
# counts one, is the DMA or link clock compared straight
# against the system clock and needs neither a rate nor a
# delay. Where there is none - the null PCM reports none, and
# nor do plenty of real devices - the position is fitted
# against the timestamp it was taken with. That position is
# inferred from the write count less the delay, so one case
# puts an absurd but constant delay in: it shifts the line
# and leaves its slope alone, which is why this is a fit and
# not a difference of two samples.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x alsa_clock_test
ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./alsa_clock_test
echo "[pass] alsa_clock_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
timeout 60 ./alsa_clock_test
echo "[pass] alsa_clock_test (TSan)"
- name: Build and run alsa_wait_writable_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/alsa_wait_writable
run: |
set -eu
# Links the shipping audio/drivers/alsa.c and interposes the
# five libasound calls alsa_wait_writable() makes via
# -Wl,--wrap, so the devices no stock PCM can produce on
# demand are scripted: a running stream whose poll never
# signals, a prepared stream reporting no space, a start that
# lands in an underrun storm, and wakes that never deliver
# space. Each must return 0 within a bounded lap and wall-time
# budget rather than parking the audio thread; the previous
# wait was an unbounded snd_pcm_wait(-1). The conforming path
# runs end-to-end on the null PCM, and the harness skips
# cleanly if no ALSA configuration is available at all.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x alsa_wait_writable_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 120 \
./alsa_wait_writable_test
echo "[pass] alsa_wait_writable_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./alsa_wait_writable_test
echo "[pass] alsa_wait_writable_test (TSan)"
- name: Build and run alsa_lifecycle_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/alsa_lifecycle
run: |
set -eu
# Links the shipping audio/drivers/alsa.c against the null PCM
# and scripts the libasound calls that decide stop/start and
# the blocking write - can_pause, pause, drop, prepare, writei,
# wait, recover - via -Wl,--wrap. alive() must follow stop()
# and start() on a device that can pause, one that cannot, and
# one that says it can and refuses; the blocking write must
# write first, wait only on EAGAIN, and never without a bound.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x alsa_lifecycle_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 120 \
./alsa_lifecycle_test
echo "[pass] alsa_lifecycle_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./alsa_lifecycle_test
echo "[pass] alsa_lifecycle_test (TSan)"
- name: Build and run pipeline_stall_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/pipeline_stall
run: |
set -eu
# Includes audio/audio_driver.c and runs the threaded pipeline's
# shipping producer and consumer against a scripted driver whose
# write_raw() path reaches the device without the resampler or
# the arenas. The device is then made to stop taking audio. The
# consumer must take nothing from the ring it cannot deliver and
# report no progress it did not make; the producer must record
# the stall after one bounded wait and drop at once thereafter;
# and both must recover when the device returns. The previous
# consumer took the chunk first, threw it away on finding no
# room, and cleared the stall - the frontend paced at one frame
# per failed pass for as long as the device was stuck.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x pipeline_stall_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 180 \
./pipeline_stall_test
echo "[pass] pipeline_stall_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 400 ./pipeline_stall_test
echo "[pass] pipeline_stall_test (TSan)"
- name: Build and run upmix_test (plain, ASan + UBSan)
shell: bash
working-directory: samples/audio/upmix
run: |
set -eu
# The stereo-to-wider stage at the last step before a device
# opened with a wider speaker layout. A layout is a mask of
# positions in ascending bit order, never a count: 5.1 with
# the rear pair at the back and 5.1 with it at the sides are
# two layouts whose slots differ. The fronts carry the stereo
# unchanged, the rear pair -3 dB in its own slots, the centre
# the -6 dB sum, the LFE the bass through a 120 Hz low-pass and
# none of the treble; stereo is a copy; a mask the stage
# cannot fill is refused.
make clean && make -j$(nproc) all
./upmix_test
echo "[pass] upmix_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
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)
shell: bash
working-directory: samples/audio/discrete_multichannel
run: |
set -eu
# A core's 5.1 through the multi-channel batch entry to a 5.1
# device without the fold and the upmix in between: each
# device channel carries its core channel's tone and none of
# the others', in all four format pairings, through the
# resampler off unity; over the threaded ring; recorded; and
# to a stereo device, the fold at the BS.775 gains with the
# LFE dropped. The last case runs the shipping WASAPI driver
# over the fake device from wasapi_exclusive_pacing, so a
# 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.
make clean && make -j$(nproc) all
./discrete_multichannel_test
echo "[pass] discrete_multichannel_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
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
working-directory: samples/audio/embedded_alsa
run: |
set -eu
# The "tinyalsa" driver in audio/drivers/alsa.c talks the
# kernel PCM ioctls directly. abi_check compares its copy of
# that ABI - extracted from the driver itself, so it cannot
# go stale - against <sound/asound.h>: every struct size and
# offset, constant and ioctl number. The test then runs the
# driver against a mock device that refines parameters the
# way the kernel does.
make clean && make -j$(nproc) check
echo "[pass] embedded_alsa_test"
make clean && make -j$(nproc) check SANITIZER=address,undefined
echo "[pass] embedded_alsa_test (ASan)"
- name: Build and run ealsa_test (the embedded ALSA driver against a mock PCM device)
shell: bash
working-directory: samples/audio/ealsa
run: |
set -eu
# The embedded driver in audio/drivers/alsa.c talks to the
# kernel's PCM ABI through one seam - open, ioctl, close,
# poll - so a scripted device that answers the way a card
# does runs it with no card present, and can refuse a rate, a
# format, a channel count or a period grid, which is where a
# negotiation goes wrong. Built with HAVE_TINYALSA alone, so
# the build never sees an alsa-lib header either. It also
# carries what tinyalsa_write_test used to check of the
# driver this one replaced: a full device refusing in both
# modes, a device that never signals, a poll cut short by a
# signal, and the first write reporting what it took.
make clean && make -j$(nproc) all
./ealsa_test
echo "[pass] ealsa_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./ealsa_test
echo "[pass] ealsa_test (ASan)"
- name: Build and run bitstream_test (plain, ASan + UBSan)
shell: bash
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:
# bursts leave whole and never partial, the queue paces the
# source rather than the source running ahead, a gap
# produces the pause burst the standard has for it rather
# than silence (which makes a receiver drop its lock), and
# the PCM frames reported are the device time the bytes
# occupy.
make clean && make -j$(nproc) all
./bitstream_test
echo "[pass] bitstream_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./bitstream_test
echo "[pass] bitstream_test (ASan)"
- name: Build and run opensl_test (the Android driver against a mock OpenSL player)
shell: bash
working-directory: samples/audio/opensl
run: |
set -eu
# audio/drivers/opensl.c is Android-only and has no build
# here, so it is built against stand-in <SLES/*.h> over a
# scripted player whose queue a thread drains: the block
# arithmetic at the latencies of issue #6405 and below, the
# queue accounting the hang there came from, float and
# 16-bit, a full queue, and a device that stops consuming.
make clean && make -j$(nproc) all
./opensl_test
echo "[pass] opensl_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./opensl_test
echo "[pass] opensl_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 ./opensl_test
echo "[pass] opensl_test (TSan)"
- name: Build and run qsa_test (the QNX driver against a mock QSA device)
shell: bash
working-directory: samples/audio/qsa
run: |
set -eu
# audio/drivers/alsa_qsa.c is QNX-only and has no build here,
# so it is built against a stand-in <sys/asoundlib.h> over a
# scripted device: init and its failure path, the rate it
# reports back, blocking and non-blocking writes, stop and
# start, underrun recovery, and a device that stops draining.
# Not a substitute for a QNX build; it is the coverage the
# driver had none of.
make clean && make -j$(nproc) all
./qsa_test
echo "[pass] qsa_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
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 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; 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.
export XDG_RUNTIME_DIR=/tmp/xdg
mkdir -p "$XDG_RUNTIME_DIR/pulse"
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" \
--log-target=file:/tmp/pa.log &
PA_PID=$!
sleep 3
make clean && make -j$(nproc) all
./live_drivers_test
echo "[pass] live_drivers_test"
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)"
kill $PA_PID || true
- name: Build and run binaural_test (plain, ASan + UBSan)
shell: bash
working-directory: samples/audio/binaural
run: |
set -eu
# A layout rendered to two ears for headphones: a left speaker
# arrives at the left ear first, louder and brighter; the rear
# pair duller than the front; centre and LFE alike to both
# ears; a centred source keeps its level and a full-scale one
# leaves at full scale; the two 5.1s render their rear pair
# from different directions; stereo is a mild crossfeed.
make clean && make -j$(nproc) all
./binaural_test
echo "[pass] binaural_test"
make clean && make -j$(nproc) all SANITIZER=address,undefined
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./binaural_test
echo "[pass] binaural_test (ASan)"
- name: Build and run pipeline_rate_control_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/pipeline_rate_control
run: |
set -eu
# Includes audio/audio_driver.c and runs the threaded pipeline's
# shipping producer, consumer and rate controller against a
# device whose 8 ms buffer drains at exactly 48000 frames a
# second of wall-clock time, fed one 800-frame video frame every
# 1/60 s on an absolute schedule, audio sync off. The clocks
# match, so the right ratio is 1.0: after a four-second settle
# the mean rate adjustment over three seconds must be within
# 500 ppm of it, and the device must have taken 99.5% of what
# was produced. Rate control on the pipeline samples pipe and
# device together, at the producer; reading the device alone,
# which the consumer holds between half and full, pins the
# 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.
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
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
run: |
set -eu
# Every resampler backend's reset(): after it the stream
# continues as a freshly initialised backend would, to the
# sample, at the ratios the frontend meets - and the reset
# makes no allocation, counted through wrapped malloc, calloc
# and memalign_alloc.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x resampler_reset_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 ./resampler_reset_test
echo "[pass] resampler_reset_test (ASan)"
- name: Build and run ff_speedup_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/ff_speedup
run: |
set -eu
# Includes audio/audio_driver.c with the clock replaced by a
# counter. The fast-forward speedup multiplier must follow the
# core's cadence on both pipelines: measured at the flush inline,
# and by the producer at its publish cadence on the threaded
# pipeline, where the consumer's own flush interval is the device
# draining the previous chunk and would only confirm the previous
# multiplier. Re-entry after an idle spell must start from unity
# rather than read the idle time as one flush interval.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x ff_speedup_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 120 ./ff_speedup_test
echo "[pass] ff_speedup_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./ff_speedup_test
echo "[pass] ff_speedup_test (TSan)"
- name: Build and run device_list_driver_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/device_list_driver
run: |
set -eu
# Includes audio/audio_driver.c with the alsa and null drivers in
# the table. Picking a driver in the menu writes the setting but
# does not reinitialise audio, and the Device list - rebuilt on
# each open - was asked of the running driver, so it showed the
# old driver's devices under the new driver's name until a
# restart. The list now comes from the configured driver, and
# is freed by the driver that built it. Cases: configured and
# running agree; configured differs from running; back again;
# nothing running; and release by the builder, once.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x device_list_driver_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 120 \
./device_list_driver_test
echo "[pass] device_list_driver_test (ASan)"
- name: Build and run rate_control_bounds_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/rate_control_bounds
run: |
set -eu
# Includes audio/audio_driver.c and runs the rate control's
# shipping computation against a scripted driver. At the
# setpoint, empty and full it must give 1.0 and the band's two
# edges; with write_avail() reporting five times buffer_size()
# it must give the upper edge and no more. Before the clamp an
# over-reporting driver drove it nine times past the band.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x rate_control_bounds_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./rate_control_bounds_test
echo "[pass] rate_control_bounds_test (ASan)"
- name: Build and run latency_contract_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/audio/latency_contract
run: |
set -eu
# Real drivers on backends that need no hardware - the ALSA null
# PCM, SDL's dummy audio, OpenAL Soft's null device - opened at
# 64 and 32 ms and checked against audio_driver.h's contract:
# buffer_size() is the setting in bytes of the output format,
# write_avail() never exceeds it, a buffer's worth offered takes
# room, and the room comes back as the device plays. The sdl
# driver before fdda5f7 reports 42.7 ms against 64 here.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x latency_contract_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 120 \
./latency_contract_test
echo "[pass] latency_contract_test (ASan)"
make clean && make -j$(nproc) all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1:suppressions=$PWD/tsan.supp \
timeout 300 ./latency_contract_test
echo "[pass] latency_contract_test (TSan)"
- name: Build and run asio_convert_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/asio_convert
run: |
set -eu
# audio/drivers/asio_convert.h is the ASIO driver's sample
# conversion, pure C, so it runs here without Windows. Every
# ASIOSampleType the specification defines is converted for full
# scale, zero, half and one 16-bit step in both signs and checked
# byte for byte against the layout the specification gives - the
# Int32LSB16..24 family as low-aligned, sign-extended words, the
# MSB types big-endian. Saturation and the silence fill past the
# supplied frames are checked too. The converter this replaced
# wrote five types and memset the rest to silence.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x asio_convert_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./asio_convert_test
echo "[pass] asio_convert_test (ASan)"
- name: Build and run coreaudio_clock_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/coreaudio_clock
run: |
set -eu
# The device clock fitted from the timestamp the render
# callback is handed, which the driver used to discard.
#
# The fit is the same shape as the ASIO one and is checked
# there. What is different is the time axis: mHostTime is in
# mach absolute units, not nanoseconds, and the ratio is one
# to one on Intel and 125 to 3 on Apple silicon. Ignoring it
# reads a 48 kHz device as 1152 Hz - invisible on Intel and
# wrong on every Mac since 2020 - so the same clock is driven
# through both timebases here.
#
# Also mRateScalar, which is the HAL's own figure for the
# same thing, read only where it is flagged valid.
#
# Arithmetic only, so it runs here without a Mac.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x coreaudio_clock_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./coreaudio_clock_test
echo "[pass] coreaudio_clock_test (ASan)"
- name: Build and run coreaudio_ring_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/coreaudio_ring
run: |
set -eu
# The CoreAudio ring keeps a frame's channels together. Its
# capacity is the sample count rounded up to a power of two,
# which for six channels is not a whole number of frames, so
# the cursors wrap mid-frame - and that does not matter,
# because a FIFO returns samples in the order they went in
# wherever they sit. This runs the traffic for every layout,
# then forces every transfer across the wrap, to keep that
# answer honest rather than assumed.
#
# What does rotate the channels is a transfer whose count is
# not a whole number of frames, which is why the callback
# trims short reads. The last case does that on purpose and
# fails if it goes unnoticed, so the trim has a guard.
#
# Arithmetic only, so it runs here without a Mac.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x coreaudio_ring_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./coreaudio_ring_test
echo "[pass] coreaudio_ring_test (ASan)"
- name: Build and run asio_clock_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/asio_clock
run: |
set -eu
# The device clock read from the driver's own time
# information, rather than from when its callbacks arrived.
#
# Two things here do not need an interface. The ASIOTime
# layout is an ABI: the sample position and system time are
# 64-bit values the SDK splits into 32-bit halves on Windows,
# and getting that wrong does not fail to build, it reads a
# driver's numbers as garbage in a real-time callback. The
# offsets are asserted against the SDK's, and asio.c carries
# the same assertions for the compiler that sees the real
# Windows ABI.
#
# And the estimate itself: a clock at a known offset is fed
# in with scheduling jitter on the timestamps, and the answer
# has to be the clock. A two-point estimate fails that - the
# anchor's own noise divided by the window reads as drift,
# 50 ppm for half a millisecond at ten seconds - which is why
# it is a least-squares fit over every callback instead.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x asio_clock_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./asio_clock_test
echo "[pass] asio_clock_test (ASan)"
- name: Build and run asio_ring_test (ASan + UBSan)
shell: bash
working-directory: samples/audio/asio_ring
run: |
set -eu
# Also the write's frame alignment: the callback reads the
# ring a frame at a time, so a write must end on one, and
# the rule is checked for every layout the driver can open.
#
# audio/drivers/asio_ring.h sizes the ring in front of the ASIO
# device: the latency setting less the device's reported stage,
# floored at four periods where that is under 6 ms, 6 ms where it
# is over, two periods at the least. Arithmetic only, so it runs
# here without Windows. The expected frames are worked by hand
# from those rules for the devices that set them - ASIO4ALL at 64
# frames, a wrapper locked at 528, a USB DAC at 8 and 128 - and
# the two points where the rules meet.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x asio_ring_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./asio_ring_test
echo "[pass] asio_ring_test (ASan)"
- name: Build and run dsound_pump_test (MinGW, under wine)
shell: bash
working-directory: samples/audio/dsound_pump
run: |
set -eu
# 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
# waits for the play cursor to move the distance it needs,
# worked out from the rate, instead of retrying every
# 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 all
WINEDEBUG=-all timeout 300 make check
echo "[pass] dsound_pump_test (wine)"
- name: Build and run wasapi_exclusive_pacing_test (ASan + UBSan, then TSan)
shell: bash
working-directory: samples/audio/wasapi_exclusive_pacing
run: |
set -eu
# audio/drivers/wasapi.c, unmodified but for its Windows include
# lines, against a fake device on a real-time clock: exclusive
# and event-driven, one period per endpoint buffer, every period
# taken or counted unanswered. The writer is a frontend with audio
# sync off: one frame of core audio per non-blocking write, no rate
# control. Passes when no period goes unanswered in either mode and
# nothing is dropped once the buffer holds a frame. Before the pump
# 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%.
make clean && make -j$(nproc) all SANITIZER=address,undefined
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
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
working-directory: samples/audio/sink_rate
run: |
set -eu
# The frontend's sink rate estimator against a scripted driver
# on a synthetic clock: a device 120 ppm fast and 80 ppm slow are
# measured and the resampling bias converges onto them; 5000 ppm
# stops at the clamp; with rate control on the bias absorbs rate
# control's mean adjustment; a paused window, a count that went
# backwards, and a stalled window move nothing; disabled, nothing
# moves at all.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x sink_rate_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 ./sink_rate_test
echo "[pass] sink_rate_test (ASan)"
- name: Build and run pacing_test (ASan + UBSan)
shell: bash
working-directory: samples/runloop/pacing
run: |
set -eu
# The three pacing decisions the runloop makes every
# iteration, run from runloop.h so this is the shipping code
# rather than a copy of it. The gap limiter over all 128
# combinations of the pace bits by nonblocking by fastmotion -
# exactly one may engage, because engaging next to another
# source double-paces and engaging under fast-forward
# throttles it to 1x, and both look like performance bugs
# rather than pacing bugs. The frame period over the rates a
# core can report including zero and a million, bounded and
# monotonic. And the filter on the measured loop rate, which
# has to reject a stall: one 0.9 s sample used to pull a 60
# fps reading to 8 and take several frames to recover.
make clean && make -j$(nproc) all SANITIZER=address,undefined
test -x pacing_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1 timeout 60 ./pacing_test
echo "[pass] pacing_test (ASan)"
- name: Build the ALSA objects through configure (--enable-alsa)
shell: bash
run: |
set -eu
# The harnesses above compile audio/drivers/alsa.c with
# -DHAVE_ALSA on the command line. A distribution build takes
# HAVE_ALSA from config.h instead, and the file gates its
# alsa-lib includes on it, so build the objects that way too:
# configure with ALSA on, then compile them. That covers the
# object a distribution ships as well as the ones the
# harnesses build (libretro/RetroArch#19525). The embedded
# driver takes its define the same way and shares the file,
# so the arrangements below cover it too.
./configure --enable-alsa --disable-qt --disable-ffmpeg \
--disable-x11 --disable-wayland
grep -q '^HAVE_ALSA = 1' config.mk
make obj-unix/release/audio/drivers/alsa.o \
obj-unix/release/audio/common/alsa.o
echo "[pass] alsa-lib alone, through configure"
# The embedded driver is in the same file behind its own
# define, and configure puts HAVE_TINYALSA in config.h as
# well as on the command line - so it has the same question
# to answer as HAVE_ALSA did, and one object serves both
# drivers. The two arrangements a distribution can ask for:
# the embedded driver with no alsa-lib anywhere, and both in
# the one object.
rm -f obj-unix/release/audio/drivers/alsa.o
./configure --enable-tinyalsa --disable-alsa --disable-qt \
--disable-ffmpeg --disable-x11 --disable-wayland
grep -q '^HAVE_TINYALSA = 1' config.mk
grep -q '^HAVE_ALSA = 0' config.mk
make obj-unix/release/audio/drivers/alsa.o
echo "[pass] the embedded driver alone, through configure"
rm -f obj-unix/release/audio/drivers/alsa.o \
obj-unix/release/audio/common/alsa.o
./configure --enable-alsa --enable-tinyalsa --disable-qt \
--disable-ffmpeg --disable-x11 --disable-wayland
grep -q '^HAVE_TINYALSA = 1' config.mk
grep -q '^HAVE_ALSA = 1' config.mk
make obj-unix/release/audio/drivers/alsa.o \
obj-unix/release/audio/common/alsa.o
echo "[pass] both drivers in the one object, through configure"
- name: Build and run stretch and native SRC chain (C89, ASan + UBSan)
working-directory: samples/audio/stretch
run: |
make -j$(nproc) check SANITIZER=address,undefined
- name: Build and run WSOLA kernel tests (C89, ASan + UBSan)
working-directory: samples/audio/wsola_search
run: |
make -j$(nproc) check SANITIZER=address,undefined
- name: Build and run native speed LPF tests (C89, ASan + UBSan)
working-directory: samples/audio/speed_lpf
run: make check SANITIZER=address,undefined
- name: Build and run experimental sinc HQ tests (C89, ASan + UBSan)
working-directory: samples/audio/sinc_hq
run: |
make -j$(nproc) check SANITIZER=address,undefined
- name: Build and run sinc AVX tests (C89, ASan + UBSan)
working-directory: samples/audio/sinc_hq
run: |
if grep -qw avx /proc/cpuinfo; then
make clean
make -j$(nproc) check CC="gcc -mavx" SANITIZER=address,undefined
else
echo "AVX unavailable on this runner; scalar/SSE tests ran above."
fi
- name: Build and run extra-channel capacity test (ASan + UBSan)
working-directory: samples/audio/extra_capacity
run: |
make -j$(nproc) check SANITIZER=address,undefined
make clean
make -j$(nproc) check SIMD_MASK=RESAMPLER_SIMD_SSE SANITIZER=address,undefined
- name: Build and run resampler option tests (C89, ASan + UBSan)
working-directory: samples/audio/resampler_options
run: |
make -j$(nproc) check SANITIZER=address,undefined
-170
View File
@@ -1,170 +0,0 @@
name: CI Linux samples/cores
on:
push:
branches:
- master
paths:
- 'cores/libretro-ffmpeg/**'
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
- 'samples/cores/**'
- '.github/workflows/Linux-samples-cores.yml'
pull_request:
branches:
- master
paths:
- 'cores/libretro-ffmpeg/**'
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
- 'samples/cores/**'
- '.github/workflows/Linux-samples-cores.yml'
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:
samples-cores:
name: Build and run samples/cores
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run camera ffmpeg_live_test (plain, ASan + UBSan, TSan)
shell: bash
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 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, and a source that
# does not exist.
make clean all
./ffmpeg_live_test
echo "[pass] ffmpeg_live_test"
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 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 ffmpeg_sweep_test (plain, ASan + UBSan, TSan)
shell: bash
working-directory: samples/cores/ffmpeg_sweep
run: |
set -eu
# Breadth where ffmpeg_audio_pipe_test has depth: eight clips
# across containers, video and audio codecs, rates, channel
# counts and the one-sided cases, each loaded, run, seeked
# both ways, reset and unloaded in one process - so the
# second load is what finds what the first unload left
# behind - then files that are truncated, stubbed, noise,
# empty or absent, then teardown while the decode thread is
# still working.
#
# 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 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 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)"
- name: Build and run ffmpeg_audio_pipe_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/cores/ffmpeg_audio_pipe
run: |
set -eu
# cores/libretro-ffmpeg/ffmpeg_core.c as a libretro host would
# drive it: a generated clip (tone under a test pattern), 5 s
# of frames checked for the audio frame count and a tone in
# every batch, then R1/L1 seeks both ways - the decode-thread
# / main-thread handshake around the audio ring - and a
# 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 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 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
# those libraries are suppressed; a race in the core's own
# code is still reported.
TSAN_OPTIONS=halt_on_error=1:suppressions=tsan.supp \
timeout 300 ./ffmpeg_audio_pipe_test
echo "[pass] ffmpeg_audio_pipe_test (TSan)"
-207
View File
@@ -1,207 +0,0 @@
name: CI Linux samples/formats
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
samples-formats:
name: Build and run samples/formats
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run dts_lpcm_test (plain, ASan + UBSan)
shell: bash
working-directory: samples/formats/dts_lpcm
run: |
set -eu
# The DTS frame layer and the LPCM codec against ffmpeg.
#
# rdts reads frames, it does not decode them, so what is
# checked is that every frame is found where ffmpeg's
# encoder put it, that the rate and the arrangement agree
# with ffprobe's reading of the same file, and that a stream
# byte-swapped or packed fourteen bits to the word reads
# back to the same core - which is what a receiver and a
# decoder are handed.
#
# rlpcm does decode, and is bit-exact: the samples go out
# through ffmpeg's own converters and come back the same, at
# 16 and 24 bits and both byte orders, and what rlpcm writes
# back is the bytes it read. 20-bit has no ffmpeg format to
# compare against - two samples to five bytes is a disc
# packing - so it is checked against itself, and the DVD and
# Blu-ray headers against their field layouts. The
# audio_transfer arm is driven too: chunked reads against
# the codec's own output, the compressed frontier, and
# seeks, which for constant-size frames land exactly.
#
# And the pass-through route, which is what a format with no
# 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 all
./dts_lpcm_test
echo "[pass] dts_lpcm_test"
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)"
- name: Build and run image_decode_fuzz_test (ASan + UBSan + LSan)
shell: bash
working-directory: samples/formats/image_decode_fuzz
run: |
set -eu
# Malformed-input sweep for the BMP, TGA, DDS and WebP decoders in
# libretro-common/formats. All three take dimensions and
# layout from a header the file supplies and size their
# output from it, which is where this kind of arithmetic
# goes wrong, and none of the four had any test at all.
# (WebP is told its buffer length, so it is the least
# exposed of them; its chunk walk still trusts sizes that
# came out of the file.)
#
# It found one on its first run: rbmp_proc_reset() gated the
# free of output_image on phase != RBMP_PHASE_IDLE, but
# rbmp_begin() allocates that surface before it sets any
# phase and returns false between the two for a palette
# header claiming a bits-per-pixel other than 4 or 8. Every
# such image leaked the surface, reachable from any
# malformed or hostile BMP. Leak detection is therefore
# switched on explicitly here rather than left to the
# default.
#
# The sweep truncates each seed at every length and sets
# every header byte to each of six interesting values,
# including the ones that make dimensions enormous. The
# count of inputs that decode successfully is asserted
# inside the test, so a sweep where the seeds stopped being
# accepted would fail rather than exercise only the reject
# 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 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
echo "[pass] image_decode_fuzz_test"
- name: Build and run image_avail_test (ASan + UBSan + LSan)
shell: bash
working-directory: samples/formats/image_avail
run: |
set -eu
# Partial-buffer ("avail-aware") still decoding for TGA and
# BMP, checked
# against the whole-buffer decode that has always been
# there: every fixture is decoded once with the file fully
# resident and again with the frontier raised a few bytes at
# a time, and the two surfaces must be bit-identical.
#
# The oracle is the decoder itself, so this catches the
# failures that do not crash: a wall mistaken for EOF (the
# decode pads the rest of the surface and reports success),
# an RLE run re-emitted after a stall, a cursor resumed off
# by a pixel. It found all three of those on its first runs
# while TGA was being converted.
#
# BMP rows are bottom-up, so a prefix of the file is the
# bottom of the image and a stall resumed on the wrong row
# shows up as a vertically displaced surface rather than as
# noise. The 4bpp and 8bpp fixtures put the wall inside the
# palette as well.
#
# Steps of 1, 3 and 7 bytes put the wall inside every field,
# inside RLE packets and mid-pixel for both 24bpp and 32bpp;
# 1024 is a realistic read granularity. A truncated file
# must still settle rather than wait forever, which is the
# one case where stopping at the frontier and stopping at
# the end of the data have to be told apart.
#
# One set of checks replays task_image's real call sequence
# rather than an order this test invented - set_buffer_ptr,
# then set_avail BEFORE each process(), then set_avail
# ((size_t)-1) the instant the read completes, which for a
# small file is before any process() has run - at four read
# granularities. Inventing the order instead of replaying
# it is exactly how the blank-BMP/TGA-thumbnail regression
# got past this file: every other check here raised the
# frontier only after the first process() call.
#
# One set of checks drives every avail-aware still decoder -
# PNG and JPEG as well as TGA and BMP - through the
# image_transfer facade in task_image's order. PNG, JPEG,
# WEBM and MP4 clamp the requested frontier in the size
# domain because their set_buf_ptr is given the buffer
# length; rtga's and rbmp's are not, which is why those two
# were the only ones that could turn (size_t)-1 into a
# wrapped pointer, and did. A sixth avail-aware decoder
# inherits whichever shape it copies, so the check lives
# here rather than in anyone's memory.
#
# It also checks header_ready, the gate the task layer uses
# to start a decode early, against the decoder itself: every
# prefix it accepts must be one the decoder can actually
# 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 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"
File diff suppressed because it is too large. Load diff
-136
View File
@@ -1,136 +0,0 @@
name: CI Linux samples/input
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
samples-input:
name: Build and run samples/input
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 5
run: |
pkgs="build-essential libusb-1.0-0-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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run illuminance_sensor_test (ASan + UBSan)
shell: bash
working-directory: samples/input/illuminance_sensor
run: |
set -eu
# The Linux IIO illuminance sensor poller, against a fake
# sysfs tree under /tmp. Pins that the poll thread waits on a
# condition between readings rather than sleeping: a raised
# rate applies at once, and close returns without waiting out
# the period.
make clean all SANITIZER=address,undefined
test -x illuminance_sensor_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./illuminance_sensor_test
echo "[pass] illuminance_sensor_test (ASan)"
- name: Build and run illuminance_sensor_test (TSan)
shell: bash
working-directory: samples/input/illuminance_sensor
run: |
set -eu
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 60 ./illuminance_sensor_test
echo "[pass] illuminance_sensor_test (TSan)"
- name: Build and run libusb_hid_test (ASan + UBSan)
shell: bash
working-directory: samples/input/libusb_hid
run: |
set -eu
# The libusb HID driver against a fake libusb: reads and
# commands run on asynchronous transfers completed by the poll
# thread, with no thread per pad. Pins that a command goes out
# at once even while the pad sends nothing, that commands stay
# in order one at a time, that unplugging frees the adapter,
# and that freeing the driver returns at once with a send
# still pending, releasing every transfer and handle.
make clean all SANITIZER=address,undefined
test -x libusb_hid_test
ASAN_OPTIONS=detect_leaks=1:detect_stack_use_after_return=1 \
UBSAN_OPTIONS=print_stacktrace=1 timeout 60 \
./libusb_hid_test
echo "[pass] libusb_hid_test (ASan)"
- name: Build and run libusb_hid_test (TSan)
shell: bash
working-directory: samples/input/libusb_hid
run: |
set -eu
make clean all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 60 ./libusb_hid_test
echo "[pass] libusb_hid_test (TSan)"
- name: Build and run wii_handshake_test (ASan + UBSan)
shell: bash
working-directory: samples/input/wii_handshake
run: |
set -eu
# The Wiimote extension handshake in connect_wii.c, fed
# reports directly. Pins that each init write waits for the
# remote's acknowledgement instead of a sleep on the packet
# thread, that a missing acknowledgement is only overtaken by
# a packet after the old 100 ms, and that no packet blocks.
make clean all SANITIZER=address,undefined
test -x wii_handshake_test
ASAN_OPTIONS=detect_leaks=1 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
timeout 60 ./wii_handshake_test
echo "[pass] wii_handshake_test (ASan)"
-123
View File
@@ -1,123 +0,0 @@
name: CI Linux samples/network
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
samples-network:
name: Build and run samples/network
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 5
run: |
pkgs="build-essential libmbedtls-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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run webdav_options_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/network/webdav_options
run: |
set -eu
# Includes network/cloud_sync/webdav.c and drives the OPTIONS
# capability probe as shipped over real-world header sets. The
# probe has to separate a WebDAV server from a plain HTTP
# server that answers OPTIONS, and the target it probes is a
# collection, on which PUT is not defined (RFC 4918 9.7.1) -
# so PUT's absence from Allow must not fail it. The previous
# probe did exactly that, rejecting mod_dav and Koofr
# (libretro/RetroArch#19486) while accepting a plain nginx
# that happened to list PUT. Covers the DAV header, Allow-only
# 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 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 all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 120 ./webdav_options_test
echo "[pass] webdav_options_test (TSan)"
- name: Build and run cheevos_login_test (bear ASan+UBSan, bear TSan, mbed ASan+UBSan)
shell: bash
working-directory: samples/network/cheevos_login
run: |
set -eu
# Regression guard for the RetroAchievements login transport
# (libretro/RetroArch#19562, #19457): drives net_http with the
# exact login shape cheevos_client.c produces, against a local
# mock server that validates every request byte-for-byte, over
# plain HTTP and over TLS with the real SSL backend linked in.
# Covers: login on a fresh TLS connection, trust-store loading
# from a realistic messy CA bundle (BearSSL), keep-alive pool
# reuse, one-shot replay of a request on a pooled connection
# the server closed while idle, and no replay once response
# bytes have been seen.
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 all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 180 make check
echo "[pass] cheevos_login_test (BearSSL, TSan)"
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)"
-103
View File
@@ -1,103 +0,0 @@
name: CI Linux samples/record
on:
push:
branches:
- master
paths:
- 'record/**'
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
- 'samples/record/**'
- '.github/workflows/Linux-samples-record.yml'
pull_request:
branches:
- master
paths:
- 'record/**'
- 'libretro-common/queues/**'
- 'libretro-common/include/retro_spsc.h'
- 'libretro-common/include/retro_atomic.h'
- 'samples/record/**'
- '.github/workflows/Linux-samples-record.yml'
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:
samples-record:
name: Build and run samples/record
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run ffmpeg_pipeline_test (ASan + UBSan, TSan)
shell: bash
working-directory: samples/record/ffmpeg_pipeline
run: |
set -eu
# record/drivers/record_ffmpeg.c end to end: frames whose
# pixels encode their number, plus audio, pushed from the
# test thread while the driver's encoder thread drains the
# attr/video/audio rings; the file is decoded back and every
# frame checked in order and pixel-exact. Covers the rings
# 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 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 all SANITIZER=thread
TSAN_OPTIONS=halt_on_error=1 timeout 300 ./ffmpeg_pipeline_test
echo "[pass] ffmpeg_pipeline_test (TSan)"
@@ -1,89 +0,0 @@
name: CI Linux samples/settings
on:
push:
branches:
- master
pull_request:
branches:
- master
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:
samples-settings:
name: Build and run samples/settings
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Restore ccache
uses: actions/cache@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
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 500M
ccache -z
- name: Build and run pipeline_migration_test (ASan + UBSan)
shell: bash
working-directory: samples/settings/pipeline_migration
run: |
set -eu
# The audio_threaded_pipeline config migration. The setting
# briefly held off/automatic/on and was saved as a number; it
# is a bool again, and a bool is always saved as "true" or
# "false", so a bare digit on the key is the older three-way
# value. config_get_bool() reads its automatic (1) as an
# explicit on, which forced the pipeline on for users who
# never chose it. Pins each stored digit against both
# defaults, and pins that "true", "false", absent, empty and
# 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 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)"
File diff suppressed because it is too large. Load diff
@@ -1,68 +0,0 @@
name: CI Linux state_manager + runahead tests
# The rewind codec and ring, and the run-ahead core-copy protocol,
# driven directly by harnesses that include or extract the shipping
# code: samples/state_rewind and samples/runahead. Plain, then under
# ASan and UBSan with halt_on_error.
on:
push:
branches: [master]
paths:
- state_manager.c
- state_manager.h
- runahead.c
- runahead.h
- runloop.h
- samples/state_rewind/**
- samples/runahead/**
- tasks/task_nbio_slice.c
- tasks/tasks_internal.h
- libretro-common/queues/task_queue.c
- .github/workflows/Linux-state-runahead-tests.yml
pull_request:
branches: [master]
paths:
- state_manager.c
- state_manager.h
- runahead.c
- runahead.h
- runloop.h
- samples/state_rewind/**
- samples/runahead/**
- tasks/task_nbio_slice.c
- tasks/tasks_internal.h
- libretro-common/queues/task_queue.c
- .github/workflows/Linux-state-runahead-tests.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:
unit:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v5
- name: state_rewind
run: make -C samples/state_rewind clean check
- name: runahead
run: make -C samples/runahead clean check
sanitize:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
ASAN_OPTIONS: abort_on_error=1:detect_leaks=1:print_stacktrace=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
steps:
- uses: actions/checkout@v5
- name: state_rewind (ASan + UBSan)
run: make -C samples/state_rewind clean check SANITIZER=address,undefined
- name: runahead (ASan + UBSan)
run: make -C samples/runahead clean check SANITIZER=address,undefined
-84
View File
@@ -1,84 +0,0 @@
name: CI Linux TSan [threaded-video harness]
# The threaded-video harness under ThreadSanitizer. Linux-tsan-threaded-
# video.yml builds with TSan and runs RetroArch headless with the
# wrapper on, which is one configuration; the harness has a lane for
# each thing the wrapper does - the runtime toggle, reinit under the
# wrapper, the command mailbox, presenter repeats and their display
# phase, the second ring waiter, the re-entrant frame, the call on the
# waiting thread, display pacing, the zero-copy loan, the hardware
# ring's bookkeeping - and runs each against the shipping objects with
# nothing stubbed. It is where the send/wait race in the waiter call
# was found, under TSan, on a developer's machine: this job is what
# keeps that class of bug found in CI instead. Null drivers, no
# display, no SDL, so no suppression file is needed; the harness sets
# halt_on_error itself, so any report fails the job.
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:
linux-tsan-harness:
name: TSan build, the threaded-video harness
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Install dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
# Non-Qt, as the harness requires (with Qt, main() lives in
# ui_qt.o). Menu enabled: the menu lanes are half the point.
run: |
./configure \
--disable-qt \
--disable-discord \
--disable-cheevos \
--disable-networking \
--disable-ffmpeg
- name: Build with DEBUG=1 and -fsanitize=thread
run: |
make -j$(getconf _NPROCESSORS_ONLN) SANITIZER=thread DEBUG=1
- name: Run the threaded-video harness under TSan
shell: bash
run: |
set -eu
# SAN=thread links exactly the build above; CYCLES=2 runs
# each toggling lane twice. The harness's own TSAN_OPTIONS
# halt on the first report.
SAN=thread CYCLES=2 make -C samples/gfx/threaded_video check
make -C samples/gfx/threaded_video clean
@@ -1,165 +0,0 @@
name: CI Linux TSan [Threaded video]
# Builds RetroArch with -fsanitize=thread and runs it headless with
# video_threaded = "true", which is the configuration none of the other
# jobs cover and the only one where the video thread exists at all.
#
# Why a separate job from Linux-asan-ubsan.yml: ASan and TSan cannot be
# linked into the same binary, and the ASan job deliberately runs
# unthreaded (video_threaded = "false") because its purpose is memory
# errors on the simplest path. Threading bugs are invisible there --
# the second thread is never created.
#
# What this reaches that nothing else does: the video thread wrapper's
# command and frame handoff, every driver frame() call running off the
# main thread, and the state the runloop and the video thread share --
# window title, alive/focus/presentable, viewport and statistics. Two
# real races were found this way and fixed (the window title handoff,
# and the runloop asking a context for presentability while the video
# thread rebuilt its swapchain); this job is what keeps them fixed.
#
# Soft-fail for now, like the ASan job's smoke tier was on its first
# iterations: TSan reports races inside libSDL2 itself that RetroArch
# neither causes nor can fix (see the suppression file written below),
# and the baseline wants a few green runs before it gates.
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:
linux-tsan-threaded-video:
name: Build with TSan and run with threaded video
runs-on: ubuntu-latest
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: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- 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
# vendored subsystem. --enable-sdl2 is explicit because the run
# below selects sdl2, and a silent fallback to another driver
# would quietly stop exercising the threaded path this job is
# for.
run: |
./configure \
--disable-menu \
--disable-discord \
--disable-cheevos \
--disable-networking \
--enable-sdl2
- name: Build with -fsanitize=thread
run: |
make -j$(getconf _NPROCESSORS_ONLN) SANITIZER=thread
test -x retroarch
file retroarch
- name: Run headless with video_threaded = true
continue-on-error: true
run: |
set -eu
Xvfb :99 -screen 0 640x480x24 &
for i in $(seq 1 15); do
if DISPLAY=:99 xdpyinfo >/dev/null 2>&1; then
break
fi
sleep 1
done
# A 1x1 PNG for the imageviewer core, as in the ASan job.
python3 - <<'PY'
import binascii, struct
def chunk(t, d):
c = t + d
return struct.pack(">I", len(d)) + c + struct.pack(">I", binascii.crc32(c))
png = b"\x89PNG\r\n\x1a\n"
png += chunk(b"IHDR", struct.pack(">IIBBBBB", 1, 1, 8, 2, 0, 0, 0))
png += chunk(b"IDAT", b"\x08\xd7\x63\xf8\xcf\xc0\x00\x00\x03\x01\x01\x00\x18\xdd\x8d\xb0")
png += chunk(b"IEND", b"")
open("/tmp/test.png", "wb").write(png)
PY
# Races inside libSDL2 itself: no RetroArch frame appears on
# either access, so there is nothing here to fix. Suppressed
# by object so a real race in our own SDL-facing code is
# still reported.
cat > /tmp/tsan.supp <<'EOF'
race:libSDL2-2.0.so
EOF
mkdir -p /tmp/tsan-cfg
cat > /tmp/tsan-cfg/retroarch.cfg <<EOF
video_driver = "sdl2"
audio_driver = "null"
video_threaded = "true"
video_fullscreen = "false"
video_windowed_fullscreen = "false"
EOF
set +e
DISPLAY=:99 \
TSAN_OPTIONS="halt_on_error=0 history_size=4 suppressions=/tmp/tsan.supp" \
timeout 300 ./retroarch \
-c /tmp/tsan-cfg/retroarch.cfg \
-L cores/libretro-imageviewer/image_core.so \
/tmp/test.png \
--max-frames=400 \
--verbose \
> /tmp/tsan.out 2> /tmp/tsan.err
rc=$?
set -e
echo "exit=${rc}"
echo "=== stderr (last 200) ==="
tail -200 /tmp/tsan.err || true
# The video thread has to have existed, or the run proved
# nothing at all and a green result would be misleading.
if ! grep -q "ra-video\|[Tt]hreaded video" /tmp/tsan.out /tmp/tsan.err; then
echo "[WARN] no sign of the video thread; the threaded path may not have run"
fi
n=$(grep -c "WARNING: ThreadSanitizer" /tmp/tsan.err || true)
echo "ThreadSanitizer reports: ${n}"
if [ "${n}" -gt 0 ]; then
echo ""
echo "[INFO] ThreadSanitizer finding(s):"
grep "SUMMARY: ThreadSanitizer" /tmp/tsan.err || true
fi
@@ -1,399 +0,0 @@
name: CI Vulkan/GL/D3D11 [idle waits + driver harness]
# Two checks on the Vulkan driver, both born from the same bug: a
# vkQueuePresentKHR under queue_lock waiting for GPU work that a
# hardware core could only submit through lock_queue (parallel-GS /
# Granite stopped the frontend that way). Every vkQueueWaitIdle and
# vkDeviceWaitIdle in the driver had the same shape - a whole-queue
# drain, under the lock the core needs, on shader change, overlay
# load, font free and swapchain resize - and all of them were replaced
# by waits on the driver's own fences.
#
# 1. Idle-wait check: tools/vulkan_idle_wait_check.py fails on any
# vkQueueWaitIdle/vkDeviceWaitIdle in the Vulkan code that is not
# on tools/vulkan_idle_wait_allow.list, and on a stale entry.
#
# 2. Validation harness: the threaded-video harness (real frontend,
# real driver, only main() replaced) run on the Vulkan driver over
# lavapipe under Xvfb, with the tree built VULKAN_DEBUG=1 so
# VK_LAYER_KHRONOS_validation is loaded. The lanes exercise driver
# reinit under the wrapper, geometry changes, async texture loads,
# font marshalling, present repeat and resize; the layer turns a
# texture destroyed while a frame still samples it, a barrier
# inside a render pass, or an object leaked at device teardown into
# a logged error, and the check-vulkan target fails on any. Those
# three were the pre-existing findings the lane produced on its
# first run.
#
# 3. TSan harness: the same lanes on the same driver, built with
# -fsanitize=thread. The null-driver TSan job never runs driver
# code on the video thread, so a plain field shared between the
# frame thread and a driver's frame (the shader chains'
# FrameTimeDelta was one) only shows up here. The layer and the
# ICD are not instrumented and are suppressed; frontend races fail.
# An address,undefined build of the same runs beside it, and the
# context-only vulkan_validation sample runs on its own.
#
# 5. D3D11 harness: the same lanes on the d3d11 driver, on a Windows
# runner through MSYS2's MinGW64 build of the tree (no Qt, so main
# stays in retroarch.o for the harness to replace) and the software
# adapter the runner exposes (Microsoft Basic Render Driver, which
# is WARP). The first real-driver coverage the Windows drivers get.
#
# 4. GL harness: the same lanes on the gl and glcore drivers over
# llvmpipe (LIBGL_ALWAYS_SOFTWARE=1), release and TSan. A GL
# context is owned by one thread at a time, so anything the
# frontend does against the driver from the wrong thread is an X
# BadAccess here rather than a corruption elsewhere; the first run
# caught the OSD font rebuild doing exactly that.
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:
vulkan-idle-waits:
name: Vulkan idle-wait allowlist
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Checker self-test
shell: bash
run: |
set -eu
python3 tools/vulkan_idle_wait_check.py --selftest
- name: Tree check
shell: bash
run: |
set -eu
python3 tools/vulkan_idle_wait_check.py
vulkan-validation-harness:
name: Threaded-video harness on Vulkan (lavapipe, validation layer)
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Install dependencies
timeout-minutes: 8
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev libxcb1-dev libxinerama-dev libxrandr-dev libxxf86vm-dev libxv-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libvulkan-dev mesa-vulkan-drivers vulkan-validationlayers vulkan-tools libasound2-dev"
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
# Non-Qt, as the harness requires (with Qt, main() lives in
# ui_qt.o). Everything else at its default so the Vulkan driver
# is built with every path a release build has.
run: |
./configure --disable-qt
grep -q '^HAVE_VULKAN = 1' config.mk
- name: Build with VULKAN_DEBUG=1
# VULKAN_DEBUG enables VK_LAYER_KHRONOS_validation and the
# debug messenger that reports through RARCH_ERR. It is a
# tree-wide define: vulkan_context_t carries a member under it,
# so every TU that includes vulkan_common.h must see it.
run: |
make -j$(getconf _NPROCESSORS_ONLN) VULKAN_DEBUG=1
test -x retroarch
- name: Run the harness on Vulkan under the validation layer
shell: bash
run: |
set -eu
Xvfb :99 -screen 0 640x480x24 &
for i in $(seq 1 15); do
if DISPLAY=:99 xdpyinfo >/dev/null 2>&1; then
break
fi
sleep 1
done
export DISPLAY=:99
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/lvp_icd.json
# The harness build reuses the tree's own compile and link
# lines, so it has to name the same build: VK_DEBUG=1. Its
# surface and overlay-page lanes run the driver's real
# in-place texture update and its borrowed-texture overlay
# page here, under the validation layer.
SAN=none VK_DEBUG=1 CYCLES=2 make -C samples/gfx/threaded_video check-vulkan
make -C samples/gfx/threaded_video clean
vulkan-validation-sample:
name: vulkan_validation sample (lavapipe, validation layer)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Install dependencies
timeout-minutes: 8
run: |
pkgs="build-essential libx11-dev libx11-xcb-dev libxcb1-dev xvfb x11-utils libvulkan-dev mesa-vulkan-drivers vulkan-validationlayers vulkan-tools"
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Build and run
shell: bash
run: |
set -eu
# The context-only sample: vulkan_common.c against the real
# loader, brought up and torn down under the validation
# layer, and every memory type it advertises selected. It
# exits 77 with no display or no device, and that is a pass.
Xvfb :99 -screen 0 640x480x24 &
for i in $(seq 1 15); do
if DISPLAY=:99 xdpyinfo >/dev/null 2>&1; then
break
fi
sleep 1
done
export DISPLAY=:99
make -C samples/gfx/vulkan_validation
rc=0
DISPLAY=:99 VK_DRIVER_FILES=/usr/share/vulkan/icd.d/lvp_icd.json \
samples/gfx/vulkan_validation/vulkan_validation_test || rc=$?
make -C samples/gfx/vulkan_validation clean
if [ "$rc" = 77 ]; then echo "skipped: no device"; exit 0; fi
exit $rc
vulkan-asan-harness:
name: Threaded-video harness on Vulkan under ASan+UBSan (lavapipe)
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Install dependencies
timeout-minutes: 8
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev libxcb1-dev libxinerama-dev libxrandr-dev libxxf86vm-dev libxv-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libvulkan-dev mesa-vulkan-drivers vulkan-validationlayers vulkan-tools libasound2-dev"
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: |
./configure --disable-qt
grep -q '^HAVE_VULKAN = 1' config.mk
- name: Build with DEBUG=1, VULKAN_DEBUG=1 and -fsanitize=address,undefined
run: |
make -j$(getconf _NPROCESSORS_ONLN) SANITIZER=address,undefined DEBUG=1 VULKAN_DEBUG=1
test -x retroarch
- name: Run the harness on Vulkan under ASan+UBSan
shell: bash
run: |
set -eu
Xvfb :99 -screen 0 640x480x24 &
for i in $(seq 1 15); do
if DISPLAY=:99 xdpyinfo >/dev/null 2>&1; then
break
fi
sleep 1
done
export DISPLAY=:99
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/lvp_icd.json
SAN=address VK_DEBUG=1 CYCLES=1 make -C samples/gfx/threaded_video check-vulkan
make -C samples/gfx/threaded_video clean
vulkan-tsan-harness:
name: Threaded-video harness on Vulkan under TSan (lavapipe)
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Install dependencies
timeout-minutes: 8
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev libxcb1-dev libxinerama-dev libxrandr-dev libxxf86vm-dev libxv-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libvulkan-dev mesa-vulkan-drivers vulkan-validationlayers vulkan-tools libasound2-dev"
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: |
./configure --disable-qt
grep -q '^HAVE_VULKAN = 1' config.mk
- name: Build with DEBUG=1, VULKAN_DEBUG=1 and -fsanitize=thread
run: |
make -j$(getconf _NPROCESSORS_ONLN) SANITIZER=thread DEBUG=1 VULKAN_DEBUG=1
test -x retroarch
- name: Run the harness on Vulkan under TSan
shell: bash
run: |
set -eu
Xvfb :99 -screen 0 640x480x24 &
for i in $(seq 1 15); do
if DISPLAY=:99 xdpyinfo >/dev/null 2>&1; then
break
fi
sleep 1
done
export DISPLAY=:99
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/lvp_icd.json
SAN=thread VK_DEBUG=1 CYCLES=1 make -C samples/gfx/threaded_video check-vulkan
make -C samples/gfx/threaded_video clean
gl-harness:
name: Threaded-video harness on ${{ matrix.driver }} (llvmpipe, ${{ matrix.san }})
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
driver: [gl, glcore]
san: [none, address, thread]
steps:
- name: Install dependencies
timeout-minutes: 8
run: |
pkgs="build-essential libxkbcommon-dev libx11-xcb-dev libxcb1-dev libxinerama-dev libxrandr-dev libxxf86vm-dev libxv-dev xvfb x11-utils zlib1g-dev libfreetype6-dev libgl-dev libglx-dev libegl-dev libgles-dev libgl1-mesa-dri libglx-mesa0 mesa-utils libasound2-dev"
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: |
./configure --disable-qt
grep -q '^HAVE_OPENGL = 1' config.mk
grep -q '^HAVE_OPENGL_CORE = 1' config.mk
- name: Build
run: |
case "${{ matrix.san }}" in
thread) make -j$(getconf _NPROCESSORS_ONLN) SANITIZER=thread DEBUG=1 ;;
address) make -j$(getconf _NPROCESSORS_ONLN) SANITIZER=address,undefined DEBUG=1 ;;
*) make -j$(getconf _NPROCESSORS_ONLN) ;;
esac
test -x retroarch
- name: Run the harness on ${{ matrix.driver }}
shell: bash
run: |
set -eu
Xvfb :99 -screen 0 640x480x24 &
for i in $(seq 1 15); do
if DISPLAY=:99 xdpyinfo >/dev/null 2>&1; then
break
fi
sleep 1
done
export DISPLAY=:99
export LIBGL_ALWAYS_SOFTWARE=1
SAN=${{ matrix.san }} DRIVER=${{ matrix.driver }} CYCLES=1 \
make -C samples/gfx/threaded_video check-driver
make -C samples/gfx/threaded_video clean
d3d-harness:
name: Threaded-video harness on ${{ matrix.driver }} (WARP, MSYS2 MinGW64)
runs-on: windows-latest
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
# d3d12 runs the same lanes on the other explicit-API backend:
# its in-place texture update is fence-tagged against the frame
# that last copied from the upload buffer, which only a running
# driver exercises.
driver: [d3d11, d3d12]
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
install: >-
base-devel
git
pacboy: >-
cc:p
gdb:p
- name: Configure and build RetroArch (no Qt)
shell: msys2 {0}
run: |
set -eu
./configure --disable-qt
grep -q '^HAVE_D3D11 = 1' config.mk
grep -q '^HAVE_D3D12 = 1' config.mk
make -j"$(nproc)"
test -x retroarch.exe
- name: Run the harness on ${{ matrix.driver }}
shell: msys2 {0}
run: |
set -eu
samples/gfx/threaded_video/build.sh
SAN=none DRIVER=${{ matrix.driver }} CYCLES=1 GDB=1 make -C samples/gfx/threaded_video check-driver
make -C samples/gfx/threaded_video clean
-50
View File
@@ -1,50 +0,0 @@
name: CI Linux (i686)
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-i386-ubuntu:xenial-gcc9
options: --user root
steps:
- name: Check Out Repo
uses: taiki-e/checkout-action@v1
- name: Configure Build
run: |
./configure --disable-qt --enable-xdelta
- name: Compile RA
run: |
make -j$(getconf _NPROCESSORS_ONLN) clean
make -j$(getconf _NPROCESSORS_ONLN) info all
- name: Stack frame sweep
run: |
set -eu
# Every stack frame in the graphics objects against the
# ceiling in CODING-GUIDELINES. It runs here rather than with
# the other checks because this is the job that builds the
# drivers: the menu harness turns OpenGL, Vulkan and the rest
# off for its own reasons, and the frames this sweep is for
# live in exactly those files.
.github/workflows/scripts/stack-frame-sweep.sh
-64
View File
@@ -1,64 +0,0 @@
name: CI Windows (MSVC)
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
# These jobs run smoke tests to ensure that MSVC-specific builds work properly.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
msvc:
runs-on: windows-2022
timeout-minutes: 90
strategy:
matrix:
version: [UWP, 2019, 2022]
configuration: [Debug, Release]
platform: [x64]
exclude:
- version: UWP
configuration: Debug
include:
- version: UWP
configuration: ReleaseAngle
platform: x64
# Qt and Cg builds are excluded for now
steps:
- uses: actions/checkout@v5
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1
- name: Compile RA
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
- name: Get short SHA
id: slug
shell: powershell
run: echo "sha8=$('${{github.sha}}'.Substring(0,8))" >> $env:GITHUB_OUTPUT
# https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
- uses: actions/upload-artifact@v4
with:
name: retroarch-${{matrix.version}}-${{matrix.configuration}}-${{matrix.platform}}-${{ steps.slug.outputs.sha8 }}
path: |
${{ matrix.version != 'UWP' }}:
pkg/msvc/${{matrix.platform}}/${{matrix.configuration}}/RetroArch-msvc${{matrix.version}}.exe
${{ matrix.version == 'UWP' }}:
pkg/msvc-uwp/AppPackages/RetroArch-msvcUWP
-98
View File
@@ -1,98 +0,0 @@
name: CI Windows (MSYS2)
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
msys2-build-test:
strategy:
fail-fast: false
matrix:
include:
# Existing x64 builds
- sys: MINGW64
runner: windows-latest
- sys: UCRT64
runner: windows-latest
- sys: CLANG64
runner: windows-latest
# New ARM64 build (native Windows on ARM)
- sys: CLANGARM64
runner: windows-11-arm
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
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 }}"
./configure
make -j"$(nproc)" info all
- name: Collect DLLs and binaries
shell: msys2 {0}
run: |
echo "Collecting DLLs and binaries"
rm -rf dist
mkdir -p dist
cp retroarch.exe dist/
ldd retroarch.exe | grep "$MINGW_PREFIX" | awk '{print $3}' | xargs -I {} cp {} dist/ || true
- name: Archive build artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: retroarch-${{ matrix.sys }}
path: dist/
-99
View File
@@ -1,99 +0,0 @@
name: CI macOS PowerPC (cross)
# Builds the macOS (Cocoa + OpenGL) frontend for 32-bit PowerPC with a
# GCC 14 cross compiler on Linux, against the 10.5 SDK, once for a
# 10.4 deployment target and once for 10.5. This is the
# compiler-compatibility leg for the Apple code: no clang, no ARC, no
# blocks, no GCD, and nothing newer than Leopard in the SDK. Whatever
# the Xcode 3 / PowerPC project would reject, this rejects first.
#
# Toolchain: VariantXYZ's GCC 14.2 powerpc-apple-darwin8 image (GCC
# with the Objective-C front end, cctools-port ld/as, dsymutil), see
# https://github.com/VariantXYZ/gcc-powerpc-apple-darwin8.
#
# The audit step lists every import the binary makes that the 10.4u
# SDK does not export; for the 10.4 target that list must be empty,
# which is what makes the binary launch on Tiger.
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
TARGET: powerpc-apple-darwin8
SDKROOT: /usr/local/MacOSX10.5.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-latest
timeout-minutes: 60
container:
image: ghcr.io/variantxyz/gcc-powerpc-apple-darwin8:build-gcc-14.2-MacOSXSDK10.5
options: --user root
strategy:
fail-fast: false
matrix:
deployment_target: ["10.4", "10.5"]
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target }}
steps:
- uses: actions/checkout@v4
- name: Configure
run: |
$TARGET-gcc --version | head -n 1
./configure --host=$TARGET \
--disable-qt --disable-sdl --disable-sdl2 --disable-ffmpeg \
--disable-x11 --disable-wayland --disable-egl \
--disable-pulse --disable-alsa --disable-jack --disable-oss \
--disable-udev --disable-v4l2 --disable-libusb \
--disable-freetype --disable-flac --disable-discord \
--disable-translate --disable-microphone --disable-avf \
--disable-mfi --disable-slang --disable-spirv_cross \
--disable-glslang --disable-crtswitchres --disable-al \
--disable-cdrom
- name: Compile RA
run: |
make ARCH=ppc -j$(getconf _NPROCESSORS_ONLN)
file retroarch
$TARGET-otool -l retroarch | grep -A2 LC_VERSION_MIN_MACOSX
- name: Audit imports against the 10.4u SDK
if: matrix.deployment_target == '10.4'
run: |
set -e
cd /usr/local
wget -q https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX10.4u.sdk.tar.xz
tar xJf MacOSX10.4u.sdk.tar.xz && rm MacOSX10.4u.sdk.tar.xz
cd "$GITHUB_WORKSPACE"
SDK4=/usr/local/MacOSX10.4u.sdk
$TARGET-nm -u retroarch | sed 's/^ *//' | sort -u > undef.txt
( find $SDK4/usr/lib -name '*.dylib' ; \
find $SDK4/System/Library/Frameworks -type f -path '*/Versions/*' ! -path '*/Headers/*' ! -path '*/Resources/*' ) \
| while read -r lib; do $TARGET-nm -g -arch ppc "$lib" 2>/dev/null | awk 'NF==3 {print $3} NF==2 {print $2}'; done \
| sort -u > sdk4.txt
echo "Imports absent from the 10.4u SDK:"
comm -23 undef.txt sdk4.txt | grep -v '^_OBJC_CLASS_\$_\|^\.objc_class_name_' | tee missing.txt
test ! -s missing.txt
- 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-macOS-ppc-${{ matrix.deployment_target }}-${{ steps.slug.outputs.sha8 }}
path: retroarch
-48
View File
@@ -1,48 +0,0 @@
name: CI macOS
on:
push:
branches: [master]
pull_request:
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: macos-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v6
- name: Cocoa companion harness on Apple's AppKit
run: |
set -o pipefail
# The same harness the Linux job runs under GNUstep, built with
# Apple's clang against the real Cocoa framework and run on the
# runner's window server: key-window arbitration after closing the
# companion, the grid, the tables, the dialogs - as AppKit does them.
tools/companion_cocoa_test_macos.sh 2>&1 | grep -v "^$"
- name: Compile RA
run: |
set -o pipefail
xcodebuild -workspace pkg/apple/RetroArch.xcworkspace -scheme RetroArch -config Release -xcconfig pkg/apple/GitHubCI.xcconfig -derivedDataPath build
- name: Get short SHA
id: slug
run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v6
with:
name: RetroArch-${{ steps.slug.outputs.sha8 }}
path: |
build/Build/Products/Release
-44
View File
@@ -1,44 +0,0 @@
name: CI Miyoo ARM32
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-dingux:latest
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile RA
run: |
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.miyoo clean
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.miyoo info all
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: retroarch_miyoo_arm32${{ steps.slug.outputs.sha8 }}
path: |
retroarch
-110
View File
@@ -1,110 +0,0 @@
name: CI msg_hash packed tables
# intl/msg_hash_<lang>.h is generated as two objects that are paired by
# position: the blob struct holds every row as one run of NUL-terminated
# strings, and ids[] names the enum each row belongs to.
# msg_hash_strtab_index_build() walks the blob once and hands row N to
# ids[N].
#
# Nothing in the C ties them together. Both objects are well formed on
# their own, and the sizeof() contiguity check inside the header only
# measures the blob against itself, so a row removed from one side and
# left on the other compiles clean everywhere and renames every row
# after it at runtime. The menu then shows real translated strings
# belonging to other entries - which is what #19534 reported, in every
# language at once. English is unaffected, because msg_hash_us.c is a
# switch rather than a packed table, so no English-language test, manual
# or automated, can see it either.
#
# 5d0f721 did exactly that: retiring audio_block_frames took
# MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES and its sublabel out of ids[]
# in twenty-nine headers and left the two blob members behind. From the
# audio device row onward every language was off by one or two.
#
# The check re-derives the pairing from the member names - json2h.py
# names each member after the djb2 hash of the key its row was emitted
# for - and compares it against ids[] row for row, under the guards. It
# reads the files rather than building them, so it covers every
# language and every #ifdef configuration at once, which no build job
# does. intl/json2h.py runs the same check on its own output before
# writing, so this is the lane that catches a header edited by hand.
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:
msg-hash-packed-check:
name: blob and ids[] pairing
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Checker self-test
shell: bash
run: |
set -eu
# Fixture pass: a consistent table is clean, 5d0f721's shape
# (a row dropped from ids[] only) is caught, so is its mirror,
# a member one byte wider than its string, a guard present on
# one side only, and a contiguity constant left stale.
#
# The fixtures are built by the checker rather than lifted
# from intl/, so this reports the same thing whether or not
# the shipped headers currently pass - it is measuring the
# checker, not the tree.
python3 tools/msg_hash_packed_check.py --selftest
- name: Tree check
shell: bash
run: |
set -eu
# Every packed header: row N's member name must be what the
# key in ids[N] hashes to and carry the same guard, each
# member must be exactly its string plus the NUL (or exactly
# 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.
python3 tools/msg_hash_packed_check.py
- name: Format parity self-test
shell: bash
run: |
set -eu
# Fixture pass: matching conversions are clean, a conversion
# lost, invented, retyped or reordered positionally is caught,
# and a percent sign in prose - English's "50% of this value",
# Hungarian's "50%-a", a doubled %% - is not mistaken for one.
# The format-site scan is measured too: it must see a format
# 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.
python3 tools/msg_hash_format_check.py --selftest
- name: Format parity tree check
shell: bash
run: |
set -eu
# Every translated row against its English source: the same
# conversions in the same order wherever English has any, no
# positional %n$ anywhere, and no conversion invented in a row
# that is used as a format string and has none in English.
# 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_*.
python3 tools/msg_hash_format_check.py
-54
View File
@@ -1,54 +0,0 @@
name: CI Overlapping-buffer copies
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:
overlap-copy-check:
name: Overlapping dst/src in copy calls
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Checker self-test
shell: bash
run: |
set -eu
# Fixture pass: exact-alias strlcpy and overlapping memcpy
# element shifts are flagged, memmove is not, unguarded
# param->param copy helpers called with aliased buffers are
# flagged while alias-guarded helpers are not, the
# allowlist suppresses audited same-base copies but can
# never suppress an exact alias, and stale allowlist
# entries are reported.
python3 tools/overlap_copy_check.py --selftest
- name: Tree check
shell: bash
run: |
set -eu
# strlcpy resolves to the fortified __strlcpy_chk on macOS,
# which aborts on ANY dst/src overlap (bd79aee: typing into
# the OSK crashed with EXC_BREAKPOINT), and overlapping
# memcpy is UB everywhere (e942ee2: leaderboard element
# shift). The portable strlcpy fallback tolerates aliasing
# 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.
python3 tools/overlap_copy_check.py
-50
View File
@@ -1,50 +0,0 @@
name: CI PS2
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-ps2:latest
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile Salamander
run: |
make -f Makefile.ps2.salamander -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.ps2.salamander -j$(getconf _NPROCESSORS_ONLN) release
- name: Compile RA
run: |
make -f Makefile.ps2 -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.ps2 -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info release
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: RA-PS2-dummy-${{ steps.slug.outputs.sha8 }}
path: |
raboot.elf
retroarchps2.elf
-50
View File
@@ -1,50 +0,0 @@
name: CI PS3/PSL1GHT
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-psl1ght:latest
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile Salamander
run: |
make -f Makefile.psl1ght.salamander -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.psl1ght.salamander -j$(getconf _NPROCESSORS_ONLN)
- name: Compile RA
run: |
make -f Makefile.psl1ght -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.psl1ght -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: RA-psl1ght-dummy-${{ steps.slug.outputs.sha8 }}
path: |
retroarch_psl1ght_salamander.elf
retroarch_psl1ght.elf
-57
View File
@@ -1,57 +0,0 @@
name: CI PS4/ORBIS
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-orbis:latest
options: --user root
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
apk add ncurses-dev make bash python2
apk add libintl icu-dev wget
wget https://dot.net/v1/dotnet-install.sh && chmod 755 dotnet-install.sh && ./dotnet-install.sh -c 3.0 --install-dir ~/cli
- name: Compile RA
run: |
export PATH=~/cli:$PATH # .net cli
make -f Makefile.orbis -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: bin-${{ steps.slug.outputs.sha8 }}
path: |
retroarch_orbis.elf
retroarch_orbis.oelf
retroarch_orbis.self
- name: Version of binaries
run: |
clang --version
orbis-ld --version
-56
View File
@@ -1,56 +0,0 @@
name: CI PSP
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-psp:latest
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile bootstrap
run: |
cd bootstrap/psp1/kernel_functions_prx
make -j$(getconf _NPROCESSORS_ONLN) clean
make -j$(getconf _NPROCESSORS_ONLN)
- name: Compile Salamander
run: |
make -f Makefile.psp1.salamander -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.psp1.salamander -j$(getconf _NPROCESSORS_ONLN)
- name: Compile RA
run: |
make -f Makefile.psp1 -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.psp1 -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)"
- uses: actions/upload-artifact@v4
with:
name: RA-PSP-dummy-${{ steps.slug.outputs.sha8 }}
path: |
kernel_functions.prx
EBOOT.PBP
-48
View File
@@ -1,48 +0,0 @@
name: CI PSVita
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-vita:latest-20260905
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile Salamander
run: |
make -f Makefile.vita.salamander -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.vita.salamander -j$(getconf _NPROCESSORS_ONLN)
- name: Compile RA
run: |
make -f Makefile.vita -j$(getconf _NPROCESSORS_ONLN) clean
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)"
- uses: actions/upload-artifact@v4
with:
name: RA-PSVita-dummy-${{ steps.slug.outputs.sha8 }}
path: |
eboot.bin
@@ -1,85 +0,0 @@
name: CI RGUI pixel format
# RGUI draws into a 16bpp framebuffer, so every menu colour, wallpaper
# and thumbnail pixel passes through one of the argb32_to_* converters
# in menu/drivers/rgui.c. Each one quantises the four 8-bit channels
# to its target widths and ORs them into their fields, with the widths
# and the shifts written by hand on separate lines - seven formats,
# fourteen driver idents, and a dithered twin of each.
#
# Nothing else in CI can see a mistake there. The formats are
# per-platform: rgb565 belongs to sdl_dingux, sdl_rs90 and xvideo, and
# no runner boots a 565 menu, so a converter can be wrong for months
# while every desktop build renders perfectly. It is not a build
# break either - a width that outgrows its shift just ORs into the
# neighbouring field, silently.
#
# c6b66c9 did exactly that: it widened green in argb32_to_rgb565 from
# 5 bits to 6 but left the packing at (g << 6), where 6-bit green
# needs (g << 5). Green's top bit landed on red's LSB, the green
# field became (g & 31) << 1, and green wrapped hard at half scale -
# mid grey rendered as (139, 0, 131). It shipped, and came back as
# #19469, bisected by hand on an Anbernic RG300X.
#
# The check lifts the marked pixel format conversion block out of
# rgui.c and compiles it on its own against two stubs, so it tests the
# real shipped converters and the real dispatch table. Field layouts
# are measured from the converters, not hardcoded, so a new format
# gets checked the moment its row is added to rgui_pixel_format_map.
on:
push:
paths:
- 'menu/drivers/rgui.c'
- 'tools/rgui_pixfmt_check.py'
- '.github/workflows/RGUI-Pixel-Format-Check.yml'
pull_request:
paths:
- 'menu/drivers/rgui.c'
- 'tools/rgui_pixfmt_check.py'
- '.github/workflows/RGUI-Pixel-Format-Check.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:
rgui-pixfmt-check:
name: RGUI 8-bit to 16bpp conversion contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Checker self-test
shell: bash
run: |
set -eu
# Fixture pass: the corrected 6-bit green packed at <<5
# passes, c6b66c9's same green packed at <<6 is caught as a
# red/green overlap, and a table row wired to another
# format's dithered twin is caught as a reach mismatch.
#
# Both green fixtures are made by forcing the packing shift
# 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.
python3 tools/rgui_pixfmt_check.py --selftest --cc gcc
- name: Tree check
shell: bash
run: |
set -eu
# Per driver ident, and for the unknown-ident fallback: the
# bits each input channel can change must be disjoint from
# every other channel's and contiguous; 0 and 255 must give
# 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.
python3 tools/rgui_pixfmt_check.py --cc gcc
-44
View File
@@ -1,44 +0,0 @@
name: CI RS90 Odbeta MIPS32
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-dingux:odbeta
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile RA
run: |
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.rs90 clean
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.rs90 info all
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: retroarch_rs90_mips32${{ steps.slug.outputs.sha8 }}
path: |
retroarch_rs90_odbeta.opk
-44
View File
@@ -1,44 +0,0 @@
name: CI RetroFW MIPS32
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-dingux:odbeta
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile RA
run: |
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.retrofw clean
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.retrofw info all
- name: Get short SHA
id: slug
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
- uses: actions/upload-artifact@v4
with:
name: retroarch_retrofw_mips32${{ steps.slug.outputs.sha8 }}
path: |
retroarch_retrofw.opk
-53
View File
@@ -1,53 +0,0 @@
name: CI Generate Source Only Tarball
# Trigger whenever a release and/or is created
on:
release:
types:
- created
push:
tags:
- "v*.*"
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
jobs:
build:
name: build
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v5
with:
submodules: recursive
- name: archive
id: archive
run: |
VERSION=${GITHUB_REF##*/}
test -z "$VERSION" && VERSION=${{ github.event.release.tag_name }}
VERSION=$(printf "%s\n" "$VERSION" | sed 's/^v//')
PKGNAME="retroarch-sourceonly-$VERSION"
mkdir -p /tmp/$PKGNAME
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
find $PKGNAME/ -type f -name '*.dylib' -delete || true
find $PKGNAME/ -type f -name '*.so.*' -delete || true
find $PKGNAME/ -type f -name '*.dll' -delete || true
TARBALL=$PKGNAME.tar.xz
tar cJf $TARBALL $PKGNAME
echo "tarball=$TARBALL" >> $GITHUB_OUTPUT
- name: upload tarball
uses: softprops/action-gh-release@v2
with:
files: ${{ steps.archive.outputs.tarball }}
-43
View File
@@ -1,43 +0,0 @@
name: CI Switch/libnx
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-libnx-devkitpro:v4-10-0
options: --user root
steps:
- uses: actions/checkout@v4
- name: Compile RA
run: |
make -f Makefile.libnx -j$(getconf _NPROCESSORS_ONLN) clean
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)"
- uses: actions/upload-artifact@v4
with:
name: RA-libnx-dummy-${{ steps.slug.outputs.sha8 }}
path: |
retroarch_switch.nro
-39
View File
@@ -1,39 +0,0 @@
name: CI Wii
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-devkitpro:latest
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Compile Salamander
run: |
make -f Makefile.wii.salamander -j$(getconf _NPROCESSORS_ONLN) clean
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
make -f Makefile.wii -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1 info all
-39
View File
@@ -1,39 +0,0 @@
name: CI WiiU
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-wiiu:latest
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Compile Salamander
run: |
make -f Makefile.wiiu -j$(getconf _NPROCESSORS_ONLN) SALAMANDER_BUILD=1 clean
make -f Makefile.wiiu -j$(getconf _NPROCESSORS_ONLN) SALAMANDER_BUILD=1
- name: Compile RA
run: |
make -f Makefile.wiiu -j$(getconf _NPROCESSORS_ONLN) clean
make -f Makefile.wiiu -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
-50
View File
@@ -1,50 +0,0 @@
name: CI Windows ARM64 (MSVC)
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
msvc:
runs-on: windows-11-arm
timeout-minutes: 90
strategy:
matrix:
version: [2022]
configuration: [Debug, Release]
platform: [ARM64]
steps:
- uses: actions/checkout@v5
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1
- 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: |
pkg/msvc/${{ matrix.platform }}/${{ matrix.configuration }}/RetroArch-msvc${{ matrix.version }}.exe
-36
View File
@@ -1,36 +0,0 @@
name: CI Windows i686 (MXE)
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-mxe-win32-cross:gcc10
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Compile RA
run: |
export MOC=/usr/lib/mxe/usr/i686-w64-mingw32.shared/qt5/bin/moc
./configure --host=i686-w64-mingw32.shared
make clean
make -j$(getconf _NPROCESSORS_ONLN)
-100
View File
@@ -1,100 +0,0 @@
name: CI Windows (memmap area)
# The fastmem window's reservation has two implementations and a Windows
# runner only ever exercises one of them. From Windows 10 1803 the area is
# a placeholder that mapping splits and unmapping coalesces; below that --
# back to Windows 2000 -- it is one reservation per allocation-granularity
# slot, released and mapped over one slot at a time. Every hosted runner is
# far past 1803, so the legacy path never runs unless it is asked for, and
# MEMSHM_AREA_FORCE_LEGACY is how it is asked for.
#
# It is worth running because its failures are quiet. A placeholder split
# that loses a range, or a slot released and not put back, does not crash:
# it maps the wrong memory, or maps nothing and lets a later map land
# somewhere else. A core with a guest RAM behind that reads and writes the
# wrong addresses.
on:
push:
branches: [master]
paths:
- 'libretro-common/memmap/**'
- 'libretro-common/include/memmap.h'
- 'libretro-common/samples/memmap/**'
- '.github/workflows/Windows-memmap-area.yml'
pull_request:
paths:
- 'libretro-common/memmap/**'
- 'libretro-common/include/memmap.h'
- 'libretro-common/samples/memmap/**'
- '.github/workflows/Windows-memmap-area.yml'
repository_dispatch:
types: [run_build]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
area:
runs-on: windows-2022
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
# The path this runner takes on its own.
- name: placeholders
defines: ''
# And the one every Windows before 10 1803 takes.
- name: legacy
defines: '-DMEMSHM_AREA_FORCE_LEGACY'
name: ${{ matrix.name }}
steps:
- uses: actions/checkout@v5
- name: Report the runner's Windows build
shell: powershell
run: |
$v = [System.Environment]::OSVersion.Version
Write-Host "Windows $($v.Major).$($v.Minor) build $($v.Build)"
if ($v.Build -lt 17134) {
Write-Host "::notice::Runner predates 10 1803; the placeholder job tests the legacy path too"
}
# vcvarsall through vswhere, which ships with every Visual Studio and
# needs no third-party action: this repo uses only
# microsoft/setup-msbuild, and one job is not a reason to add
# another dependency to the supply chain.
- name: Build the area sample
shell: cmd
run: |
for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set VSPATH=%%i
if not defined VSPATH exit /b 1
call "%VSPATH%\VC\Auxiliary\Build\vcvars64.bat"
cd libretro-common\samples\memmap\memshm_area_test
cl /nologo /W3 /WX /I..\..\..\include ${{ matrix.defines }} ^
memshm_area_test.c ..\..\..\memmap\memmap.c ^
/Fe:memshm_area_test.exe
if errorlevel 1 exit /b 1
# The sample's own exit code covers the assertions. This also fails
# a run that reported no area at all: that is a pass for a platform
# which cannot have one, and a silent no-op on a runner that can.
- name: Run it, and fail if the area was skipped
shell: powershell
run: |
cd libretro-common\samples\memmap\memshm_area_test
$out = & .\memshm_area_test.exe | Out-String
Write-Host $out
if ($out -match 'skipped') {
Write-Error "no area on a runner that must be able to provide one"
exit 1
}
if ($out -notmatch 'memshm area: ok') {
Write-Error "the sample did not report ok"
exit 1
}
-36
View File
@@ -1,36 +0,0 @@
name: CI Windows x64 (MXE)
on:
push:
branches: [master]
pull_request:
repository_dispatch:
types: [run_build]
permissions:
contents: read
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
container:
image: reallibretroretroarch/libretro-build-mxe-win64-cross:gcc10
options: --user root
steps:
- uses: taiki-e/checkout-action@v1
- name: Compile RA
run: |
export MOC=/usr/lib/mxe/usr/x86_64-w64-mingw32.shared/qt5/bin/moc
./configure --host=x86_64-w64-mingw32.shared
make clean
make -j$(getconf _NPROCESSORS_ONLN)
-46
View File
@@ -1,46 +0,0 @@
# Download translations from Crowdin and push to GitHub
name: Crowdin Daily Workflow
on:
schedule:
- cron: '0 0 * * *' # every day at midnight
permissions:
contents: read
jobs:
sync:
permissions:
contents: write # for Git to git push
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Setup Java JDK
uses: actions/setup-java@v4
with:
java-version: 18
distribution: zulu
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Checkout
uses: actions/checkout@v5
- name: Crowdin Sync
shell: bash
env:
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
run: |
cd intl
python3 -m pip install requests PyYAML
python3 crowdin_sync.py "$CROWDIN_API_KEY"
git config user.name github-actions
git config user.email [email protected]
git add .
if git diff --cached --quiet; then
echo "No translation changes to commit."
else
git commit -m "Fetch translations from Crowdin"
git push
fi
+4 -11
View File
@@ -10,25 +10,18 @@ on:
- 'intl/*_us.h'
- 'intl/*_us.json'
permissions:
contents: read
jobs:
sync:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Setup Java JDK
uses: actions/setup-java@v4
uses: actions/setup-java@v1
with:
java-version: 18
distribution: zulu
java-version: 1.8
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
uses: actions/setup-python@v2
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v2
- name: Crowdin Sync
shell: bash
env:
-32
View File
@@ -1,32 +0,0 @@
name: CI iOS (13)
on:
push:
branches: [master]
pull_request:
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: macos-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v6
- name: Compile RA
run: |
set -o pipefail
xcodebuild -workspace pkg/apple/RetroArch.xcworkspace -destination generic/platform=iOS -config Release \
-scheme "RetroArch iOS Release" -xcconfig pkg/apple/GitHubCI.xcconfig \
CODE_SIGNING_ALLOWED=NO \ CODE_SIGNING_REQUIRED=NO \ CODE_SIGN_IDENTITY="" \ PROVISIONING_PROFILE_SPECIFIER="" \
-derivedDataPath build
-58
View File
@@ -1,58 +0,0 @@
# Validates compilation of RetroArch binary
name: RetroArch CI
on:
push:
branches:
- master
pull_request:
branches:
- master
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-c89: # Smoketest build using most restrictive compiler and default options
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Dependencies
timeout-minutes: 5
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
sudo apt-get install -y \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
$pkgs
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: ./configure
- name: Build
run: make C89_BUILD=1
- name: Build Debug
run: |
make clean # making sure we don't have leftovers from previous build
make DEBUG=1 GL_DEBUG=1 C89_BUILD=1 info all
-412
View File
@@ -1,412 +0,0 @@
#!/bin/sh
# Compile the translation units whose contents depend on which codecs or
# which platform a build selects, across the combinations real builds
# actually use.
#
# The ordinary CI jobs each build one configuration, so a file that
# compiles for the configuration they build is green even when it cannot
# compile for a console's. This has broken the tree: giving WAV a
# streaming mixer type made it a user of machinery guarded on the
# compressed codecs, which every desktop build has and Wii U - WAV and
# nothing else - does not. Nothing caught it until the console job ran.
#
# Nothing here links or runs; it is a syntax and declaration check, which
# is the class of breakage this is for.
set -e
cd "$(dirname "$0")/../../.."
CC=${CC:-gcc}
INC="-I. -Ilibretro-common/include -Ideps -Ideps/rcheevos/include -Iinput/include"
WARN="-Wall -Wno-unused-function -Werror=implicit-function-declaration"
BASE="-DRARCH_INTERNAL -DHAVE_AUDIOMIXER -DHAVE_THREADS -DHAVE_CONFIGFILE -DHAVE_MENU"
fail=0
check() {
name="$1"; shift
defs="$1"; shift
bad=0
for tu in "$@"; do
if ! out=$($CC $WARN $INC $BASE $defs -fsyntax-only "$tu" 2>&1); then
echo "FAIL $name"
echo " $tu"
echo "$out" | sed 's/^/ /' | head -12
fail=1; bad=1
fi
done
[ "$bad" = 1 ] || echo "ok $name"
}
AUDIO="libretro-common/formats/audio_transfer.c libretro-common/audio/audio_mixer.c"
echo "== audio codec combinations =="
# the sets real platform makefiles select, plus each codec alone and none
check "wav only (ctr/psp/wiiu)" "-DHAVE_RWAV" $AUDIO
check "wav+mod (gx/ngc/wii)" "-DHAVE_RWAV -DHAVE_RMODTRACKER" $AUDIO
check "mod+vorbis (emscripten)" "-DHAVE_RMODTRACKER -DHAVE_RVORBIS" $AUDIO
check "wav+vorbis (vita)" "-DHAVE_RWAV -DHAVE_RVORBIS" $AUDIO
check "wav+vorbis+mp3+mod (nx)" "-DHAVE_RWAV -DHAVE_RVORBIS -DHAVE_RMP3 -DHAVE_RMODTRACKER" $AUDIO
check "mod+mp3+vorbis (dos)" "-DHAVE_RMODTRACKER -DHAVE_RMP3 -DHAVE_RVORBIS" $AUDIO
check "vorbis only" "-DHAVE_RVORBIS" $AUDIO
check "flac only" "-DHAVE_RFLAC" $AUDIO
check "mp3 only" "-DHAVE_RMP3" $AUDIO
check "mod only" "-DHAVE_RMODTRACKER" $AUDIO
check "aac only" "-DHAVE_RAAC" $AUDIO
check "aac+mp4" "-DHAVE_RAAC -DHAVE_RMP4" $AUDIO
check "opus only" "-DHAVE_ROPUS" $AUDIO
check "opus+webm" "-DHAVE_ROPUS -DHAVE_RWEBM" $AUDIO
check "no codecs" "" $AUDIO
check "everything" \
"-DHAVE_RWAV -DHAVE_RVORBIS -DHAVE_RFLAC -DHAVE_RMP3 -DHAVE_RMODTRACKER -DHAVE_RAAC -DHAVE_ROPUS -DHAVE_RMP4 -DHAVE_RWEBM" \
$AUDIO
# mem_stats selects one platform backend out of a dozen, and its includes
# and its bodies must both follow that one choice. When they were two
# separate chains, a platform matching an early arm while still defining
# __unix__ - Orbis and Emscripten do, and DJGPP does - got its own arm's
# includes and a different arm's code, and three console jobs failed on
# symbols the arm had never included a header for.
#
# The SDK headers are not here, so an arm whose header is missing cannot
# be compiled. What can be checked anywhere is that the only thing it
# complains about is that header: a diagnostic naming a symbol that
# belongs to some other arm means the chains have drifted apart again.
echo
echo "== mem_stats platform arms =="
# The SDKs are not on a runner, so each arm is compiled against a stub
# header supplying only the handful of symbols that arm names. That does
# not prove the real SDK matches the stub - it proves the arm's own code
# is well formed and that every symbol it uses is one it has arranged to
# have. Three console failures reached CI as missing or wrong headers -
# 3ds.h absent, gccore.h guessed, SYSMEM1_SIZE taken from the SDK when
# it is RetroArch's own - and each would have shown up here.
STUBS="$(dirname "$0")/stubs"
# host headers are the real ones and deprecate things the target's do not
ARMWARN="$WARN -Wno-deprecated-declarations"
# A platform's own video driver, which the arm lanes above do not reach:
# they check that one file's headers resolve, not that the driver a
# console actually draws with still compiles. Settings a driver reads
# while answering the frontend have moved into the frame descriptor more
# than once, and each time these drivers were the ones left behind -
# nothing in CI compiles them.
#
# @extra carries whatever headers the driver needs that the runner has;
# a lane whose headers are absent says so and is not a failure.
platform_video() {
name="$1"; defs="$2"; extra="$3"; tu="$4"; probe="$5"
if [ -n "$probe" ] && [ ! -f "$probe" ]; then
echo "skip $name (no $probe)"
return
fi
if ! out=$($CC $WARN $extra $INC $BASE $defs -fsyntax-only "$tu" 2>&1); then
echo "FAIL $name"
echo " $tu"
printf '%s\n' "$out" | sed 's/^/ /' | head -10
fail=1
else
echo "ok $name"
fi
}
arm() {
name="$1"; stub="$2"; defs="$3"
inc="$INC"
[ -n "$stub" ] && inc="-I$STUBS/$stub $INC"
if ! out=$($CC $ARMWARN $inc $defs -fsyntax-only \
libretro-common/memory/mem_stats.c 2>&1); then
echo "FAIL $name"
printf '%s\n' "$out" | sed 's/^/ /' | head -8
fail=1
elif [ -n "$out" ]; then
echo "FAIL $name (warnings)"
printf '%s\n' "$out" | sed 's/^/ /' | head -6
fail=1
else
echo "ok $name"
fi
}
arm "3ds" ctr "-D_3DS"
arm "gamecube" gx "-DGEKKO"
arm "wii" gx "-DGEKKO -DHW_RVL"
arm "vita" "" "-DVITA"
arm "switch" libnx "-DHAVE_LIBNX"
arm "orbis" orbis "-DORBIS"
arm "ps3" ps3 "-D__PSL1GHT__ -DHAVE_MEMINFO"
arm "ps2" "" "-DPS2"
arm "emscripten" emscripten "-D__EMSCRIPTEN__"
platform_video "odroidgo2 video" \
"-DHAVE_ODROIDGO2 -DHAVE_OPENGL -DHAVE_GLSL" "" \
gfx/drivers/gl2.c ""
platform_video "gx video" "-DGEKKO -DHW_RVL" "-I$STUBS/gx" \
gfx/drivers/gx_gfx.c ""
platform_video "switch video" \
"-DHAVE_LIBNX -DSWITCH -D__SWITCH__" "-I$STUBS/libnx" \
gfx/drivers/switch_nx_gfx.c ""
platform_video "dingux video" "-DDINGUX" "-I/usr/include/SDL" \
gfx/drivers/sdl_dingux_gfx.c /usr/include/SDL/SDL.h
platform_video "rs90 video" "-DDINGUX -DRS90" "-I/usr/include/SDL" \
gfx/drivers/sdl_rs90_gfx.c /usr/include/SDL/SDL.h
arm "win32" win32 "-D_WIN32 -D_WIN32_WINNT=0x0600"
arm "win32-old" win32 "-D_WIN32 -D_WIN32_WINNT=0x0400"
arm "macos" apple "-D__APPLE__"
arm "ios" apple "-D__APPLE__ -DTARGET_OS_IPHONE=1"
arm "dos/djgpp" "" "-D__DJGPP__ -D__unix__"
arm "linux" "" ""
# The video drivers and the threaded wrapper compile under more than
# one API and one threading model, and the desktop job builds one of
# each. The OpenGL ring's sync objects went in under a guard the
# desktop build satisfied and the GLES builds did not, and every GLES
# target - Android, Emscripten, Vita, PS4 - went red at once; a
# threadless build had been broken for longer than anyone noticed, on
# calls that compile against a prototype and fail only at link.
# These lanes are the ones a desktop build does not exercise.
echo
echo "== video drivers: API and threading combinations =="
GLINC="-Igfx/include"
GLDEFS="-DHAVE_OPENGL -DHAVE_GLSL -DHAVE_FBO -DHAVE_REWIND -DHAVE_OVERLAY"
check "gl2: GLES2 (android/emscripten/vita/ps4)" \
"$GLDEFS -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL $GLINC" gfx/drivers/gl2.c
check "gl2: GLES3" \
"$GLDEFS -DHAVE_OPENGLES -DHAVE_OPENGLES3 -DHAVE_EGL $GLINC" gfx/drivers/gl2.c
check "gl2: desktop" \
"$GLDEFS $GLINC" gfx/drivers/gl2.c
GL3DEFS="-DHAVE_OPENGL -DHAVE_OPENGL_CORE -DHAVE_SLANG -DHAVE_GLSLANG -DHAVE_SPIRV_CROSS -DHAVE_REWIND -DHAVE_OVERLAY -Ideps/SPIRV-Cross"
check "gl3: desktop" \
"$GL3DEFS $GLINC" gfx/drivers/gl3.c
check "gl3: GLES3" \
"$GL3DEFS -DHAVE_OPENGLES -DHAVE_OPENGLES3 -DHAVE_EGL $GLINC" gfx/drivers/gl3.c
# gl3 is not in the C89 job's configuration, so its C89 lane is here.
# The flags the Makefile's C89_BUILD lane uses, _GNU_SOURCE included:
# -ansi hides the C99 math names otherwise.
C89="-std=c89 -ansi -pedantic -Werror=pedantic -Werror=declaration-after-statement -Wno-long-long -Wno-variadic-macros -D_GNU_SOURCE -DC89_BUILD"
check "gl3: desktop, C89" \
"$GL3DEFS $GLINC $C89" gfx/drivers/gl3.c
check "hw ring: OpenGL only" \
"-DHAVE_OPENGL $GLINC" gfx/video_thread_hw.c
check "hw ring: GLES only" \
"-DHAVE_OPENGLES -DHAVE_OPENGLES2 $GLINC" gfx/video_thread_hw.c
check "hw ring: Vulkan only" \
"-DHAVE_VULKAN $GLINC" gfx/video_thread_hw.c
check "hw ring: no hardware API" \
"$GLINC" gfx/video_thread_hw.c
# Widget state lock: the worker draws widgets while the main thread
# writes them, and the wrapper yields the lock around its waits.
check "widgets: state lock" "$GLINC -DHAVE_GFX_WIDGETS" \
gfx/gfx_widgets.c gfx/video_thread_wrapper.c gfx/video_driver.c runloop.c
# Without threads: the wrapper is not built, and callers must compile
# against the macro stand-ins, not the wrapper's prototypes. Syntax
# only here; the link is the threadless job's.
NOTHREADS=$(echo "$BASE" | sed 's/-DHAVE_THREADS//')
check_nothreads() {
name="$1"; shift
defs="$1"; shift
bad=0
for tu in "$@"; do
if ! out=$($CC $WARN $INC $NOTHREADS $defs -fsyntax-only "$tu" 2>&1); then
echo "FAIL $name"
echo " $tu"
echo "$out" | sed 's/^/ /' | head -12
fail=1; bad=1
fi
done
[ "$bad" = 1 ] || echo "ok $name"
}
# Console rgui: the menu driver's GEKKO and DINGUX shapes have their
# own framebuffer dimensions, aspect handling and pixel converters;
# a syntax pass keeps refactors honest for both. GEKKO needs one
# tiny libogc stub header (tools/platform_stubs/gekko).
# The Android OpenSL driver compiles nowhere else; a stub SLES header
# set (tools/platform_stubs/android) keeps its lock-free write path
# and hardened teardown under a syntax gate.
# OpenAL: not in the audit build's configure. Compile-only AL stubs,
# first in the include order, so the lane needs no system
# libopenal-dev and behaves the same on every runner. Covers the
# eventcount park path (threads on).
check "audio: openal" "-Itools/platform_stubs/openal -DHAVE_AL -DHAVE_THREADS -Wdeclaration-after-statement -Werror=declaration-after-statement" audio/drivers/openal.c
# psp_audio: index-pair SPSC + eventcount park; compile-only sce
# stubs, PSP and Vita arms.
check "psp: psp_audio" "-Itools/platform_stubs/psp -DPSP -DHAVE_THREADS -Wdeclaration-after-statement -Werror=declaration-after-statement" audio/drivers/psp_audio.c
check "vita: psp_audio" "-Itools/platform_stubs/vita -DVITA -DHAVE_THREADS -Wdeclaration-after-statement -Werror=declaration-after-statement" audio/drivers/psp_audio.c
# features_cpu.c on every statically linked platform. It owns
# cpu_features_get_time_usec() and retro_sleep_until_us(); the wait's
# generic loop calls retro_sleep_us, a per-platform macro from
# retro_timers.h everywhere but Windows and Darwin, so the branch that
# only the console toolchains compile is compiled here, against
# hermetic stubs of each SDK header the file pulls. The host compiler
# predefines __linux__ and friends; a lane that keeps them takes the
# Linux branch of every #if ladder and proves nothing, so these shed
# them. PSP gets _POSIX_C_SOURCE for the host libc's nanosleep, which
# pspsdk's newlib declares unconditionally.
FCPU_TU=libretro-common/features/features_cpu.c
HOSTOFF="-U__linux__ -U__gnu_linux__ -Ulinux -U__unix__ -U__unix -Uunix"
check "features_cpu: 3ds" "$HOSTOFF -Itools/platform_stubs/ctr -D_3DS -D__3DS__ -DARM11 -DRARCH_CONSOLE" $FCPU_TU
check "features_cpu: gekko" "$HOSTOFF -Itools/platform_stubs/gekko -DGEKKO -DHW_RVL -DRARCH_CONSOLE" $FCPU_TU
check "features_cpu: wiiu" "$HOSTOFF -Itools/platform_stubs/wiiu -DWIIU -DRARCH_CONSOLE" $FCPU_TU
check "features_cpu: psp" "$HOSTOFF -Itools/platform_stubs/psp -DPSP -D_POSIX_C_SOURCE=199309L -DRARCH_CONSOLE" $FCPU_TU
check "features_cpu: vita" "$HOSTOFF -Itools/platform_stubs/vita -DVITA -DRARCH_CONSOLE" $FCPU_TU
check "features_cpu: ps3" "$HOSTOFF -Itools/platform_stubs/ps3 -D__PS3__ -DRARCH_CONSOLE" $FCPU_TU
check "features_cpu: psl1ght" "$HOSTOFF -Itools/platform_stubs/psl1ght -D__PS3__ -D__PSL1GHT__ -DRARCH_CONSOLE" $FCPU_TU
check "features_cpu: emscripten" "$HOSTOFF -Itools/platform_stubs/emscripten -D__EMSCRIPTEN__ -DEMSCRIPTEN" $FCPU_TU
# The salamander launchers link a hand-picked subset of libretro-common
# with -DIS_SALAMANDER: rtime.c for rtime_localtime, no features_cpu.c.
# A syntax pass cannot see the link error that a symbol from an
# unlinked TU produces there, so this lane links exactly that object
# set with a host main, under the Vita salamander's defines.
salamander_link() {
name="$1"; shift
defs="$1"; shift
if ! out=$($CC $WARN $INC $BASE $defs -o /tmp/salamander_link_check \
tools/platform_stubs/salamander_main.c "$@" 2>&1); then
echo "FAIL $name"
echo "$out" | sed 's/^/ /' | head -12
fail=1
else
echo "ok $name"
fi
rm -f /tmp/salamander_link_check
}
salamander_link "salamander link: rtime.c" \
"$HOSTOFF -UHAVE_THREADS -Itools/platform_stubs/vita -DVITA -DIS_SALAMANDER -DRARCH_CONSOLE" \
libretro-common/time/rtime.c
# runloop.c under Android: runloop_idle_wait's looper branch, and every
# other ANDROID block in the file, compiled against hermetic NDK stubs
# (jni, looper, native_activity, sensor, configuration, window) with
# the host identity shed.
check "android: runloop" "$HOSTOFF -DANDROID -Itools/platform_stubs/android" runloop.c
check "android: dispserv" "$HOSTOFF -DANDROID -Itools/platform_stubs/android" gfx/display_servers/dispserv_android.c
# The Android arms of rthreads: thread affinity goes to the kernel
# directly there (bionic keeps cpu_set_t behind _GNU_SOURCE), and the
# API 21 arm names pthread_gettid_np, which only bionic declares.
check "android: rthreads (API 21)" "-DHAVE_THREADS -D__ANDROID__ -D__ANDROID_API__=21 -include tools/platform_stubs/android/bionic_pthread_stub.h -Itools/platform_stubs/android" libretro-common/rthreads/rthreads.c
check "android: rthreads (API 19)" "-DHAVE_THREADS -D__ANDROID__ -D__ANDROID_API__=19 -Itools/platform_stubs/android" libretro-common/rthreads/rthreads.c
check "android: opensl" "-DANDROID -DHAVE_OPENSL -Itools/platform_stubs/android -Wdeclaration-after-statement -Werror=declaration-after-statement" audio/drivers/opensl.c
check "gekko: rgui" "-DGEKKO -DHAVE_MENU -DHAVE_RGUI -Itools/platform_stubs/gekko" menu/drivers/rgui.c
check "dingux: rgui" "-DDINGUX -DHAVE_MENU -DHAVE_RGUI" menu/drivers/rgui.c
# The streaming surface embeds a wrapper node under HAVE_THREADS and
# collapses to direct driver calls without; both shapes compile here,
# along with the thumbnail code that produces into it.
# The VP9 decoder's tile-column threading and the video streams' pooled
# colour conversion sit behind HAVE_THREADS; both shapes compile.
check "vp9/h265/video streams: threads" "-DHAVE_RVP9 -DHAVE_RVP8 -DHAVE_RWEBM -DHAVE_RMP4 -DHAVE_RH264 -DHAVE_RH265" libretro-common/formats/vp9/rvp9.c libretro-common/formats/h265/rh265.c libretro-common/formats/webm/rwebm_video.c libretro-common/formats/mp4/rmp4_video.c libretro-common/formats/image/image_blit_bands.c
check_nothreads "no threads: vp9/h265/video streams" "-DHAVE_RVP9 -DHAVE_RVP8 -DHAVE_RWEBM -DHAVE_RMP4 -DHAVE_RH264 -DHAVE_RH265" libretro-common/formats/vp9/rvp9.c libretro-common/formats/h265/rh265.c libretro-common/formats/webm/rwebm_video.c libretro-common/formats/mp4/rmp4_video.c libretro-common/formats/image/image_blit_bands.c
check "gfx_surface: threads" "$GLINC" gfx/gfx_surface.c gfx/gfx_thumbnail.c
check_nothreads "no threads: gfx_surface" "$GLINC" gfx/gfx_surface.c gfx/gfx_thumbnail.c
check_nothreads "no threads: gl2" "$GLDEFS $GLINC" gfx/drivers/gl2.c
check_nothreads "no threads: video_driver" "$GLINC" gfx/video_driver.c
check_nothreads "no threads: retroarch" "$GLINC -DHAVE_COMMAND -DHAVE_STDIN_CMD" retroarch.c
check_nothreads "no threads: audio_driver" "$GLINC" audio/audio_driver.c
check_nothreads "no threads: linux input" "$GLINC" input/common/linux_common.c
check_nothreads "no threads: widget state lock stand-ins" \
"$GLINC -DHAVE_GFX_WIDGETS" \
gfx/gfx_widgets.c gfx/widgets/gfx_widget_volume.c gfx/video_driver.c runloop.c
# The networking files carry threaded machinery of their own - the HTTP
# DNS cache's lock and condition, the task queue's - beside code that is
# compiled either way, so a broadcast or a wait written outside the
# guard is green in every job here and breaks a threadless build. That
# has happened: a DNS cache signal added to net_http_resolve(), which is
# not itself guarded, was caught by a sample rather than by this matrix.
NETDEFS="-DHAVE_NETWORKING $GLINC"
check_nothreads "no threads: net_http" "$NETDEFS" libretro-common/net/net_http.c
check_nothreads "no threads: net_socket" "$NETDEFS" libretro-common/net/net_socket.c
check_nothreads "no threads: task_http" "$NETDEFS" tasks/task_http.c
check_nothreads "no threads: cloud sync" "$NETDEFS -DHAVE_CLOUDSYNC" \
tasks/task_cloudsync.c network/cloud_sync/webdav.c
# The menu and the on-screen widgets are switched separately, so the
# frontend translation units have to hold for all four combinations of
# the two. Every lane above builds with HAVE_MENU, and the shipping jobs
# all enable one or the other, so a declaration that reaches a caller
# only through menu_driver.h or gfx_widgets.h is green everywhere and
# absent from a build with both off.
echo
echo "== menu and widget gates =="
NOMENU=$(echo "$BASE" | sed 's/-DHAVE_MENU//')
check_gates() {
name="$1"; shift
defs="$1"; shift
bad=0
for tu in "$@"; do
if ! out=$($CC $WARN $INC $NOMENU $defs -fsyntax-only "$tu" 2>&1); then
echo "FAIL $name"
echo " $tu"
echo "$out" | sed 's/^/ /' | head -12
fail=1; bad=1
fi
done
[ "$bad" = 1 ] || echo "ok $name"
}
UITU="retroarch.c runloop.c gfx/video_driver.c gfx/gfx_display.c"
UIDEFS="$GLINC -DHAVE_COMMAND -DHAVE_STDIN_CMD"
check_gates "gates: menu + widgets" "$UIDEFS -DHAVE_MENU -DHAVE_GFX_WIDGETS" $UITU
check_gates "gates: menu only" "$UIDEFS -DHAVE_MENU" $UITU
check_gates "gates: widgets only" "$UIDEFS -DHAVE_GFX_WIDGETS" $UITU
check_gates "gates: neither" "$UIDEFS" $UITU
# The optional subsystems switch independently of the menu and of each
# other, and the units that call into them are built either way. Each
# lane drops one subsystem from a fully featured build; the last drops
# all of them, which is what a minimal frontend compiles as.
ALLGATES="-DHAVE_MENU -DHAVE_GFX_WIDGETS -DHAVE_OVERLAY -DHAVE_CHEEVOS -DRC_CLIENT_SUPPORTS_HASH -DHAVE_NETWORKING -DHAVE_RUNAHEAD -DHAVE_DYNAMIC -DHAVE_DYLIB"
FETU="retroarch.c runloop.c command.c gfx/video_driver.c input/input_driver.c configuration.c tasks/task_content.c"
without() { echo "$ALLGATES" | sed "s/$1//g"; }
check_gates "gates: every subsystem" "$UIDEFS $ALLGATES" $FETU
check_gates "gates: no overlay" "$UIDEFS $(without -DHAVE_OVERLAY)" $FETU
check_gates "gates: no cheevos" "$UIDEFS $(without '-DHAVE_CHEEVOS -DRC_CLIENT_SUPPORTS_HASH')" $FETU
check_gates "gates: no networking" "$UIDEFS $(without -DHAVE_NETWORKING)" $FETU
check_gates "gates: no run-ahead" "$UIDEFS $(without -DHAVE_RUNAHEAD)" $FETU
check_gates "gates: no subsystems" "$UIDEFS" $FETU
# A subsystem's own unit is built only when its gate is on, so each is
# checked with that gate on and the user interface off: the achievement
# and netplay widgets, and the menu entries either drives, are the edges
# where a declaration goes missing.
check_gates "gates: netplay, no UI" \
"$UIDEFS -DHAVE_NETWORKING" network/netplay/netplay_frontend.c
check_gates "gates: cheevos, no UI" \
"$UIDEFS -DHAVE_CHEEVOS -DRC_CLIENT_SUPPORTS_HASH" cheevos/cheevos.c
check_gates "gates: run-ahead, no UI" \
"$UIDEFS -DHAVE_RUNAHEAD -DHAVE_DYNAMIC -DHAVE_DYLIB" runahead.c
# The builtin DSP filters are compiled only by console builds, through
# griffin, and no other job compiles them as C. Each is checked on its
# own, as the consoles build it, in the C89 lane: once with the C99 math
# names glibc declares under _GNU_SOURCE, and once without them, as on
# MSVC, so an undeclared sqrtf() or M_PI fails here.
echo
echo "== dsp filters: C89 =="
DSP=$(ls libretro-common/audio/dsp_filters/*.c)
check "dsp filters: C89" "$C89 -DHAVE_FILTERS_BUILTIN" $DSP
check "dsp filters: C89, no C99 math declarations" \
"$(echo "$C89" | sed 's/ -D_GNU_SOURCE//') -DHAVE_FILTERS_BUILTIN" $DSP
echo "== run-ahead: the dynamic-library gates =="
# The secondary instance exists only with HAVE_DYNAMIC; a build that
# can load libraries but links its core statically (HAVE_DYLIB alone)
# compiles the secondary path out and keeps the callers linking.
RADEFS="-DHAVE_REWIND -DHAVE_RUNAHEAD -DHAVE_DYNAMIC_EXTENSIONS"
check "runahead: neither" "$RADEFS" runahead.c
check "runahead: HAVE_DYLIB only" "$RADEFS -DHAVE_DYLIB" runahead.c
check "runahead: HAVE_DYNAMIC" "$RADEFS -DHAVE_DYNAMIC" runahead.c
check "runahead: both" "$RADEFS -DHAVE_DYNAMIC -DHAVE_DYLIB" runahead.c
exit $fail
@@ -1,5 +0,0 @@
# function size stack-frame (release build, x86-64 GCC)
runloop_iterate 3933 88
video_driver_frame 9447 4008
video_thread_frame 3097 152
audio_driver_sample_batch 394 24
@@ -1,81 +0,0 @@
#!/bin/sh
# The size and stack frame of the frontend's hottest functions, against
# a checked-in budget.
#
# Code size is I-cache footprint on the path that runs every frame, and
# the stack frame is what the prologue touches before any work happens.
# Neither is visible to a test: a change that doubles either passes
# every lane in the suite and shows up only as a slower frame on
# someone's machine. This is the check that notices.
#
# The numbers come from the release objects, so run it after a plain
# `make`. The budget is deliberately loose - a quarter over what the
# tree measures today - because compilers differ and the point is to
# catch a step change, not to freeze a byte count. When a change means
# to grow one of these, the reference moves with it in the same commit,
# which is exactly the moment to say why in the message.
#
# The functions, and why each is here:
# runloop_iterate the frame's orchestration
# video_driver_frame the frontend's hottest function by its
# own comment; also the largest frame
# video_thread_frame the handover, on the paced path
# audio_driver_sample_batch called once per core frame, more with
# per-sample cores
set -eu
cd "$(dirname "$0")/../../.."
ref=".github/workflows/scripts/hot-function-budget.ref"
obj="obj-unix/release"
fail=0
if [ ! -d "$obj" ]; then
echo "no release objects in $obj; run make first" >&2
exit 1
fi
measure() {
o="$1"; fn="$2"
sz=$(nm -S "$o" 2>/dev/null | grep -w "$fn" | head -1 | awk '{print $2}')
[ -n "$sz" ] || { echo "SKIP $fn (not in $o)"; return; }
size=$(printf '%d' "0x$sz")
# mawk has no strtonum(); the hex comes back as text and the shell
# converts it.
frame_hex=$(objdump -d --no-show-raw-insn "$o" 2>/dev/null | awk -v f="$fn" '
$0 ~ "<"f">:" { in_fn = 1; next }
in_fn && /^$/ { exit }
in_fn && /sub +\$0x[0-9a-f]+,%rsp/ {
match($0, /0x[0-9a-f]+/); print substr($0, RSTART + 2, RLENGTH - 2); exit }')
if [ -n "$frame_hex" ]; then
frame=$(printf '%d' "0x$frame_hex")
else
frame=0
fi
want_size=$(awk -v f="$fn" '$1 == f { print $2 }' "$ref")
want_frame=$(awk -v f="$fn" '$1 == f { print $3 }' "$ref")
[ -n "$want_size" ] || { echo "SKIP $fn (no reference)"; return; }
max_size=$(( want_size + want_size / 4 ))
max_frame=$(( want_frame + want_frame / 4 + 64 ))
status="ok "
if [ "$size" -gt "$max_size" ] || [ "$frame" -gt "$max_frame" ]; then
status="FAIL "
fail=1
fi
printf '%s %-28s size %6d (budget %6d) frame %5d (budget %5d)\n' \
"$status" "$fn" "$size" "$max_size" "$frame" "$max_frame"
}
echo "== hot function budget =="
measure "$obj/runloop.o" runloop_iterate
measure "$obj/gfx/video_driver.o" video_driver_frame
measure "$obj/gfx/video_thread_wrapper.o" video_thread_frame
measure "$obj/audio/audio_driver.o" audio_driver_sample_batch
if [ "$fail" = 1 ]; then
echo
echo "A hot function grew past its budget. If that is deliberate, move"
echo "the number in $ref in the same commit and say why."
exit 1
fi
@@ -1,15 +0,0 @@
# function bytes (release build, x86-64 GCC)
#
# Over the ceiling and left that way, each with its reason. A frame
# that is not listed here fails the sweep; one that grows past what is
# recorded fails too, and the number moves in the commit that grows it.
#
# switch_res_crt a CRT mode switch, once when the resolution
# changes, on the main thread
# spirv_cache_save shader cache written once per compiled pass,
# spirv_cache_load read once per pass at load
# gfx_anim_preview_probe probes a preview file, off the frame path
switch_res_crt 4440
spirv_cache_save 4312
spirv_cache_load 4296
gfx_anim_preview_probe 4128
@@ -1,95 +0,0 @@
#!/bin/sh
# Every stack frame in the graphics objects, against the tree's limit.
#
# CODING-GUIDELINES puts a ceiling on a function's stack frame - two
# kilobytes inside libretro-common, four outside it - because the
# threads this code runs on do not all get a desktop's stack, and a
# frame that overruns one corrupts whatever is under it rather than
# failing. Nothing checked it: the frames this sweep was written for
# were twelve kilobytes, in four font paths and an overlay batch, and
# they had been there for years.
#
# A large local array is invisible in review and to every other lane -
# it compiles, it runs on a machine with eight megabytes of stack, and
# it is only a problem on the platform with the smallest one. This is
# the check that notices.
#
# Reads the release objects, so run it after a plain `make`. Functions
# allowed to exceed the ceiling are listed in stack-frame-sweep.ref
# with the size they measure; a change that grows one moves its line in
# the same commit, which is the moment to say why in the message.
set -e
cd "$(dirname "$0")/../../.."
OBJDIR=${OBJDIR:-obj-unix/release}
ref="$(dirname "$0")/stack-frame-sweep.ref"
limit=${LIMIT:-4096}
fail=0
if [ ! -d "$OBJDIR/gfx" ]; then
echo "skip: no objects in $OBJDIR (run make first)"
exit 0
fi
# A large frame is built by repeated probes of a page at a time, so the
# allocation is the sum of the subtractions a function makes, not the
# largest one.
for o in $(find "$OBJDIR/gfx" -name '*.o' | sort); do
objdump -d --no-show-raw-insn "$o" 2>/dev/null | awk -v obj="$o" -v lim="$limit" '
/^[0-9a-f]+ <.*>:/ {
if (fn != "" && total > lim)
printf "%s %s %d\n", obj, fn, total
fn = $2; sub(/^</, "", fn); sub(/>:$/, "", fn)
total = 0
next
}
/sub +\$0x[0-9a-f]+,%rsp/ {
# The hex is not at a fixed field: the address column shifts
# them, so take it out of the line rather than by index.
line = $0
sub(/^.*sub +\$0x/, "", line)
sub(/,%rsp.*$/, "", line)
hex = line
# mawk has no strtonum(); fold the hex by hand, and ignore the
# sign-extended constants an add-by-subtract produces.
n = 0; ok = 1
for (i = 1; i <= length(hex); i++) {
c = substr(hex, i, 1)
p = index("0123456789abcdef", c)
if (p == 0) { ok = 0; break }
n = n * 16 + (p - 1)
}
if (ok && n < 4194304) total += n
next
}
END {
if (fn != "" && total > lim)
printf "%s %s %d\n", obj, fn, total
}
'
done > /tmp/stack-frame-sweep.$$ || true
echo "== stack frames over $limit bytes =="
while read -r obj fn size; do
[ -n "$fn" ] || continue
want=$(awk -v f="$fn" '$1 == f { print $2 }' "$ref" 2>/dev/null)
if [ -z "$want" ]; then
echo "FAIL $fn ($size bytes) in $(basename "$obj")"
fail=1
elif [ "$size" -gt "$want" ]; then
echo "FAIL $fn grew to $size, recorded $want"
fail=1
else
echo "ok $fn ($size bytes, recorded $want)"
fi
done < /tmp/stack-frame-sweep.$$
rm -f /tmp/stack-frame-sweep.$$
if [ "$fail" = 1 ]; then
echo
echo "A function's stack frame is over the ceiling in CODING-GUIDELINES."
echo "Move the array off the frame, or record it in $ref with why."
exit 1
fi
echo "ok nothing else over $limit bytes"
exit 0
@@ -1,9 +0,0 @@
#ifndef STUB_TC_H
#define STUB_TC_H
#ifdef __MACH__
#include <TargetConditionals.h>
#endif
#ifndef TARGET_OS_IPHONE
#define TARGET_OS_IPHONE 0
#endif
#endif
@@ -1,25 +0,0 @@
#ifndef STUB_MACH_H
#define STUB_MACH_H
/* Stands in for the SDK's umbrella header: on a real Apple SDK
* mach/mach.h reaches mach/mach_port.h, mach/task.h and the rest through
* mach/mach_interface.h, so anything that chain provides is declared
* here. A mem_stats Apple arm that starts naming a new mach symbol gets
* its declaration added to this file - not an extra #include added to
* mem_stats.c, which would then need a stub of its own and would still
* be describing this harness rather than any SDK. */
#include <stdint.h>
typedef int kern_return_t;
#define KERN_SUCCESS 0
typedef unsigned int mach_port_t;
typedef uintptr_t vm_size_t;
typedef unsigned int mach_msg_type_number_t;
typedef int *task_info_t;
#define TASK_VM_INFO 22
#define TASK_VM_INFO_COUNT 87
typedef struct { uint64_t phys_footprint; uint64_t limit_bytes_remaining; }
task_vm_info_data_t;
mach_port_t mach_task_self(void);
kern_return_t task_info(mach_port_t t, int flavor, task_info_t info,
mach_msg_type_number_t *count);
kern_return_t mach_port_deallocate(mach_port_t task, mach_port_t name);
#endif
@@ -1,14 +0,0 @@
#ifndef STUB_MACH_HOST_H
#define STUB_MACH_HOST_H
#include <mach/mach.h>
typedef int *host_info_t;
#define HOST_VM_INFO 2
#define HOST_VM_INFO_COUNT 15
typedef unsigned int natural_t;
typedef struct { natural_t free_count; natural_t inactive_count; }
vm_statistics_data_t;
mach_port_t mach_host_self(void);
kern_return_t host_page_size(mach_port_t h, vm_size_t *sz);
kern_return_t host_statistics(mach_port_t h, int flavor, host_info_t info,
mach_msg_type_number_t *count);
#endif
@@ -1,9 +0,0 @@
#ifndef STUB_SYSCTL_H
#define STUB_SYSCTL_H
#include <stddef.h>
#define CTL_HW 6
#define HW_MEMSIZE 24
#define HW_PHYSMEM 5
int sysctl(int *name, unsigned namelen, void *old, size_t *oldlen,
void *newp, size_t newlen);
#endif
@@ -1,4 +0,0 @@
#ifndef STUB_3DS_H
#define STUB_3DS_H
#include <stdint.h>
#endif
@@ -1,7 +0,0 @@
#ifndef STUB_3DS_OS_H
#define STUB_3DS_OS_H
#include <stdint.h>
typedef enum { MEMREGION_ALL = 0 } MemRegion;
uint32_t osGetMemRegionSize(MemRegion region);
uint32_t osGetMemRegionFree(MemRegion region);
#endif
@@ -1,5 +0,0 @@
#ifndef STUB_EM_HEAP_H
#define STUB_EM_HEAP_H
#include <stddef.h>
size_t emscripten_get_heap_max(void);
#endif
-372
View File
@@ -1,372 +0,0 @@
/* Stand-in for devkitPro's libogc <gccore.h>, for the GX video driver.
*
* Prototypes and values follow libogc's, so the driver's calls are
* checked as it makes them. As the note at the top of compile-matrix.sh
* says, this does not prove the real SDK matches: it proves RetroArch's
* own GX code is well formed and uses only what it has arranged to
* have. Pinning the surface here rather than fetching the SDK is
* deliberate - the 3DS driver no longer compiles against a current
* libctru, whose gspSubmitGxCommand() changed shape under it, and a
* lane that goes red when somebody else's headers move tells us
* nothing about this tree.
*/
#ifndef LIBOGC_STUB_GCCORE_H
#define LIBOGC_STUB_GCCORE_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef float f32;
typedef double f64;
typedef volatile uint8_t vu8;
typedef volatile uint16_t vu16;
typedef volatile uint32_t vu32;
typedef uint32_t lwpq_t;
typedef uint32_t lwp_t;
typedef uint32_t mutex_t;
typedef uint32_t syswd_t;
typedef struct { u32 dummy[16]; } GXFifoObj;
typedef void (*VIRetraceCallback)(u32 retraceCnt);
typedef void (*VIPositionCallback)(s16 x, s16 y);
typedef f32 Mtx[3][4];
typedef f32 Mtx44[4][4];
#define ATTRIBUTE_ALIGN(v) __attribute__((aligned(v)))
#define ATTRIBUTE_PACKED __attribute__((packed))
#define LWP_TQUEUE_NULL 0xffffffff
#define SYS_BASE_CACHED 0x80000000
#define SYS_BASE_UNCACHED 0xc0000000
/* uintptr_t, not u32: on the console a pointer is 32 bits and libogc's
* own cast is exact, while the host running this check is 64-bit and
* would lose half of one. The arithmetic is what matters here. */
#define MEM_K0_TO_K1(x) ((void*)((uintptr_t)(x) + (SYS_BASE_UNCACHED - SYS_BASE_CACHED)))
#define MEM_K1_TO_K0(x) ((void*)((uintptr_t)(x) - (SYS_BASE_UNCACHED - SYS_BASE_CACHED)))
#define VIDEO_PadFramebufferWidth(w) ((u16)(((u16)(w) + 15) & ~15))
#define VI_TVMODE(fmt, mode) (((fmt) << 2) + (mode))
typedef struct { u8 r, g, b, a; } GXColor;
typedef struct { u32 dummy[8]; } GXTexObj;
typedef struct
{
u32 viTVMode;
u16 fbWidth, efbHeight, xfbHeight;
u16 viXOrigin, viYOrigin, viWidth, viHeight;
u32 xfbMode;
u8 field_rendering, aa;
u8 sample_pattern[12][2];
u8 vfilter[7];
} GXRModeObj;
typedef enum { CONF_VIDEO_NTSC = 0, CONF_VIDEO_PAL, CONF_VIDEO_MPAL } CONFVideoMode;
#ifndef COLOR_BLACK
#define COLOR_BLACK (0x10801080)
#endif
#ifndef VI_DISPLAY_PIX_SZ
#define VI_DISPLAY_PIX_SZ 2
#endif
#ifndef VI_EURGB60
#define VI_EURGB60 5
#endif
#ifndef VI_INTERLACE
#define VI_INTERLACE 0
#endif
#ifndef VI_MAX_HEIGHT_EURGB60
#define VI_MAX_HEIGHT_EURGB60 VI_MAX_HEIGHT_NTSC
#endif
#ifndef VI_MAX_HEIGHT_MPAL
#define VI_MAX_HEIGHT_MPAL 480
#endif
#ifndef VI_MAX_HEIGHT_NTSC
#define VI_MAX_HEIGHT_NTSC 480
#endif
#ifndef VI_MAX_HEIGHT_PAL
#define VI_MAX_HEIGHT_PAL 576
#endif
#ifndef VI_MAX_WIDTH_EURGB60
#define VI_MAX_WIDTH_EURGB60 VI_MAX_WIDTH_NTSC
#endif
#ifndef VI_MAX_WIDTH_MPAL
#define VI_MAX_WIDTH_MPAL 720
#endif
#ifndef VI_MAX_WIDTH_NTSC
#define VI_MAX_WIDTH_NTSC 720
#endif
#ifndef VI_MAX_WIDTH_PAL
#define VI_MAX_WIDTH_PAL 720
#endif
#ifndef VI_MPAL
#define VI_MPAL 2
#endif
#ifndef VI_NON_INTERLACE
#define VI_NON_INTERLACE 1
#endif
#ifndef VI_NTSC
#define VI_NTSC 0
#endif
#ifndef VI_PAL
#define VI_PAL 1
#endif
#ifndef VI_PROGRESSIVE
#define VI_PROGRESSIVE 2
#endif
#ifndef VI_XFBMODE_DF
#define VI_XFBMODE_DF 1
#endif
#ifndef VI_XFBMODE_SF
#define VI_XFBMODE_SF 0
#endif
typedef struct { u32 dummy[8]; } syssram;
/* Drawing primitives libogc gives as inline functions */
static inline void GX_Position3f32(f32 x, f32 y, f32 z) { (void)x; (void)y; (void)z; }
static inline void GX_Position1x8(u8 i) { (void)i; }
static inline void GX_Color4u8(u8 r, u8 g, u8 b, u8 a) { (void)r; (void)g; (void)b; (void)a; }
static inline void GX_Color1x8(u8 i) { (void)i; }
static inline void GX_TexCoord2f32(f32 s, f32 t) { (void)s; (void)t; }
static inline void GX_TexCoord1x8(u8 i) { (void)i; }
static inline void GX_End(void) { }
void VIDEO_SetGamma(int gamma);
/* The matrix helpers the driver sets its projection up with */
void guOrtho(Mtx44 mt, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f);
void guMtxIdentity(Mtx mt);
void c_guMtxConcat(Mtx a, Mtx b, Mtx ab);
void DCFlushRange(void *startaddress, u32 len);
void DCInvalidateRange(void *startaddress, u32 len);
void guMtxRotDeg(Mtx mt, const char axis, f32 deg);
/* The threading calls libretro-common's gx_defines.h maps OS* onto */
void LWP_InitQueue(lwpq_t *queue);
void LWP_CloseQueue(lwpq_t queue);
void LWP_ThreadSignal(lwpq_t queue);
void LWP_ThreadBroadcast(lwpq_t queue);
s32 LWP_ThreadSleep(lwpq_t queue);
s32 LWP_MutexInit(mutex_t *mutex, bool use_recursive);
s32 LWP_MutexLock(mutex_t mutex);
s32 LWP_MutexTryLock(mutex_t mutex);
s32 LWP_MutexUnlock(mutex_t mutex);
s32 LWP_MutexDestroy(mutex_t mutex);
s32 LWP_CondInit(lwpq_t *cond);
s32 LWP_CondWait(lwpq_t cond, mutex_t mutex);
s32 LWP_CondDestroy(lwpq_t cond);
s32 LWP_CreateThread(lwp_t *thethread, void *(*entry)(void *),
void *arg, void *stackbase, u32 stack_size, u8 prio);
s32 LWP_JoinThread(lwp_t thethread, void **value_ptr);
void VIDEO_SetTrapFilter(bool enable);
#ifndef CONF_ASPECT_4_3
#define CONF_ASPECT_4_3 0
#endif
#ifndef GX_AF_NONE
#define GX_AF_NONE 2
#endif
#ifndef GX_ALWAYS
#define GX_ALWAYS 7
#endif
#ifndef GX_BL_INVSRCALPHA
#define GX_BL_INVSRCALPHA 5
#endif
#ifndef GX_BL_SRCALPHA
#define GX_BL_SRCALPHA 4
#endif
#ifndef GX_BM_BLEND
#define GX_BM_BLEND 1
#endif
#ifndef GX_CLAMP
#define GX_CLAMP 0
#endif
#ifndef GX_CLIP_DISABLE
#define GX_CLIP_DISABLE 1
#endif
#ifndef GX_CLR_RGBA
#define GX_CLR_RGBA 1
#endif
#ifndef GX_COLOR0A0
#define GX_COLOR0A0 4
#endif
#ifndef GX_CULL_NONE
#define GX_CULL_NONE 0
#endif
#ifndef GX_DF_NONE
#define GX_DF_NONE 0
#endif
#ifndef GX_DIRECT
#define GX_DIRECT 1
#endif
#ifndef GX_DISABLE
#define GX_DISABLE 0
#endif
#ifndef GX_ENABLE
#define GX_ENABLE 1
#endif
#ifndef GX_F32
#define GX_F32 4
#endif
#ifndef GX_FALSE
#define GX_FALSE 0
#endif
#ifndef GX_INDEX8
#define GX_INDEX8 2
#endif
#ifndef GX_LIGHTNULL
#define GX_LIGHTNULL 0x000
#endif
#ifndef GX_LINEAR
#define GX_LINEAR 1
#endif
#ifndef GX_LO_CLEAR
#define GX_LO_CLEAR 0
#endif
#ifndef GX_MAX_Z24
#define GX_MAX_Z24 0x00ffffff
#endif
#ifndef GX_MODULATE
#define GX_MODULATE 0
#endif
#ifndef GX_NEAR
#define GX_NEAR 0
#endif
#ifndef GX_ORTHOGRAPHIC
#define GX_ORTHOGRAPHIC 1
#endif
#ifndef GX_PF_RGB8_Z24
#define GX_PF_RGB8_Z24 0
#endif
#ifndef GX_PNMTX0
#define GX_PNMTX0 0
#endif
#ifndef GX_PNMTX1
#define GX_PNMTX1 3
#endif
#ifndef GX_POS_XYZ
#define GX_POS_XYZ 1
#endif
#ifndef GX_RGBA8
#define GX_RGBA8 5
#endif
#ifndef GX_SRC_REG
#define GX_SRC_REG 0
#endif
#ifndef GX_SRC_VTX
#define GX_SRC_VTX 1
#endif
#ifndef GX_TEVSTAGE0
#define GX_TEVSTAGE0 0
#endif
#ifndef GX_TEXCOORD0
#define GX_TEXCOORD0 0x0
#endif
#ifndef GX_TEXMAP0
#define GX_TEXMAP0 0
#endif
#ifndef GX_TEX_ST
#define GX_TEX_ST 1
#endif
#ifndef GX_TF_RGB565
#define GX_TF_RGB565 0x4
#endif
#ifndef GX_TF_RGB5A3
#define GX_TF_RGB5A3 0x5
#endif
#ifndef GX_TF_RGBA8
#define GX_TF_RGBA8 0x6
#endif
#ifndef GX_TRIANGLESTRIP
#define GX_TRIANGLESTRIP 0x98
#endif
#ifndef GX_TRUE
#define GX_TRUE 1
#endif
#ifndef GX_VA_CLR0
#define GX_VA_CLR0 11
#endif
#ifndef GX_VA_POS
#define GX_VA_POS 9
#endif
#ifndef GX_VA_TEX0
#define GX_VA_TEX0 13
#endif
#ifndef GX_VTXFMT0
#define GX_VTXFMT0 0
#endif
#ifndef GX_ZC_LINEAR
#define GX_ZC_LINEAR 0
#endif
#ifndef LWP_TQUEUE_NULL
#define LWP_TQUEUE_NULL 0xffffffff
#endif
s32 CONF_GetAspectRatio(void);
s32 CONF_GetDisplayOffsetH(s8 *offset);
s32 CONF_GetEuRGB60(void);
s32 CONF_GetProgressiveScan(void);
s32 CONF_GetVideo(void);
void GX_AbortFrame(void);
void GX_Begin(u8 primitve,u8 vtxfmt,u16 vtxcnt);
void GX_BeginDispList(void *list,u32 size);
void GX_CallDispList(void *list,u32 nbytes);
void GX_ClearVtxDesc(void);
void GX_CopyDisp(void *dest,u8 clear);
void GX_DrawDone(void);
u32 GX_EndDispList(void);
void GX_Flush(void);
f32 GX_GetYScaleFactor(u16 efbHeight,u16 xfbHeight);
GXFifoObj* GX_Init(void *base,u32 size);
void GX_InitTexObj(GXTexObj *obj,void *img_ptr,u16 wd,u16 ht,u8 fmt,u8 wrap_s,u8 wrap_t,u8 mipmap);
void GX_InitTexObjFilterMode(GXTexObj *obj,u8 minfilt,u8 magfilt);
void GX_InvVtxCache(void);
void GX_InvalidateTexAll(void);
void GX_LoadPosMtxImm(Mtx mt,u32 pnidx);
void GX_LoadProjectionMtx(Mtx44 mt,u8 type);
void GX_LoadTexObj(GXTexObj *obj,u8 mapid);
void GX_PeekARGB(u16 x,u16 y,GXColor *color);
void GX_PokeARGB(u16 x,u16 y,GXColor color);
void GX_SetAlphaUpdate(u8 enable);
void GX_SetArray(u32 attr,void *ptr,u8 stride);
void GX_SetBlendMode(u8 type,u8 src_fact,u8 dst_fact,u8 op);
void GX_SetChanCtrl(s32 channel,u8 enable,u8 ambsrc,u8 matsrc,u8 litmask,u8 diff_fn,u8 attn_fn);
void GX_SetClipMode(u8 mode);
void GX_SetColorUpdate(u8 enable);
void GX_SetCopyClear(GXColor color,u32 zvalue);
void GX_SetCopyFilter(u8 aa,u8 sample_pattern[12][2],u8 vf,u8 vfilter[7]);
void GX_SetCullMode(u8 mode);
void GX_SetCurrentMtx(u32 mtx);
void GX_SetDispCopyDst(u16 wd,u16 ht);
void GX_SetDispCopyGamma(u8 gamma);
void GX_SetDispCopySrc(u16 left,u16 top,u16 wd,u16 ht);
u32 GX_SetDispCopyYScale(f32 yscale);
void GX_SetFieldMode(u8 field_mode,u8 half_aspect_ratio);
void GX_SetNumChans(u8 num);
void GX_SetNumTexGens(u32 nr);
void GX_SetPixelFmt(u8 pix_fmt,u8 z_fmt);
void GX_SetTevOp(u8 tevstage,u8 mode);
void GX_SetTevOrder(u8 tevstage,u8 texcoord,u32 texmap,u8 color);
void GX_SetViewportJitter(f32 xOrig,f32 yOrig,f32 wd,f32 ht,f32 nearZ,f32 farZ,u32 field);
void GX_SetVtxAttrFmt(u8 vtxfmt,u32 vtxattr,u32 comptype,u32 compsize,u32 frac);
void GX_SetVtxDesc(u8 attr,u8 type);
void GX_SetZMode(u8 enable,u8 func,u8 update_enable);
u32 SYS_GetArena1Size(void);
void VIDEO_ClearFrameBuffer(GXRModeObj *rmode,void *fb,u32 color);
void VIDEO_Configure(GXRModeObj *rmode);
void VIDEO_Flush(void);
u32 VIDEO_GetCurrentTvMode(void);
u32 VIDEO_GetNextField(void);
GXRModeObj * VIDEO_GetPreferredMode(GXRModeObj *mode);
u32 VIDEO_HaveComponentCable(void);
void VIDEO_Init(void);
void VIDEO_SetBlack(bool black);
void VIDEO_SetNextFramebuffer(void *fb);
VIRetraceCallback VIDEO_SetPostRetraceCallback(VIRetraceCallback callback);
void VIDEO_WaitVSync(void);
#endif
@@ -1,4 +0,0 @@
#ifndef LIBOGC_STUB_OGCSYS_H
#define LIBOGC_STUB_OGCSYS_H
#include <gccore.h>
#endif
@@ -1,54 +0,0 @@
/* Stand-in for devkitPro's libnx <switch.h>.
*
* Only what the translation units checked here name, declared with the
* shapes libnx gives them. As the note at the top of compile-matrix.sh
* says, this does not prove the real SDK matches: it proves RetroArch's
* own Switch code is well formed and that every symbol it uses is one it
* has arranged to have. That is the class of breakage these lanes are
* for - a driver naming a struct member or a setting that moved.
*/
#ifndef LIBNX_STUB_SWITCH_H
#define LIBNX_STUB_SWITCH_H
#include <stdint.h>
#include <stddef.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int32_t s32;
typedef uint32_t Result;
/* mem_stats.c */
typedef enum { InfoType_TotalMemorySize = 6, InfoType_UsedMemorySize = 7 } InfoType;
#define CUR_PROCESS_HANDLE 0xFFFF8001
#define R_SUCCEEDED(res) ((res) == 0)
#define R_FAILED(res) ((res) != 0)
Result svcGetInfo(u64 *out, u32 id, u32 handle, u64 sub);
/* The window and framebuffer the Switch video driver draws through */
typedef struct NWindow NWindow;
typedef struct
{
void *buf;
u32 stride;
} Framebuffer;
typedef enum
{
PIXEL_FORMAT_RGBA_8888 = 1
} PixelFormat;
NWindow *nwindowGetDefault(void);
Result nwindowSetDimensions(NWindow *nw, u32 width, u32 height);
Result framebufferCreate(Framebuffer *fb, NWindow *win,
u32 width, u32 height, u32 format, u32 num_fbs);
Result framebufferMakeLinear(Framebuffer *fb);
void *framebufferBegin(Framebuffer *fb, u32 *out_stride);
void framebufferEnd(Framebuffer *fb);
void framebufferClose(Framebuffer *fb);
#endif
@@ -1,5 +0,0 @@
#ifndef STUB_ORBIS_H
#define STUB_ORBIS_H
#include <stddef.h>
void get_user_mem_size(size_t *max_mem, size_t *cur_mem);
#endif
@@ -1,5 +0,0 @@
#ifndef STUB_PPU_LV2_H
#define STUB_PPU_LV2_H
int lv2syscall1_impl(int n, unsigned long a);
#define lv2syscall1(n, a) lv2syscall1_impl((n), (unsigned long)(a))
#endif
@@ -1,12 +0,0 @@
#ifndef STUB_WINDOWS_H
#define STUB_WINDOWS_H
#include <stdint.h>
typedef uint32_t DWORD;
typedef uint64_t DWORDLONG;
typedef struct { DWORD dwLength; DWORD dwMemoryLoad; DWORDLONG ullTotalPhys;
DWORDLONG ullAvailPhys; } MEMORYSTATUSEX;
typedef struct { DWORD dwLength; DWORD dwMemoryLoad; DWORD dwTotalPhys;
DWORD dwAvailPhys; } MEMORYSTATUS;
void GlobalMemoryStatusEx(MEMORYSTATUSEX *s);
void GlobalMemoryStatus(MEMORYSTATUS *s);
#endif
-217
View File
@@ -1,217 +0,0 @@
name: CI webOS
on:
push:
tags-ignore:
- '*'
branches:
- '*'
pull_request:
release:
types: [ published ]
repository_dispatch:
types: [ run_build ]
env:
PACKAGE_NAME: com.retroarch.webos
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Check Out Repo
uses: actions/checkout@v7
- name: Download ares-cli-rs
uses: robinraju/release-downloader@v1
with:
repository: "webosbrew/ares-cli-rs"
latest: true
fileName: "ares-package_*_amd64.deb"
out-file-path: "temp"
- name: Download Manifest Generator
uses: robinraju/release-downloader@v1
with:
repository: "webosbrew/dev-toolbox-cli"
latest: true
fileName: "webosbrew-toolbox-gen-manifest_*_amd64.deb"
out-file-path: "temp"
- name: Update packages
timeout-minutes: 5
run: |
for i in 1 2 3; do
sudo timeout 90 apt-get -yq update \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 && break
echo "apt-get update failed (attempt $i); retrying in 10s"
sleep 10
done
- name: Install webOS CLI
timeout-minutes: 5
run: |
sudo apt-get -yq install \
-o Acquire::Retries=3 -o Acquire::http::Timeout=30 \
./temp/ares-package_*_amd64.deb \
./temp/webosbrew-toolbox-gen-manifest_*.deb
- name: Download webOS (arm) NDK
uses: robinraju/release-downloader@v1
with:
repository: "openlgtv/buildroot-nc4"
latest: true
fileName: "arm-webos-linux-gnueabi_sdk-buildroot-x86_64.tar.gz"
out-file-path: "/tmp"
- name: Download webOS (aarch64) NDK
uses: robinraju/release-downloader@v1
with:
repository: "cscd98/buildroot-nc4"
latest: true
fileName: "aarch64-webos-linux-gnu_sdk-buildroot-x86_64.tar.gz"
out-file-path: "/tmp"
- name: Extract webOS NDKs
shell: bash
working-directory: /tmp
run: |
tar xzf arm-webos-linux-gnueabi_sdk-buildroot-x86_64.tar.gz
./arm-webos-linux-gnueabi_sdk-buildroot/relocate-sdk.sh
tar xzf aarch64-webos-linux-gnu_sdk-buildroot-x86_64.tar.gz
./aarch64-webos-linux-gnu_sdk-buildroot/relocate-sdk.sh
- name: Load RARCH_VERSION from version.all
id: version
shell: bash
run: |
RARCH_VERSION=$(grep -Po '(?<=#define PACKAGE_VERSION ")[^"]+' version.all)
echo "RARCH_VERSION=$RARCH_VERSION" >> "$GITHUB_ENV"
- name: Resolve SDL2 prebuilt archive
id: sdl2
shell: bash
run: |
URL=$(sed -n 's/^SDL2_PREBUILT_ARCHIVE *?= *//p' Makefile.webos)
echo "url=$URL" >> "$GITHUB_OUTPUT"
echo "name=$(basename "$URL")" >> "$GITHUB_OUTPUT"
- name: Cache SDL2 prebuilt
id: sdl2-cache
uses: actions/cache@v4
with:
path: /tmp/sdl2-prebuilt
key: sdl2-prebuilt-${{ steps.sdl2.outputs.name }}
- name: Download SDL2 prebuilt
if: steps.sdl2-cache.outputs.cache-hit != 'true'
shell: bash
env:
SDL2_URL: ${{ steps.sdl2.outputs.url }}
SDL2_NAME: ${{ steps.sdl2.outputs.name }}
run: |
mkdir -p /tmp/sdl2-prebuilt
curl -fsSL --retry 5 --retry-all-errors --retry-delay 5 \
--connect-timeout 30 -o "/tmp/sdl2-prebuilt/$SDL2_NAME" "$SDL2_URL"
- name: Compile RA (GLES2, no wayland legacy variant)
shell: bash
run: |
. /tmp/arm-webos-linux-gnueabi_sdk-buildroot/environment-setup
export SDK_PATH=/tmp/arm-webos-linux-gnueabi_sdk-buildroot
make -f Makefile.webos clean
make -f Makefile.webos ipk PACKAGE_NAME=${PACKAGE_NAME} ADD_SDL2_LIB=1 \
SDL2_PREBUILT_ARCHIVE="file:///tmp/sdl2-prebuilt/${SDL2_NAME}" \
-j"$(getconf _NPROCESSORS_ONLN)"
mkdir -p webos/arm
mv webos/com.retroarch.webos_${RARCH_VERSION}_arm.ipk \
webos/arm/com.retroarch.webos-legacy-gles2-no-wayland_${RARCH_VERSION}_arm.ipk
env:
DEBUG: ${{ github.event_name == 'release' && '0' || '1' }}
SDL2_NAME: ${{ steps.sdl2.outputs.name }}
- name: Upload GLES2 artifact
uses: actions/upload-artifact@v7
with:
name: com.retroarch.webos-legacy-gles2-no-wayland_${{ env.RARCH_VERSION }}_${{ github.sha }}_arm.ipk
path: webos/arm/com.retroarch.webos-legacy-gles2-no-wayland_${{ env.RARCH_VERSION }}_arm.ipk
archive: false
- name: Compile RA (default)
shell: bash
run: |
. /tmp/arm-webos-linux-gnueabi_sdk-buildroot/environment-setup
export SDK_PATH=/tmp/arm-webos-linux-gnueabi_sdk-buildroot
make -f Makefile.webos clean
bash gfx/common/wayland/generate_wayland_protos.sh
make -f Makefile.webos ipk PACKAGE_NAME=${PACKAGE_NAME} ADD_SDL2_LIB=1 \
SDL2_PREBUILT_ARCHIVE="file:///tmp/sdl2-prebuilt/${SDL2_NAME}" \
HAVE_XKBCOMMON=1 HAVE_USERLAND=1 HAVE_EGL=1 HAVE_WAYLAND=1 \
HAVE_OPENGLES3=1 HAVE_OPENGLES3_1=1 HAVE_OPENGLES3_2=1 -j"$(getconf _NPROCESSORS_ONLN)"
mkdir -p webos/arm
mv webos/com.retroarch.webos_${RARCH_VERSION}_arm.ipk \
webos/arm/com.retroarch.webos_${RARCH_VERSION}_arm.ipk
env:
DEBUG: ${{ github.event_name == 'release' && '0' || '1' }}
SDL2_NAME: ${{ steps.sdl2.outputs.name }}
- name: Upload default artifact
uses: actions/upload-artifact@v7
with:
name: com.retroarch.webos_${{ env.RARCH_VERSION }}_${{ github.sha }}_arm.ipk
path: webos/arm/com.retroarch.webos_${{ env.RARCH_VERSION }}_arm.ipk
archive: false
- name: Generate Manifest (default only)
if: github.repository == 'webosbrew/Retroarch'
shell: bash
run: |
webosbrew-gen-manifest -o webos/${PACKAGE_NAME}.manifest.json \
-p webos/arm/${PACKAGE_NAME}_${RARCH_VERSION}_arm.ipk \
-i https://github.com/webosbrew/RetroArch/raw/webos/webos/icon160.png \
-l https://github.com/webosbrew/RetroArch
- name: Compile RA (aarch64)
shell: bash
run: |
. /tmp/aarch64-webos-linux-gnu_sdk-buildroot/environment-setup
export SDK_PATH=/tmp/aarch64-webos-linux-gnu_sdk-buildroot
make -f Makefile.webos clean
bash gfx/common/wayland/generate_wayland_protos.sh
make -f Makefile.webos ipk PACKAGE_NAME=${PACKAGE_NAME} \
ADD_SDL2_LIB=0 HAVE_SDL2=0 HAVE_SDL3=1 \
HAVE_XKBCOMMON=1 HAVE_USERLAND=1 HAVE_EGL=1 HAVE_WAYLAND=1 \
HAVE_OPENGLES3=1 HAVE_OPENGLES3_1=1 HAVE_OPENGLES3_2=1 \
HAVE_WAYLAND_BACKPORT=0 HAVE_64TO32BIT_BRIDGE=1 SET_ELF_INTERPRETER=1 HAVE_UDEV=1 \
ARES_PACKAGE_ARGS="-A arm" -j"$(getconf _NPROCESSORS_ONLN)"
mkdir -p webos/aarch64
mv webos/com.retroarch.webos_${{ env.RARCH_VERSION }}_arm.ipk \
webos/aarch64/com.retroarch.webos_${{ env.RARCH_VERSION }}_aarch64.ipk
env:
DEBUG: ${{ github.event_name == 'release' && '0' || '1' }}
- name: Upload aarch64 artifact
uses: actions/upload-artifact@v7
with:
name: com.retroarch.webos_${{ env.RARCH_VERSION }}_${{ github.sha }}_aarch64.ipk
path: webos/aarch64/com.retroarch.webos_${{ env.RARCH_VERSION }}_aarch64.ipk
archive: false
- name: Release
if: github.event_name == 'release' && github.repository == 'webosbrew/Retroarch'
uses: ncipollo/release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.event.release.tag_name }}
allowUpdates: true
omitNameDuringUpdate: true
omitBody: true
omitPrereleaseDuringUpdate: true
artifacts: |
webos/arm/com.retroarch.webos_${{ env.RARCH_VERSION }}_arm.ipk
webos/arm/com.retroarch.webos-legacy-gles2-no-wayland_${{ env.RARCH_VERSION }}_arm.ipk
webos/aarch64/com.retroarch.webos_${{ env.RARCH_VERSION }}_aarch64.ipk
webos/${{ env.PACKAGE_NAME }}.manifest.json
+16 -110
View File
@@ -1,13 +1,7 @@
*.o
*.obj
*.pdb
*.exe
*.bmpobj
*.binobj
*.shbin
*.shbin.s
*.so
*.so.*
*.dll
*.a
*.elf
@@ -16,18 +10,13 @@
*.swp
*.cache
*.gcda
# clang --analyze drops a .plist report per translation unit into the
# working directory. Anchored to the repository root so the tracked
# Info.plist / ExportOptions.plist files under pkg/apple are unaffected.
/*.plist
*.lcbk
*.gcno
.tmp
.tmp.c
.tmp.cxx
.moc.h
.moc.cpp
*.log
config.log
/.project
/.externalToolBuilders/
/retroarch
@@ -36,6 +25,8 @@
/retroarch_debug.exe
/config.h
/config.mk
/tools/retroarch-joyconfig
/tools/retroarch-joyconfig.exe
*.ncb
*.sdf
*.opensdf
@@ -71,7 +62,6 @@ apple/RetroArch_iOS.xcodeproj/project.xcworkspace/*
/Cg/
/GL/
/SDL/
/SDL3/
/ffmpeg/
/freetype2/
/ft2build.h
@@ -99,15 +89,11 @@ content_video_history.lpl
saves
screenshots
autoconfig
/config
/database
config
database
overlays
playlists
states
cheats
thumbnails
docs/html
system
shaders/shaders_cg
shaders/shaders_glsl
shaders/shaders_slang
@@ -146,7 +132,6 @@ wiiu/wut/elf2rpl/elf2rpl
# CLion
/cmake-build-debug/
.run
# Android
/pkg/android/phoenix/obj/
@@ -155,12 +140,10 @@ wiiu/wut/elf2rpl/elf2rpl
/pkg/android/phoenix/bin/
/pkg/android/phoenix/gen/
/pkg/android/phoenix/local.properties
/pkg/android/phoenix/gradle.properties
/pkg/android/phoenix/.gradle
/pkg/android/phoenix/.externalNativeBuild
/pkg/android/phoenix/build
/pkg/android/phoenix-legacy/.project
/pkg/android/phoenix-jelly-bean/**/.gradle/
/pkg/android/phoenix-jelly-bean/.cxx/
# Cloned by libretro-fetch.sh
/media/assets/
@@ -169,7 +152,6 @@ wiiu/wut/elf2rpl/elf2rpl
/media/shaders_cg/
/media/libretrodb/
compile_commands.json
pkg/apple/iOS/build/
pkg/apple/build/
ui/drivers/qt/moc_*
@@ -178,26 +160,23 @@ ui/drivers/moc_*
obj-unix/
.vagrant/
# Visual Studio
/pkg/msvc/Release Cg/*.exe
/pkg/msvc/Release Cg/*.iobj
/pkg/msvc/Release Cg/*.ipdb
/pkg/msvc/Release Cg/*.pdb
/pkg/msvc/Release Cg/*.lpl
/pkg/msvc/Release Cg/*.cfg
/pkg/msvc/*.db
/pkg/msvc/.vs
/pkg/msvc/*/.vs
*.tlog
*.lastbuildstate
*.FileListAbsolute.txt
*.res
/pkg/msvc/msvc-2010/Release Cg/RetroArc.27FF7CE1.tlog/*.tlog
/pkg/msvc/msvc-2010/Release Cg/RetroArc.27FF7CE1.tlog/*.lastbuildstate
/pkg/msvc/msvc-2010/Release Cg/*.log
/pkg/msvc/msvc-2010/Release Cg/*.obj
/pkg/msvc/msvc-2010/Release Cg/*.res
/pkg/msvc/msvc-2010/Release Cg/*.pdb
retroarch.cfg
Makefile.local
pkg/msvc/**/ARM
pkg/msvc/**/ARM64
pkg/msvc/**/* Cg
pkg/msvc/**/* QT
pkg/msvc/**/* QT+CG
pkg/msvc/**/x64
# Emscripten artifacts
@@ -205,8 +184,6 @@ retroarch.js
retroarch.js.mem
*.bc
*.wasm
*.wasm.map
obj-emscripten/
# only ignore .js files in the repo root
/*.js
@@ -221,13 +198,10 @@ retroarch_switch.nro
retroarch_switch.nso
# PS2
*_irx.c
ps2/irx/*.c
*.irx
# Wayland
gfx/common/wayland/fractional-scale-v1.c
gfx/common/wayland/fractional-scale-v1.h
gfx/common/wayland/viewporter.c
gfx/common/wayland/viewporter.h
gfx/common/wayland/idle-inhibit-unstable-v1.c
gfx/common/wayland/idle-inhibit-unstable-v1.h
gfx/common/wayland/xdg-shell-unstable-v6.c
@@ -236,55 +210,9 @@ gfx/common/wayland/xdg-decoration-unstable-v1.h
gfx/common/wayland/xdg-decoration-unstable-v1.c
gfx/common/wayland/xdg-shell.c
gfx/common/wayland/xdg-shell.h
gfx/common/wayland/pointer-constraints-unstable-v1.c
gfx/common/wayland/pointer-constraints-unstable-v1.h
gfx/common/wayland/presentation-time.h
gfx/common/wayland/presentation-time.c
gfx/common/wayland/relative-pointer-unstable-v1.c
gfx/common/wayland/relative-pointer-unstable-v1.h
gfx/common/wayland/viewporter.c
gfx/common/wayland/viewporter.h
gfx/common/wayland/cursor-shape-v1.h
gfx/common/wayland/cursor-shape-v1.c
gfx/common/wayland/tablet-unstable-v2.h
gfx/common/wayland/tablet-unstable-v2.c
gfx/common/wayland/content-type-v1.h
gfx/common/wayland/content-type-v1.c
gfx/common/wayland/single-pixel-buffer-v1.h
gfx/common/wayland/single-pixel-buffer-v1.c
gfx/common/wayland/xdg-toplevel-icon-v1.h
gfx/common/wayland/xdg-toplevel-icon-v1.c
gfx/common/wayland/xdg-toplevel-tag-v1.h
gfx/common/wayland/xdg-toplevel-tag-v1.c
gfx/common/wayland/webos-foreign.c
gfx/common/wayland/webos-foreign.h
gfx/common/wayland/webos-input-manager.c
gfx/common/wayland/webos-input-manager.h
gfx/common/wayland/webos-shell.c
gfx/common/wayland/webos-shell.h
gfx/common/wayland/webos-surface-group.c
gfx/common/wayland/webos-surface-group.h
gfx/common/wayland/tearing-control-v1.h
gfx/common/wayland/tearing-control-v1.c
# samples/: built harness executables and objects. Each directory's
# test is <dir>_test; nothing built there is source.
samples/**/*_test
samples/audio/stretch/stretch_bench
samples/**/*.o
libretro-common/samples/**/*_test
!libretro-common/samples/**/*_test/
# Harness executables that are not named <dir>_test. This one had been
# committed as a built binary, which made any make clean in that
# directory show up as a deletion.
samples/audio/embedded_alsa/abi_check
samples/gfx/font_lifecycle/lifecycle
samples/gfx/font_lifecycle/lifecycle-threaded
samples/gfx/font_lifecycle/create
# libretro-common samples
libretro-common/samples/streams/rzip/rzip
libretro-common/samples/audio/audio_mixer_loop/audio_mixer_loop_test
# DINGUX
*.opk
@@ -297,25 +225,3 @@ param.sfo
*.vpk
/.vs
/deps/SPIRV-Cross/out/build/x64-Debug
# Visual Studio Code
.vscode/
# Clazy
*.clazy.yaml
# PSL1GHT
*.SELF
EBOOT.BIN
pkg/psl1ght/*.pkg
modern_alpha_blend_fpo.h
modern_alpha_blend_vpo.h
modern_opaque_fpo.h
modern_opaque_vpo.h
gfx/drivers/rsx_shaders/modern_alpha_blend.fpo
gfx/drivers/rsx_shaders/modern_alpha_blend.vpo
gfx/drivers/rsx_shaders/modern_opaque.fpo
gfx/drivers/rsx_shaders/modern_opaque.vpo
pkg/psl1ght/pkg/USRDIR/shaders_cg/
!pkg/psl1ght/pkg/USRDIR/system/
samples/audio/embedded_alsa/ealsa_abi.h
+176 -437
View File
@@ -47,7 +47,6 @@ build-retroarch-windows-x64:
--enforcedir /usr/lib/mxe/usr/x86_64-w64-mingw32.shared/qt5/plugins/styles/
--copy
--objdump x86_64-w64-mingw32.shared-objdump"
- "cp -f nvdaControllerClient64.dll ${MEDIA_PATH}/${CI_PROJECT_NAME}/redist/nvdaControllerClient64.dll"
- "rm -f ${MEDIA_PATH}/${CI_PROJECT_NAME}/redist/opengl32.dll"
build-retroarch-windows-i686:
@@ -105,10 +104,9 @@ build-retroarch-windows-msvc10-x64:
SDK_BIN_DIR: C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
RCEDIT_BIN_DIR: C:\Program Files\rcedit
PEDEPS_BIN_DIR: C:\Program Files\pedeps-0.1.9-win64\bin
MSVC_PLATFORM: windows_msvc2010_x64
before_script:
- $Env:HOME = "."
- $Env:Path += -join(";", "$Env:MSYS_BIN_DIR", ";", "$Env:SDK_BIN_DIR", ";", "$Env:RCEDIT_BIN_DIR", ";", "$Env:PEDEPS_BIN_DIR")
- $Env:Path += -join(";", "$Env:SDK_BIN_DIR", ";", "$Env:RCEDIT_BIN_DIR", ";", "$Env:PEDEPS_BIN_DIR")
artifacts:
paths:
- retroarch.exe
@@ -116,31 +114,26 @@ build-retroarch-windows-msvc10-x64:
expire_in: 10 min
dependencies: []
script:
- |
$ErrorActionPreference = 'Stop'
# Build RetroArch
bash.exe -l -c "make -f Makefile.griffin platform=$Env:MSVC_PLATFORM"
if ($LastExitCode -ne 0){throw "Failed to build RetroArch"}
mt.exe -nologo -manifest "retroarch.exe.manifest" -outputresource:"retroarch.exe;#1"
if ($LastExitCode -ne 0){throw "Failed to add manifest to RetroArch binary"}
rcedit-x64.exe "retroarch.exe" --set-icon "media\retroarch.ico"
if ($LastExitCode -ne 0){throw "Failed to set icon of RetroArch binary"}
# Create .media subdirectories
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist" -ItemType Directory
# Copy audio/video filters
Get-ChildItem -Path "libretro-common/audio/dsp_filters/*" -Include *.dsp | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio"
Get-ChildItem -Path "gfx/video_filters/*" -Include *.filt | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video"
# Copy default config file
Copy-Item -Path "retroarch.cfg" -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg/retroarch.default.cfg"
# Copy dll dependencies
# (note that msvc builds should not have any, but this
# may change in the future)
copypedeps.exe -r retroarch.exe "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist"
if ($LastExitCode -ne 0){throw "Failed to copy RetroArch dependencies"}
Remove-Item "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist/retroarch.exe" -ErrorAction Ignore
# Build RetroArch
- $Script:MakeCmd = "$Env:MSYS_BIN_DIR\env.exe $Env:MSYS_BIN_DIR\bash.exe -l -c 'make -f Makefile.griffin platform=windows_msvc2010_x64'"
- Invoke-Expression $Script:MakeCmd
- mt.exe -nologo -manifest "retroarch.exe.manifest" -outputresource:"retroarch.exe;#1"
- rcedit-x64.exe "retroarch.exe" --set-icon "media\retroarch.ico"
# Create .media subdirectories
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist" -ItemType Directory
# Copy audio/video filters
- Get-ChildItem -Path "libretro-common/audio/dsp_filters/*" -Include *.dsp | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio"
- Get-ChildItem -Path "gfx/video_filters/*" -Include *.filt | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video"
# Copy default config file
- Copy-Item -Path "retroarch.cfg" -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg/retroarch.default.cfg"
# Copy dll dependencies
# (note that msvc10 build should not have any, but this
# may change in the future)
- copypedeps.exe -r retroarch.exe "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist"
- Remove-Item "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist/retroarch.exe" -ErrorAction Ignore
build-retroarch-windows-msvc10-i686:
tags:
@@ -154,10 +147,9 @@ build-retroarch-windows-msvc10-i686:
SDK_BIN_DIR: C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
RCEDIT_BIN_DIR: C:\Program Files\rcedit
PEDEPS_BIN_DIR: C:\Program Files\pedeps-0.1.9-win64\bin
MSVC_PLATFORM: windows_msvc2010_x86
before_script:
- $Env:HOME = "."
- $Env:Path += -join(";", "$Env:MSYS_BIN_DIR", ";", "$Env:SDK_BIN_DIR", ";", "$Env:RCEDIT_BIN_DIR", ";", "$Env:PEDEPS_BIN_DIR")
- $Env:Path += -join(";", "$Env:SDK_BIN_DIR", ";", "$Env:RCEDIT_BIN_DIR", ";", "$Env:PEDEPS_BIN_DIR")
artifacts:
paths:
- retroarch.exe
@@ -165,31 +157,26 @@ build-retroarch-windows-msvc10-i686:
expire_in: 10 min
dependencies: []
script:
- |
$ErrorActionPreference = 'Stop'
# Build RetroArch
bash.exe -l -c "make -f Makefile.griffin platform=$Env:MSVC_PLATFORM"
if ($LastExitCode -ne 0){throw "Failed to build RetroArch"}
mt.exe -nologo -manifest "retroarch.exe.manifest" -outputresource:"retroarch.exe;#1"
if ($LastExitCode -ne 0){throw "Failed to add manifest to RetroArch binary"}
rcedit-x64.exe "retroarch.exe" --set-icon "media\retroarch.ico"
if ($LastExitCode -ne 0){throw "Failed to set icon of RetroArch binary"}
# Create .media subdirectories
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist" -ItemType Directory
# Copy audio/video filters
Get-ChildItem -Path "libretro-common/audio/dsp_filters/*" -Include *.dsp | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio"
Get-ChildItem -Path "gfx/video_filters/*" -Include *.filt | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video"
# Copy default config file
Copy-Item -Path "retroarch.cfg" -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg/retroarch.default.cfg"
# Copy dll dependencies
# (note that msvc builds should not have any, but this
# may change in the future)
copypedeps.exe -r retroarch.exe "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist"
if ($LastExitCode -ne 0){throw "Failed to copy RetroArch dependencies"}
Remove-Item "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist/retroarch.exe" -ErrorAction Ignore
# Build RetroArch
- $Script:MakeCmd = "$Env:MSYS_BIN_DIR\env.exe $Env:MSYS_BIN_DIR\bash.exe -l -c 'make -f Makefile.griffin platform=windows_msvc2010_x86'"
- Invoke-Expression $Script:MakeCmd
- mt.exe -nologo -manifest "retroarch.exe.manifest" -outputresource:"retroarch.exe;#1"
- rcedit-x64.exe "retroarch.exe" --set-icon "media\retroarch.ico"
# Create .media subdirectories
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist" -ItemType Directory
# Copy audio/video filters
- Get-ChildItem -Path "libretro-common/audio/dsp_filters/*" -Include *.dsp | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio"
- Get-ChildItem -Path "gfx/video_filters/*" -Include *.filt | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video"
# Copy default config file
- Copy-Item -Path "retroarch.cfg" -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg/retroarch.default.cfg"
# Copy dll dependencies
# (note that msvc10 build should not have any, but this
# may change in the future)
- copypedeps.exe -r retroarch.exe "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist"
- Remove-Item "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist/retroarch.exe" -ErrorAction Ignore
build-retroarch-windows-msvc05-i686:
tags:
@@ -204,10 +191,9 @@ build-retroarch-windows-msvc05-i686:
RCEDIT_BIN_DIR: C:\Program Files\rcedit
PEDEPS_BIN_DIR: C:\Program Files\pedeps-0.1.9-win64\bin
VS80COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\
MSVC_PLATFORM: windows_msvc2005_x86
before_script:
- $Env:HOME = "."
- $Env:Path += -join(";", "$Env:MSYS_BIN_DIR", ";", "$Env:SDK_BIN_DIR", ";", "$Env:RCEDIT_BIN_DIR", ";", "$Env:PEDEPS_BIN_DIR")
- $Env:Path += -join(";", "$Env:SDK_BIN_DIR", ";", "$Env:RCEDIT_BIN_DIR", ";", "$Env:PEDEPS_BIN_DIR")
artifacts:
paths:
- retroarch.exe
@@ -215,31 +201,26 @@ build-retroarch-windows-msvc05-i686:
expire_in: 10 min
dependencies: []
script:
- |
$ErrorActionPreference = 'Stop'
# Build RetroArch
bash.exe -l -c "make -f Makefile.griffin platform=$Env:MSVC_PLATFORM"
if ($LastExitCode -ne 0){throw "Failed to build RetroArch"}
mt.exe -nologo -manifest "retroarch.exe.manifest" -outputresource:"retroarch.exe;#1"
if ($LastExitCode -ne 0){throw "Failed to add manifest to RetroArch binary"}
rcedit-x64.exe "retroarch.exe" --set-icon "media\retroarch.ico"
if ($LastExitCode -ne 0){throw "Failed to set icon of RetroArch binary"}
# Create .media subdirectories
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg" -ItemType Directory
New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist" -ItemType Directory
# Copy audio/video filters
Get-ChildItem -Path "libretro-common/audio/dsp_filters/*" -Include *.dsp | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio"
Get-ChildItem -Path "gfx/video_filters/*" -Include *.filt | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video"
# Copy default config file
Copy-Item -Path "retroarch.cfg" -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg/retroarch.default.cfg"
# Copy dll dependencies
# (note that msvc builds should not have any, but this
# may change in the future)
copypedeps.exe -r retroarch.exe "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist"
if ($LastExitCode -ne 0){throw "Failed to copy RetroArch dependencies"}
Remove-Item "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist/retroarch.exe" -ErrorAction Ignore
# Build RetroArch
- $Script:MakeCmd = "$Env:MSYS_BIN_DIR\env.exe $Env:MSYS_BIN_DIR\bash.exe -l -c 'make -f Makefile.griffin platform=windows_msvc2005_x86'"
- Invoke-Expression $Script:MakeCmd
- mt.exe -nologo -manifest "retroarch.exe.manifest" -outputresource:"retroarch.exe;#1"
- rcedit-x64.exe "retroarch.exe" --set-icon "media\retroarch.ico"
# Create .media subdirectories
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg" -ItemType Directory
- New-Item -Path "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist" -ItemType Directory
# Copy audio/video filters
- Get-ChildItem -Path "libretro-common/audio/dsp_filters/*" -Include *.dsp | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/audio"
- Get-ChildItem -Path "gfx/video_filters/*" -Include *.filt | Copy-Item -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/filters/video"
# Copy default config file
- Copy-Item -Path "retroarch.cfg" -Destination "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/pkg/retroarch.default.cfg"
# Copy dll dependencies
# (note that msvc05 build should not have any, but this
# may change in the future)
- copypedeps.exe -r retroarch.exe "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist"
- Remove-Item "$Env:MEDIA_PATH/$Env:CI_PROJECT_NAME/redist/retroarch.exe" -ErrorAction Ignore
build-retroarch-linux-x64:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-amd64-ubuntu:xenial-gcc9
@@ -327,79 +308,11 @@ build-retroarch-linux-i686:
- "cd gfx/video_filters && make -j$NUMPROC build=release && make -j$NUMPROC build=release strip && cd -"
- "cp -f gfx/video_filters/*.so ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
build-retroarch-linux-aarch64:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-aarch64-ubuntu:latest
stage: build
tags:
- aarch64
variables:
MEDIA_PATH: .media
STRIP_BIN: 1
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch
- retroarch_qt
- ${MEDIA_PATH}
expire_in: 10 min
dependencies: []
script:
# Qt build
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/AppDirQt"
- "./configure --disable-ffmpeg --prefix=/usr"
- "make -j$NUMPROC"
- if [ $STRIP_BIN -eq 1 ]; then strip --strip-unneeded retroarch; fi
- "make install DESTDIR=${MEDIA_PATH}/${CI_PROJECT_NAME}/AppDirQt prefix=/usr"
- "rm -rf ${MEDIA_PATH}/${CI_PROJECT_NAME}/AppDirQt/etc"
- "cd ${MEDIA_PATH}/${CI_PROJECT_NAME}/ && tar -czf AppDirQt.tar.gz AppDirQt && rm -rf AppDirQt && cd -"
- "mv -f retroarch retroarch_qt"
# Non-Qt build
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/AppDir"
- "make clean"
- "./configure --disable-ffmpeg --disable-qt --prefix=/usr"
- "make -j$NUMPROC"
- if [ $STRIP_BIN -eq 1 ]; then strip --strip-unneeded retroarch; fi
- "make install DESTDIR=${MEDIA_PATH}/${CI_PROJECT_NAME}/AppDir prefix=/usr"
- "rm -rf ${MEDIA_PATH}/${CI_PROJECT_NAME}/AppDir/etc"
- "cd ${MEDIA_PATH}/${CI_PROJECT_NAME}/ && tar -czf AppDir.tar.gz AppDir && rm -rf AppDir && cd -"
# Filters
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "cd libretro-common/audio/dsp_filters && make -j$NUMPROC build=release && make -j$NUMPROC build=release strip && cd -"
- "cp -f libretro-common/audio/dsp_filters/*.so ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio"
- "cp -f libretro-common/audio/dsp_filters/*.dsp ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio"
- "cd gfx/video_filters && make -j$NUMPROC build=release && make -j$NUMPROC build=release strip && cd -"
- "cp -f gfx/video_filters/*.so ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
build-retroarch-webos-armv7a:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-webos:latest
stage: build
variables:
MEDIA_PATH: .media
before_script:
- export NUMPROC=$(($(nproc)/3))
- . /developer/arm-webos-linux-gnueabi_sdk-buildroot/environment-setup
artifacts:
paths:
- retroarch
- ${MEDIA_PATH}
expire_in: 10 min
dependencies: []
script:
- make -f Makefile.webos retroarch -j$NUMPROC
- arm-webos-linux-gnueabi-strip --strip-unneeded retroarch
- mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio
- mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video
- cp -f libretro-common/audio/dsp_filters/*.dsp ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio
- cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video
.build-retroarch-macos-xcode:
# Metal/Universal x86_64 arm64 is default
tags:
- mac-apple-silicon
- macosx-packaging
stage: build
variables:
XCARCHIVE_PATH: pkg/apple/build/RetroArchUniversal
@@ -413,11 +326,12 @@ build-retroarch-webos-armv7a:
dependencies: []
script:
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -config Release -scheme RetroArch -archivePath ${XCARCHIVE_PATH} -xcconfig pkg/apple/${XCCONFIG} archive
- xcodebuild -exportArchive -archivePath ${XCARCHIVE_PATH}.xcarchive -exportPath . -exportOptionsPlist pkg/apple/OSX/ExportOptions.plist
- ditto -c -k --sequesterRsrc --keepParent RetroArch.app ${XCPROJECT_NAME}.zip
- pushd ${XCARCHIVE_PATH}.xcarchive/Products/Users/gitlab/Applications/
- ditto -c -k --sequesterRsrc --keepParent RetroArch.app RetroArch.zip
- popd
- mv ${XCARCHIVE_PATH}.xcarchive/Products/Users/gitlab/Applications/RetroArch.zip ${XCPROJECT_NAME}.zip
- mkdir .retroarch-repo
- "cp -R ./* .retroarch-repo"
- echo '#define GIT_VERSION ' $(git rev-parse --short HEAD) > .retroarch-repo/.git_version.h
- "cp -r ./* .retroarch-repo"
- "mv .retroarch-repo/ retroarch-repo/"
# Mac OS Universal, Metal
@@ -426,58 +340,29 @@ build-retroarch-osx-universal-metal:
build-retroarch-osx-opengl-x64:
extends: .build-retroarch-macos-xcode
tags:
- macosx-packaging
variables:
XCARCHIVE_PATH: pkg/apple/build/RetroArchOpenGL
XCPROJECT_NAME: RetroArch
XCCONFIG: OpenGL_GitLabCI.xcconfig
#build-retroarch-osx-ppc:
# stage: build
# artifacts:
# paths:
# - ${XCPROJECT_NAME}.zip
# - retroarch-repo/
# expire_in: 10 min
# dependencies: []
# variables:
# XCPROJECT_NAME: RetroArch
# XCCONFIG: OpenGL_GitLabCI.xcconfig
# tags:
# - macosx-legacy
# script:
# - xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch_PPC.xcodeproj ONLY_ACTIVE_ARCH=NO
# - pushd pkg/apple/build/Release/
# - ditto -c -k --sequesterRsrc --keepParent RetroArch.app ${XCPROJECT_NAME}.zip
# - popd
# - mv pkg/apple/build/Release/RetroArch.zip ${XCPROJECT_NAME}.zip
# - mkdir .retroarch-repo
# - "cp -r ./* .retroarch-repo"
# - "mv .retroarch-repo/ retroarch-repo/"
build-retroarch-ios-arm64:
extends: .build-retroarch-macos-xcode
variables:
XCPROJECT_NAME: RetroArch_iOS13
XCPROJECT_NAME: RetroArch_iOS11_Metal
XCCONFIG: GitLabCI.xcconfig
XCSCHEME: "RetroArch iOS Release"
XCDESTINATION: "generic/platform=iOS"
artifacts:
paths:
- retroarch-repo/
expire_in: 10 min
script:
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -destination ${XCDESTINATION} -config Release -scheme "${XCSCHEME}" -xcconfig pkg/apple/iOS/${XCCONFIG} build
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -config Release -scheme "${XCSCHEME}" -xcconfig pkg/apple/iOS/GitLabCI.xcconfig build
- mkdir .retroarch-repo
- "cp -r ./* .retroarch-repo"
- echo '#define GIT_VERSION ' $(git rev-parse --short HEAD) > .retroarch-repo/.git_version.h
- "mv .retroarch-repo/ retroarch-repo/"
build-retroarch-ios9:
extends: .build-retroarch-macos-xcode
tags:
- macosx-packaging
variables:
XCPROJECT_NAME: RetroArch_iOS9
XCCONFIG: GitLabCI.xcconfig
@@ -490,14 +375,12 @@ build-retroarch-ios9:
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -config Release -scheme "${XCSCHEME}" -xcconfig pkg/apple/iOS/GitLabCI.xcconfig build
- mkdir .retroarch-repo
- "cp -r ./* .retroarch-repo"
- echo '#define GIT_VERSION ' $(git rev-parse --short HEAD) > .retroarch-repo/.git_version.h
- "mv .retroarch-repo/ retroarch-repo/"
build-retroarch-tvos-arm64:
extends: build-retroarch-ios-arm64
variables:
XCSCHEME: "RetroArch tvOS Release"
XCDESTINATION: "generic/platform=tvOS"
build-retroarch-dingux-mips32:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-dingux:latest
@@ -587,29 +470,6 @@ build-retroarch-retrofw-mips32:
- "cp -f libretro-common/audio/dsp_filters/*.dsp ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio"
- "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
build-retroarch-miyoo-arm32:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-dingux:latest
stage: build
variables:
MEDIA_PATH: .media
STRIP_BIN: 1
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch
- ${MEDIA_PATH}
expire_in: 10 min
dependencies: []
script:
- "make -j$NUMPROC -f Makefile.miyoo"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
- "cp -f libretro-common/audio/dsp_filters/*.dsp ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio"
- "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "cp -f pkg/miyoo/20a-retroarch ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
build-retroarch-android-normal:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-android:latest
stage: build
@@ -618,15 +478,10 @@ build-retroarch-android-normal:
- retroarch-precompiled/
expire_in: 10 min
script:
script:
- |
set -e
cd pkg/android/phoenix
./gradlew assembleNormalRelease
cd -
mkdir .retroarch-precompiled
cp -r ./* .retroarch-precompiled/
mv .retroarch-precompiled/ retroarch-precompiled/
- "cd pkg/android/phoenix && ./gradlew assembleNormalRelease && cd -"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-retroarch-android-aarch64:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-android:latest
@@ -636,14 +491,10 @@ build-retroarch-android-aarch64:
- retroarch-precompiled/
expire_in: 10 min
script:
- |
set -e
cd pkg/android/phoenix
./gradlew assembleAarch64Release
cd -
mkdir .retroarch-precompiled
cp -r ./* .retroarch-precompiled/
mv .retroarch-precompiled/ retroarch-precompiled/
- "cd pkg/android/phoenix && ./gradlew assembleAarch64Release && cd -"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-retroarch-android-ra32:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-android:latest
@@ -653,14 +504,10 @@ build-retroarch-android-ra32:
- retroarch-precompiled/
expire_in: 10 min
script:
- |
set -e
cd pkg/android/phoenix
./gradlew assembleRa32Release
cd -
mkdir .retroarch-precompiled
cp -r ./* .retroarch-precompiled/
mv .retroarch-precompiled/ retroarch-precompiled/
- "cd pkg/android/phoenix && ./gradlew assembleRa32Release && cd -"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-retroarch-android-playstore-normal:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-android:latest
@@ -670,14 +517,10 @@ build-retroarch-android-playstore-normal:
- retroarch-precompiled/
expire_in: 10 min
script:
- |
set -e
cd pkg/android/phoenix
./gradlew bundlePlayStoreNormalRelease
cd -
mkdir .retroarch-precompiled
cp -r ./* .retroarch-precompiled/
mv .retroarch-precompiled/ retroarch-precompiled/
- "cd pkg/android/phoenix && ./gradlew bundlePlayStoreNormalRelease && cd -"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-retroarch-android-playstore-plus:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-android:latest
@@ -687,17 +530,13 @@ build-retroarch-android-playstore-plus:
- retroarch-precompiled/
expire_in: 10 min
script:
- |
set -e
cd pkg/android/phoenix
./gradlew bundlePlayStorePlusRelease
cd -
mkdir .retroarch-precompiled
cp -r ./* .retroarch-precompiled/
mv .retroarch-precompiled/ retroarch-precompiled/
- "cd pkg/android/phoenix && ./gradlew bundlePlayStorePlusRelease && cd -"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-static-retroarch-libnx-aarch64:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-libnx-devkitpro:v4-10-0
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-libnx-devkitpro:latest
stage: prepare-for-static-cores
before_script:
- export NUMPROC=$(($(nproc)/3))
@@ -717,7 +556,7 @@ build-static-retroarch-libnx-aarch64:
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-static-retroarch-dummy-libnx-aarch64:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-libnx-devkitpro:v4-10-0
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-libnx-devkitpro:latest
stage: build
variables:
MEDIA_PATH: .media
@@ -737,6 +576,86 @@ build-static-retroarch-dummy-libnx-aarch64:
- "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "cp -f pkg/libnx/retroarch.jpg ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
build-static-retroarch-vita:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-vita:latest
stage: prepare-for-static-cores
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch-precompiled/
- retroarch-precompiled-gl/
expire_in: 10 min
dependencies: []
needs:
# Dummy build requires no core
- build-static-retroarch-dummy-vita
script:
# Allow failure since we don't have a core
- "make -f Makefile.vita -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "make -f Makefile.vita clean"
- "HAVE_VITAGLES=1 make -f Makefile.vita -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled-gl"
- "cp -r ./* .retroarch-precompiled-gl/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
- "mv .retroarch-precompiled-gl/ retroarch-precompiled-gl/"
build-static-retroarch-dummy-vita:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-vita:latest
stage: build
variables:
MEDIA_PATH: .media
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- eboot.bin
- param.sfo
- ${MEDIA_PATH}
expire_in: 10 min
dependencies: []
script:
- "make -f Makefile.vita.salamander -j$NUMPROC"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
- "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "cp -fr pkg/vita/* ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
build-static-retroarch-ps2:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-ps2:latest
stage: prepare-for-static-cores
artifacts:
paths:
- retroarch-precompiled/
expire_in: 10 min
dependencies: []
needs:
# Dummy build requires no core
- build-static-retroarch-dummy-ps2
script:
# Allow failure since we don't have a core
# PS2 makefile for now doesn't allow -jX so this is why is hardcoded to -j1
- "make -f Makefile.ps2 -j1 ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-static-retroarch-dummy-ps2:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-ps2:latest
stage: build
before_script:
# PS2 doesn't allow to use -jX for now
- export NUMPROC=1
artifacts:
paths:
- raboot.elf
expire_in: 10 min
dependencies: []
script:
- "make -f Makefile.ps2.salamander -j$NUMPROC release"
build-static-retroarch-psp:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-psp:latest
stage: prepare-for-static-cores
@@ -781,183 +700,6 @@ build-static-retroarch-dummy-psp:
- "cp -f pkg/psp1/ICON0.PNG ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
- "cp -f pkg/psp1/PIC1.PNG ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
build-static-retroarch-vita:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-vita:latest-20260905
stage: prepare-for-static-cores
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch-precompiled/
- retroarch-precompiled-gl/
expire_in: 10 min
dependencies: []
needs:
# Dummy build requires no core
- build-static-retroarch-dummy-vita
script:
# Allow failure since we don't have a core
- "make -f Makefile.vita -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "make -f Makefile.vita clean"
- "HAVE_VITAGLES=1 make -f Makefile.vita -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled-gl"
- "cp -r ./* .retroarch-precompiled-gl/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
- "mv .retroarch-precompiled-gl/ retroarch-precompiled-gl/"
build-static-retroarch-dummy-vita:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-vita:latest-20260905
stage: build
variables:
MEDIA_PATH: .media
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- eboot.bin
- param.sfo
- ${MEDIA_PATH}
expire_in: 10 min
dependencies: []
script:
- "make -f Makefile.vita.salamander -j$NUMPROC"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
- "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video"
- "cp -fr pkg/vita/* ${MEDIA_PATH}/${CI_PROJECT_NAME}/pkg"
build-static-retroarch-ps2:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-ps2:latest
stage: prepare-for-static-cores
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch-precompiled/
expire_in: 10 min
dependencies: []
needs:
# Dummy build requires no core
- build-static-retroarch-dummy-ps2
script:
# Allow failure since we don't have a core
- "make -f Makefile.ps2 -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-static-retroarch-dummy-ps2:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-ps2:latest
stage: build
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- raboot.elf
expire_in: 10 min
dependencies: []
script:
- "make -f Makefile.ps2.salamander -j$NUMPROC release"
build-static-retroarch-psl1ght:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-psl1ght:latest
stage: prepare-for-static-cores
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch-precompiled/
expire_in: 10 min
dependencies: []
needs:
# Dummy build requires no core
- build-static-retroarch-dummy-psl1ght
script:
# Allow failure since we don't have a core
- "make -f Makefile.psl1ght -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-static-retroarch-dummy-psl1ght:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-psl1ght:latest
stage: build
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch_psl1ght_salamander.elf
expire_in: 10 min
dependencies: []
script:
- "make -f Makefile.psl1ght.salamander -j$NUMPROC create-salamander"
build-static-retroarch-orbis:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-orbis:latest
stage: prepare-for-static-cores
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch-precompiled/
expire_in: 10 min
dependencies: []
needs:
# Dummy build requires no core
- build-static-retroarch-dummy-orbis
script:
# Allow failure since we don't have a core
- "make -f Makefile.orbis -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
build-static-retroarch-dummy-orbis:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-orbis:latest
stage: build
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch_orbis.self
expire_in: 10 min
dependencies: []
script:
- "make -f Makefile.orbis -j$NUMPROC HAVE_STATIC_DUMMY=1"
build-static-retroarch-djgpp:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-djgpp-build-container:latest
stage: prepare-for-static-cores
before_script:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch-precompiled/
expire_in: 10 min
dependencies: []
needs: []
script:
# Allow failure since we don't have a core
- "make -f Makefile.dos -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
#build-static-retroarch-dummy-djgpp:
# image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-djgpp-build-container:latest
# stage: build
# before_script:
# - export NUMPROC=$(($(nproc)/3))
# artifacts:
# paths:
# - retrodos.exe
# expire_in: 10 min
# dependencies: []
# script:
# - "make -f Makefile.dos.salamander -j$NUMPROC release"
build-static-retroarch-ctr:
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-devkitpro:latest
stage: prepare-for-static-cores
@@ -988,10 +730,9 @@ build-static-retroarch-ctr-legacy:
- retroarch-precompiled/
expire_in: 10 min
dependencies: []
needs: []
script:
# Allow failure since we don't have a core
- "make -f Makefile.ctr -j$NUMPROC USE_CTRULIB_2=0 ||:"
- "make -f Makefile.ctr -j$NUMPROC ||:"
- "mkdir .retroarch-precompiled"
- "cp -r ./* .retroarch-precompiled/"
- "mv .retroarch-precompiled/ retroarch-precompiled/"
@@ -1199,11 +940,9 @@ trigger_static-cores:
stage: trigger-static-cores
needs:
- build-static-retroarch-libnx-aarch64
- build-static-retroarch-psp
- build-static-retroarch-vita
- build-static-retroarch-ps2
- build-static-retroarch-psl1ght
- build-static-retroarch-orbis
- build-static-retroarch-psp
- build-static-retroarch-ctr
- build-static-retroarch-ctr-legacy
- build-static-retroarch-wiiu
+155
View File
@@ -0,0 +1,155 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}",
"${workspaceRoot}/libretro-common/include"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
]
},
{
"name": "Linux",
"includePath": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}",
"${workspaceFolder}/libretro-common/include",
"${workspaceRoot}/libretro-common/include"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
"${workspaceRoot}",
"${workspaceFolder}/libretro-common/include"
],
"defines": [
"_DEBUG",
"UNICODE"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
},
{
"name": "msys2-mingw32",
"includePath": [
"C:/msys64/mingw32/include",
"C:/msys64/mingw32/i686-w64-mingw32/include",
"${workspaceRoot}/libretro-common/include",
"${workspaceRoot}/include",
"${workspaceRoot}"
],
"defines": [
"_DEBUG",
"UNICODE"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"C:/msys64/mingw32/include",
"C:/msys64/mingw32/i686-w64-mingw32/include",
"${workspaceRoot}/libretro-common/include",
"${workspaceRoot}/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "msys2-mingw64",
"includePath": [
"C:/msys64/mingw64/include",
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
"${workspaceRoot}/libretro-common/include",
"${workspaceRoot}/include",
"${workspaceRoot}"
],
"defines": [
"_DEBUG",
"UNICODE"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"C:/msys64/mingw64/include",
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
"${workspaceRoot}/libretro-common/include",
"${workspaceRoot}/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Switch",
"includePath": [
"/opt/devkitpro/devkitA64/aarch64-none-elf/include",
"/opt/devkitpro/devkitA64/lib/gcc/aarch64-none-elf/8.3.0/include",
"/opt/devkitpro/libnx/include",
"/opt/devkitpro/portlibs/switch/include",
"/opt/devkitpro/portlibs/switch/include/freetype2",
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"__aarch64__",
"__SWITCH__",
"HAVE_LIBNX"
],
"windowsSdkVersion": "10.0.17763.0",
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc",
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
}
+70
View File
@@ -0,0 +1,70 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/retroarch.exe",
"args": ["-v"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/retroarch.exe",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "PSP-GDB Debugger",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/retroarchpsp.elf",
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"setupCommands": [
{
"text": "symbol-file ${workspaceFolder}/retroarchpsp.elf",
"description": "read symbols for elf file",
"ignoreFailures": true
},
{
"description": "Enable all-exceptions",
"text": "-exec \"catch throw\"",
"ignoreFailures": true
}
],
"showDisplayString": true,
"targetArchitecture": "mips",
"MIMode": "gdb",
"miDebuggerPath": "/usr/local/pspdev/bin/psp-gdb",
"miDebuggerServerAddress": "127.0.0.1:10001",
}
]
}
+71
View File
@@ -0,0 +1,71 @@
{
"terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
"terminal.integrated.env.windows": {
"PATH": "/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:$PATH",
"MSYSTEM": "MINGW64",
},
"terminal.integrated.cursorBlinking": true,
"editor.tabSize": 3,
"editor.detectIndentation": false,
"editor.renderWhitespace": "all",
"editor.insertSpaces": true,
"editor.formatOnSave": false,
"files.associations": {
"frontend_driver.h": "c",
"*.in": "c",
"*.rh": "c",
"array": "c",
"file_stream.h": "c",
"driver.h": "c",
"iosfwd": "c",
"xlocbuf": "c",
"xmemory0": "c",
"ios": "c",
"list": "c",
"input_driver.h": "c",
"menu_driver.h": "c",
"file_path.h": "c",
"unordered_map": "c",
"unordered_set": "c",
"sstream": "cpp",
"hash_map": "c",
"hash_set": "c",
"initializer_list": "c",
"string_view": "c",
"utility": "c",
"menu_input.h": "c",
"tasks_internal.h": "c",
"ozone.h": "c",
"ozone_theme.h": "c",
"ozone_texture.h": "c",
"string_list.h": "c",
"core_info.h": "c",
"thread": "c",
"xlocale": "c",
"gfx_widgets.h": "c",
"message_queue.h": "c",
"task_queue.h": "c",
"fifo_queue.h": "c",
"file_list.h": "c",
"strl.h": "c",
"configuration.h": "c",
"ozone_display.h": "c",
"verbosity.h": "c",
"retroarch.h": "c",
"gfx_animation.h": "c",
"netplay.h": "c",
"scaler.h": "c",
"deque": "c",
"vector": "c",
"xhash": "c",
"xiosbase": "c",
"xstring": "c",
"xtree": "c",
"xutility": "c",
"menu_input_dialog.h": "c",
"ozone_sidebar.h": "c",
"menu_thumbnail_path.h": "c",
"badges.h": "c"
},
"C_Cpp.dimInactiveRegions": false,
}
+128
View File
@@ -0,0 +1,128 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "linux clean build",
"type": "shell",
"group": "build",
"command": "make clean && ./configure && make -j12"
},
{
"label": "linux clean",
"type": "shell",
"group": "build",
"command": "make clean"
},
{
"label": "linux build with debug symbols",
"type": "shell",
"group": "build",
"command": "DEBUG=1 make -j12"
},
{
"label": "linux build",
"type": "shell",
"group": "build",
"command": "make -j12"
},
{
"label": "linux build and run",
"type": "shell",
"group": "build",
"command": "make -j12 && ./retroarch -v"
},
{
"label": "linux build and run with debug symbols",
"type": "shell",
"group": "build",
"command": "DEBUG=1 make -j12 && ./retroarch -v"
},
{
"label": "msys2-mingw64 build",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"command": "./configure; make -j2",
"options": {
"shell": {
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
"args": [
"-c"
]
}
}
},
{
"label": "msys2-mingw64 build with debug symbols",
"type": "shell",
"group": "build",
"command": "./configure; DEBUG=1 make -j2",
"options": {
"shell": {
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
"args": [
"-c"
]
}
}
},
{
"label": "msys2-mingw64 rebuild",
"type": "shell",
"group": "build",
"command": "make -j2",
"options": {
"shell": {
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
"args": [
"-c"
]
}
}
},
{
"label": "msys2-mingw64 clean",
"type": "shell",
"group": "build",
"command": "make clean",
"options": {
"shell": {
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
"args": [
"-c"
]
}
}
},
{
"label": "msys2-mingw64 run",
"type": "shell",
"group": {
"kind": "test",
"isDefault": true },
"command": "./retroarch -v",
"options": {
"shell": {
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
"args": [
"-c"
]
}
}
}
]
}
+96
View File
@@ -0,0 +1,96 @@
diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c
index b90a8e40c3..e57c4df194 100644
--- a/gfx/drivers_context/wgl_ctx.c
+++ b/gfx/drivers_context/wgl_ctx.c
@@ -78,6 +78,47 @@
#ifndef WGL_CONTEXT_DEBUG_BIT_ARB
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#endif
+
+#ifndef WGL_ACCELERATION_ARB
+#define WGL_ACCELERATION_ARB 0x2003
+#endif
+
+#ifndef WGL_FULL_ACCELERATION_ARB
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#endif
+
+#ifndef WGL_DRAW_TO_WINDOW_ARB
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#endif
+
+#ifndef WGL_DOUBLE_BUFFER_ARB
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#endif
+
+#ifndef WGL_RED_BITS_ARB
+#define WGL_RED_BITS_ARB 0x2015
+#endif
+
+#ifndef WGL_GREEN_BITS_ARB
+#define WGL_GREEN_BITS_ARB 0x2017
+#endif
+
+#ifndef WGL_BLUE_BITS_ARB
+#define WGL_BLUE_BITS_ARB 0x2019
+#endif
+
+#ifndef WGL_ALPHA_BITS_ARB
+#define WGL_ALPHA_BITS_ARB 0x201B
+#endif
+
+#ifndef WGL_PIXEL_TYPE_ARB
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#endif
+
+#ifndef WGL_TYPE_RGBA_ARB
+#define WGL_TYPE_RGBA_ARB 0x202B
+#endif
+
#endif
#if defined(HAVE_OPENGL)
@@ -313,6 +354,43 @@ static void create_gl_context(HWND hwnd, bool *quit)
RARCH_LOG("[WGL]: Adaptive VSync supported.\n");
wgl_adaptive_vsync = true;
}
+ if (wgl_has_extension("WGL_ARB_pixel_format", extensions))
+ {
+ BOOL (WINAPI * wglChoosePixelFormatARB)
+ (HDC hdc,
+ const int *piAttribIList,
+ const FLOAT *pfAttribFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT *nNumFormats);
+ UINT nMatchingFormats;
+ int index = 0;
+ int attribsDesired[] = {
+ WGL_DRAW_TO_WINDOW_ARB, 1,
+ WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+ WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
+ WGL_RED_BITS_ARB, 10,
+ WGL_GREEN_BITS_ARB, 10,
+ WGL_BLUE_BITS_ARB, 10,
+ WGL_ALPHA_BITS_ARB, 2,
+ WGL_DOUBLE_BUFFER_ARB, 1,
+ 0,0
+ };
+ wglChoosePixelFormatARB = (BOOL (WINAPI *) (HDC, const int *,
+ const FLOAT*, UINT, int*, UINT*))
+ gfx_ctx_wgl_get_proc_address("wglChoosePixelFormatARB");
+
+ RARCH_LOG("[WGL]: ARB pixel format supported.\n");
+
+ if (wglChoosePixelFormatARB(win32_hdc, attribsDesired,
+ NULL, 1, &index, &nMatchingFormats))
+ {
+ if (nMatchingFormats == 0)
+ {
+ RARCH_WARN("No 10bpc WGL_ARB_pixel_formats found!\n");
+ }
+ }
+ }
}
}
#endif
-118
View File
@@ -1,118 +0,0 @@
AGENTS.md
## Project
RetroArch is primarily written in C89. Preserve the existing language and style of the file being edited.
- New C code must be C89-compatible unless the surrounding code explicitly requires otherwise.
- Do not introduce C99/C11 features into C89 code.
- Existing files written in C++, Objective-C, or another language should remain in that language.
- Follow the conventions of surrounding code rather than introducing a new style.
- Prefer the smallest change that completely solves the task.
- Preserve existing architecture
RetroArch contains deliberately complex, cross-file systems. Do not simplify, consolidate, refactor, or redesign an existing subsystem merely because its structure appears unnecessarily complicated.
Complexity may exist for compatibility, platform, driver, or architectural reasons.
When implementing a feature, find an existing feature with similar behavior and follow its implementation pattern. The current source tree takes precedence over historical examples.
Do not make unrelated cleanup or refactoring changes.
## Comments
Keep comments as short as possible.
- Prefer no comment when the code is self-explanatory.
- When a comment is necessary, prefer a few words or a few lines at most.
- Explain why something is non-obvious, rather than describing what obvious code does.
- Do not add comments merely because code was changed.
- Do not describe the previous implementation or behavior unless that historical context is necessary to understand the current code.
- Do not use comments as miniature documentation or change logs.
- Prefer clear names and straightforward code over explanatory comments.
Comments should describe information that will remain useful after the current change is forgotten.
## Commit messages
Keep commit messages concise and focused.
- Explain what changed and why.
- Prefer a short subject line and a brief body when additional context is useful.
- Do not enumerate every changed file or implementation detail.
- Do not describe intermediate attempts, discarded approaches, or the development process.
- Do not explain the previous implementation unless it is necessary to understand the change.
- Keep the complete commit message below approximately 600 words.
- A commit message is not a changelog or development diary.
## Menu changes
Adding or modifying a menu option commonly requires changes in several parts of the codebase.
Do not assume that a menu option can be implemented by modifying only the file where it is displayed.
### Before adding a menu option:
- Find an existing menu option with similar behavior.
- Trace its complete implementation through the menu, settings, configuration, and message systems.
- Identify every part of that pattern that applies to the new option.
- Implement the new option consistently across all required layers.
- Do not modify unrelated menu code.
#### Useful reference commits:
- 6e9aa66aea2b2b3d0687585e41bac658ac9ae252 — SMB timeout/context settings exposed as menu options.
- 434f41b935232325ed13024786653f9dfef49643 — CRT menu additions.
- 23170b82ec58c2b283a7132b85fa73e18050a5ae — MIDI device dropdown menu items.
05faba73e3fed69a5e118df2cc28d31309089243 — menu implementation example.
These are reference implementations, not fixed lists of files to modify. The required files depend on the feature.
## Shader and video backend changes
Shader functionality frequently crosses shared shader code and multiple video backends.
### When adding or modifying shader functionality:
- Find an existing shader feature with similar behavior.
- Trace the feature through the shared shader infrastructure.
- Identify every applicable shader implementation and video backend.
- Keep backend implementations consistent where the feature is supported.
- Do not update only the backend currently being tested if the feature is expected to work elsewhere.
- Check platform/backend-specific differences rather than blindly duplicating code.
#### Useful reference commits:
- da5ecaa45a862e51783eca1280f46fbfb7984ede — OriginalAspect and OriginalAspectRot uniforms.
- 2a56a827e8a97a3838a9d455f1dca442c0ffbb07 — frametime/original-FPS shader uniforms.
- 37cfa4857d064464754e800bad89ce69e81230fe — sensor shader uniforms across multiple shader and video/input backends.
These commits demonstrate the breadth of changes that may be required. They are examples of implementation patterns, not instructions to reproduce their exact file lists.
## Historical commits
Historical commits may be used to understand established implementation patterns.
- Treat examples as references, not specifications.
- Prefer the current source tree when it differs from an historical commit.
- Do not copy historical changes mechanically.
- Do not reproduce obsolete workarounds merely because they appear in an old commit.
- Inspect surrounding current code before applying a historical pattern.
## Scope of changes
Keep changes focused.
### Do not:
- reformat unrelated code;
- rename unrelated symbols;
- modernize C89 code;
- replace established patterns with preferred patterns;
- refactor neighboring code without a direct need;
- add documentation or comments solely to explain the current change;
- make speculative improvements.
If a task requires a broad change, make the breadth necessary for the feature rather than artificially minimizing the number of files changed.
A change touching many files is not inherently a problem in RetroArch. Missing a required layer of an established multi-file system is a problem.
+321
View File
@@ -0,0 +1,321 @@
static const char *retroarch_contributors_list = R"(
RetroArch and the libretro team would like to
acknowledge the following contributors:
1ch (L0sted)
Aaahh Ahh (Aaahh)
Aaron Oneal (aarononeal)
Adam Londero (alondero)
Adam Mechtley (amechtley)
AdrianoML
ajefr
Alberto Simon (asimonf)
Alcaro
Aleksey Samoilov (Sunderland93)
Alessandro Mangone (Vektor) (zevektor)
Alex Eckhart (alex34567)
Alex Folland (AlexFolland)
Alexander Spady (alkaseltzerspadt)
Alexandre Garcia (Alexandre-Garcia)
Alfredo Monclus (alfrix)
aliaspider
alphanu1
altiereslima
Alwin Garside (Yogarine)
Amiga1200Gamer (amigagamer)
Andre Leiradella (leiradel)
Andrés (fr500)
Anthony J. Bentley (bentley)
Antonio Jose Ramos Marquez (psxdev)
AridRayne
ArnaudFaucher
Arto Vainiolehto (arakerlu)
Ash (QuarkTheAwesome)
Ashura (CoalaJoe)
Autechre64
Avton1
ayssia
barbudreadmon
bearoso
benutzer193
blackgur
Boris Timofeev (btimofeev)
bparker06
Brandon Johnson (Denu8thell)
Brian Koropoff (bkoropoff)
Brian S. Stephan (bsstephan)
Brunnis
bubuleur
Casey Borders (CaseyB)
ceb33
celerizer
Chris Merrett (chrisfu)
Christian Murphy (grimpunch)
chu (9chu)
CidVonHighwind
clienthax
cold-brewed
CompCom
Conn O'Griofa (psyke83)
CozmoP
cpsw
Cray Elliott (MP2E)
Cristian Sandu (crazyquark)
ctult
cucholix
cudencuden
cxd4
dalter
Dan Weiss (Dwedit)
danieljg
Daniil Zhilin (LaserMoai)
dankcushions
Dave (freakdave)
Dave Leaver (danzel)
David Demelier (markand)
David Erickson (daviderickson)
David Shah (daveshah1)
David Walters (hiddenasbestos)
DEX357
diablodiab
dibas
Diego A. (SuperrSonic)
Diego Viola (diegoviola)
Diogo Barros (BlueKore)
DogParty
dor3k
driver1998
Dudu Akiva (duduke)
duganchen
dukemiller
duskgao
ekipan
Emmanuel Martin (daliaetnano)
endrift
erbridge
Ethan Lee (flibitijibibo)
Exvat
Ezio-PS
Fabio (Oibaf66)
Fabio Ritrovato (Sephiroth87)
Fayne Aldan (FayneAldan)
FIX94
Flame Sage (chris062689)
flyinghead
Francisco Javier Trujillo Mata (fjtrujy)
Francisco José García García (frangarcj)
Gabriel (Ghabry)
GameDragon2k
Garrett Brown (garbear)
gblues
Geoffrey Plitt (GeoffreyPlitt)
Glenn Hevey (hevey)
Googer
gouchi
grant2258
Gregor Richards (GregorR)
Gui Andrade (archshift)
Gustavo Maciel Dias Vieira (gmdvieira)
gvbr
H. İbrahim Güngör (igungor)
hadess
Hans-Kristian Arntzen (Themaister)
Henri Gomez (hgomez)
Henri Gomez (hgomez-sonarsource)
Higor Eurípedes (heuripedes)
Hisman Yosika (dnjstlr555)
hizzlekizzle
Hugo B. (hug0b)
Hugo Hromic (hhromic)
hunterk
hyarsan
Hyllian
i30817
iAmGhost
Jack (jakcron)
Jacob (cubtekki)
James Le Cuirot (chewi)
James Sexton (Bezier89)
Jamiras
Jan Holthuis (Holzhaus)
Jay McCarthy (jeapostrophe)
jdgleaver
Jean-André Santoni (kivutar)
Jean-Paul Mari (djipi)
Jean-Sébastien Guay (Skylark13)
Jesse Bryan (winneon)
Joel (joel16)
Joerg Sonnenberger (jsonn)
Johannes Schickel (lordhoto)
John Regan (jprjr)
Jon Maddox (maddox)
Jonathan Relf (jonathanrelf)
Joohan Lee (losernator)
Jools Wills (joolswills)
Jose Lage Miguez (Joselagem)
Joseph Carter (iKarith)
Joseph Conan Montgomery (Grotke)
Josh Palmer (ShiftyAxel)
JuanVCS
Justin Jacobs (dorkster)
Justin Weiss (justinweiss)
Ken Rossato (rossato)
krzys_h (krzys-h)
kurumushi
kwyxz
l3iggs
lambolighting
lasers
Lawrence Kesteloot (lkesteloot)
lifajucejo
liffy (lifning)
Lionel Flandrin (simias)
littleguy77
Logan (loganmc10)
lordashram
Lothar Serra Mari (lotharsm)
Lubosz Sarnecki (lubosz)
lucianposton
lxerandrew
m4xw
Mahyar Koshkouei (deltabeard)
Manuel Alfayate Corchete (vanfanel)
Marcelo Munhoz Pélos (mpelos)
markwkidd
Maschell
Mat M. (lioncash)
Mats A. (Datamats)
Matt Sephton (gingerbeardman)
Matthew Wang (asakous)
Max K. (langerhans)
Maxime Gauduin (alucryd)
mcrisostomo
meancoot
meepingsnesroms
meleu
Michael K. (kuxii2016)
Michael Lelli (ToadKing)
Michał Durak (micechal)
mickski56
Mico Chopitea (micochops)
miguelpinheiro
Mike Swanson (chungy)
miqlas (extrowerk)
misson20000
Monroe88
mprobinson
MrHuu
MrJs (mrjschulte)
muzuiget
mwtremblay
myfreeweb
Nathan S. (natinusala)
NathanStrong-Tripwire
nattycleopatra
nayslayer
Nephilim
netux79
nfnty
nia (ensra)
Nicolas Adenis-Lamarre (nadenislamarre)
Nicolas Guillaumin (nguillaumin)
Nicolas Lopez Fernandez (pyroesp)
Nikita Vakhrushev (SwooodGa)
Nikola Kocić (nikola-kocic)
Niouby
nosh01
not6 (r-type)
notaz
nstCactus
nurupo
Oggom
Oleg Shevchenko (olsh)
opendata26
orbea
OV2
pamapa
Paolo Bonzini (bonzini)
Paul McCarty (notabeatle)
Pedro Ribeiro (pedrib)
pinumbernumber
pponso1
Ramiro Morales (ramiro)
Raphaël Zumer (rzumer)
retro-wertz
retrotails
reztek
Richard Howell (rmaz)
rlnilsen
Rob Loach (RobLoach)
Romain Gay (vikbez)
Romain Graillot (notnotme)
Romain TISSERAND (rtissera)
Roman Kalashnikov (lunixoid)
Royerson
rrooij
rsn8887
Ryunam
rz5
Saggi Mizrahi (ficoos)
SAKUJ0
Sam Pagenkopf (44100hertz)
Sam Stenvall (Jalle19)
Samuel P. (p-sam)
Scheiker
Sebastien Ronsse (sronsse)
Sergi Granell (xerpi)
Sergio Padrino (sergiou87)
sergio-br2 (sergiobenrocha2)
Seth Kingsley (sethk)
Shane Mouton (ismouton)
Shizeeg Unadequatov (shizeeg)
slotek
sparklewind
spec-chum
Stefan (gizmo98)
stefan-gr
stellarporter
Steven M. Vascellaro (stevoisiak)
Stuart Carnie (stuartcarnie)
Sunguk Lee (d3m3vilurr)
Supernature2k
Sven (RetroSven)
Swingflip
Swizzy
Sylvain Colinet (Skarsnik)
Tatsuya79
Terry Lewis (terry-au)
thedax
theheroGAC
TheMrIron2
TheOfficialFloW
thiolliere
Thomas Lorblanchès (Zlika)
Tobias Jakobi (tobiasjakobi)
Tomáš Kelemen (ToKe79)
Torsten Paul (t-paul)
TotalCaesar659
TroggleMonkey
Twinaphex
URBANsUNITED
vgmoose
Vicky C Lau (vickychenglau)
Vladimir Panteleev (CyberShadow)
Vladimir Serbinenko (phcoder)
Víctor "IlDucci" (IlDucci)
waitingmoon
Wang Vincent (susemm)
webgeek1234
Weedy Weed Smoker (WeedyWeedSmoker)
WerWolv
Wiimpathy
Wiktor Strzębała (wiktorek140)
xhp-creations
yesfish (huwpascoe)
Yongwoon Cho (ssangkong)
yoshisuga
zeromus
zlice
Zoran Vuckovic (casdevel)
Ömercan Kömür (fpscan)
)";
+9 -1914
View File
File diff suppressed because it is too large. Load diff
-1
View File
@@ -1 +0,0 @@
@AGENTS.md
+66 -283
View File
@@ -1,283 +1,66 @@
Refer also to this page for more information -
https://docs.libretro.com/development/coding-standards/
Struct ordering
---------------
For POD-types, try to order structs as follows (first to last):
* long double (8 bytes, 16 bytes [64bit x86], 12 bytes [32bit x86])
* double (8 bytes)
* int64_t (8 bytes, 8 bytes [32bit ARM],
4 bytes [32bit x86])
* uint64_t (4 bytes [32bit], 8 bytes [32bit ARM], 8 bytes [64bit])
* pointer (4 bytes [32bit], 8 bytes [64bit] [1])
* intptr_t (4 bytes [32bit], 8 bytes [64bit] [1])
* uintptr_t (4 bytes [32bit], 8 bytes [64bit] [1])
* ptrdiff_t (4 bytes [32bit], 8 bytes [64bit] [1])
* ssize_t (4 bytes [32bit], 8 bytes [64bit])
* size_t (4 bytes [32bit], 8 bytes [64bit])
* jmp_buf (4 bytes)
* long (4 bytes [64bit Win], 8 bytes [64bit non-Win],
4 bytes [32bit])
* int32_t (4 bytes)
* unsigned (4 bytes)
* float (4 bytes)
* int (4 bytes)
* enum (4 bytes)
* int16_t (2 bytes)
* char (1 byte)
* bool (1 byte)
[1] PS3 uses 4 byte pointers despite having a 64bit processor
Struct members should be sorted by alignment. Therefore, structs
should be sorted by the largest type inside them.
For example, take a struct like this:
typedef struct
{
size_t capacity;
bool old_format;
bool compress;
bool fuzzy_archive_match;
bool autofix_paths;
char path[PATH_MAX_LENGTH];
char base_content_directory[DIR_MAX_LENGTH];
} playlist_config_t;
size_t has the biggest alignment here, so 'struct playlist_config_t'
inside a struct should come before or after size_t.
*** BEST PRACTICES ***
* If we have pointers and size variable pairs, it's best to
interleave them to increase the probability they go in the
same cacheline. It also makes the code more readable, that
these two variables are connected.
Example:
struct a
{
char* b;
size_t b_len;
char* c;
size_t c_len;
};
Stack size
----------
You have to assume that stack size is going to be limited in
RetroArch. These are the thread stacks the tree creates today:
* GEKKO (Wii/GC) 8 KiB STACKSIZE, rthreads/rthreads.c
* 3DS 32 KiB STACKSIZE, rthreads/rthreads.c
* PSP 32 KiB STACKSIZE, rthreads/rthreads.c
* Vita 64 KiB STACKSIZE, rthreads/rthreads.c
* WiiU 128 KiB STACKSIZE, rthreads/rthreads.c
* Switch 128 KiB STACKSIZE, rthreads/rthreads.c
* PS2 32 KiB STACKSIZE, rthreads/rthreads.c
* Vita 64 KiB rthreads.c, 0x10000
* Apple 2 MiB rthreads.c, raised from a 512 KiB default
* Windows 1 MiB reserved by default, committed lazily
8 KiB on GEKKO is the floor, and it is the number to design
against.
Which thread your code runs on is not something you get to assume.
Anything reachable from a task handler can end up on one of these:
retro_task_regular_gather() runs handlers on the main thread, but
with a threaded task queue the same handler runs on a worker.
*** THE BUDGET ***
- 4 KiB is the ceiling for a single stack frame anywhere in the
tree.
- 2 KiB is the ceiling for anything under libretro-common, and it
is enforced. tools/stack_budget.py measures every shipped .c
there with -fstack-usage and fails the build over it; it runs in
CI as part of Linux-libretro-common-tests.yml. Read the header
of that script before adding an entry to its allowlist - an
entry there is debt, not an exemption.
Neither number is a per-function allowance to spend. A frame does
not run alone, it runs on top of everything that called it. Ten
1.5 KiB frames in a row pass every per-frame check ever written
and still overflow an 8 KiB stack, which is why the budget sits so
far below the smallest stack.
*** WHY 4 KIB ***
- Small-stack targets. See the table above. A 16 KiB local buffer
is twice the whole GEKKO stack, and nothing warns about it: the
code builds everywhere and overflows only on a target most
contributors cannot build, at whatever moment it first runs on a
worker. config_file_write() carried a 16 KiB stdio buffer as a
local on a path reached from input_autoconfigure_connect_handler
- a task handler - and nothing noticed for years.
- Stack probes on Windows. 4 KiB is the page size, and Windows
commits thread stacks lazily: one guard page sits below the
committed region, and touching it is what makes the OS commit
another page and move the guard down. A frame that moves the
stack pointer past the guard page without touching it faults
outside the guard page, which the OS treats as a plain access
violation rather than a request to grow the stack - the process
dies. Compilers avoid that by emitting a probe: MSVC's default
is /Gs4096 on x86, x64, ARM and ARM64, so any function needing
more than one page of locals gets a call to __chkstk (or
___chkstk_ms under mingw-w64, which uses the same threshold)
that walks the frame page by page in order. So crossing 4 KiB
turns a single subtract into an out-of-line loop at every entry
to that function, and commits every page it touches for the life
of the thread. GCC's -fstack-clash-protection does the same
thing on Linux, and the kernel-side reason is the same.
- Recursion and reentrancy. A frame you can afford once is a frame
you cannot afford at depth 40. Anything recursive - directory
walks, archive nesting, parsers - should carry its state in a
heap-allocated context and bound its depth explicitly, not lean
on the stack to hold the recursion for it.
*** IN PRACTICE ***
- Measure rather than guess. For one file:
gcc -O2 -DPSP -fstack-usage -c foo.c -Ilibretro-common/include
and read foo.su. Or point the script at a file or a directory:
tools/stack_budget.py libretro-common/formats/. -DPSP matters,
because PATH_MAX_LENGTH is 512 on those targets and 2048
elsewhere - a host-shaped measurement overstates every function
holding a path buffer. Adding -Wstack-usage=4096 to a local
build turns the ceiling into a warning while you work.
Frame size is a property of an ABI, not of the source; the same
function measures 16 to 192 bytes larger under mingw-w64 than
under SysV. Do not compare an absolute number against one taken
from a different target triple.
- Per-frame is necessary and not sufficient. tools/stack_chain.py
sums frames along the call graph from a set of roots (task
handlers being the roots that matter) and reports the deepest
chain. It is a screening tool rather than a verdict, which is
why it is not in CI - read its header for what it cannot see.
- Path buffers are the usual culprit. On desktop PATH_MAX_LENGTH
is 2048, so two of them in one frame is already over the
ceiling. Use DIR_MAX_LENGTH (1024) and NAME_MAX_LENGTH (128)
when that is what the buffer actually holds, and reuse one
buffer rather than carrying a second.
- No VLAs and no alloca(). VLAs are not C89 (see below); alloca()
additionally makes the frame unbounded at compile time, and
-fstack-usage can only report such a frame as dynamic, so it
drops out of every check above.
- When a frame is too large, the question is not "can this
overflow today" but "does this need to be on the stack at all".
The answer is usually no, and the fix is usually one of: move
the buffer to the heap, or move it into a state object that is
already allocated once per stream/session, or shrink it. Real
examples, all done rather than argued about:
vh_build 16784 -> 400 scratch to the heap
config_file_write 16432 -> 48 stdio buffer to heap
chd_read_header_core_file 57504 -> 32 chd_file to the heap
rd_gen_lengths 12768 -> 352 scratch into the struct
sha1_calculate 4304 -> 224 mapped view, else heap
- None of this means small structs belong on the heap. Heap
allocations are slow compared to the stack, and scattering tiny
ones fragments memory - which matters most on exactly the
platforms with the small stacks. A balancing act is necessary:
a few hundred bytes of locals is fine and idiomatic, a kilobyte
wants a reason, and 4 KiB is where the decision is made for you.
Functions
---------
- Avoid doing small getter/setter functions. We want a function
to justify its function call overhead by doing a significant
body of work. Small one-line getter/setter functions for what
is predominantly C-style structs is not useful, plus it leads
to people thinking this function is more complex than it
actually is, thus obfuscating the sourcecode instead of it
being easier to read.
If you can find examples in the codebase that violate this
guideline, do not hesitate to point them out to us.
Variable declaration
--------------------
For C source files, we have to insist you stick to the following:
- Declare variables either at the start of a function or the start
of a code block, depending on the scope they need.
- Do not do initial for loop declarations. Refer to the bulletpoint above:
either declare them at the start of the function, or at the start
of the code block.
Not doing this would break compilation on platforms where we are compiling
these C source files in C89 compatibility mode. If such issues occur in pull
requests, we have to request that it be fixed.
VLA (Variable Length Array)
---------------------------
Do not use VLAs (Variable Length Array) in C source files. These are not
C89-compliant.
Main thread and task handlers
-----------------------------
The UI and the main thread must never block. When Threaded Tasks is
disabled - which it is on several platforms, and which users turn off
deliberately - task handlers run on the same thread that drives the
frame loop, so anything a handler does between returns is a frame the
UI cannot paint.
- Do not call task_queue_wait() from code reachable while the menu is
visible or a core is running. Cancel the work and guard against a
stale completion, or move what follows the wait into the task's own
callback. A last-resort safety net is acceptable only where an
invariant genuinely requires it (a worker must not call into a core
that is about to be unloaded, for instance), and then it must be
bounded and commented.
- Never pass a NULL condition to task_queue_wait(). It does not mean
"wait for my task": both queue implementations read it as "until the
queue is empty", so the caller ends up waiting out every unrelated
task in flight - a content scan, a core download. Pass a condition
that describes your own work.
- A handler that processes a collection must consult the shared
per-frame I/O window (task_nbio_slice_open /
task_nbio_slice_within_budget / task_nbio_slice_close) between
items, and must always complete at least one item per invocation so
an exhausted window cannot stall it. Do NOT chunk by a count derived
from the workload - "half the entries", "a quarter of the files" -
because that is not pacing: a bigger job simply produces bigger
chunks and the same number of invocations.
- Putting work on a background thread is not a substitute for pacing
it. The threaded queue is optional; the budget is what protects the
frame loop in the configuration that has no worker.
Debug builds report handlers that overrun a frame - see
task_queue_set_slow_handler_cb() - which is the cheapest way to find
out whether a handler you are adding respects any of this.
Commit message density
----------------------
Keep commit message short and appropriate for the size of the change. One or two
paragraphs appropriately sized based on the size of the change. Only explain how the
code works moving forward, not how it worked historically. Latter rule should also apply to code comments.
Miscellaneous
-------------
- Brace usage follows "Allman style". The brace associated with a control statement is placed on the following line,
indented to the same level as the control statement.
Statements within the braces are indented to the next level.
- A single statement block must not include brackets (unless the block uses a macro that expands into multiple lines)
- If possible, avoid 'while (true)' and use 'for (;;)' instead
Struct ordering
---------------
For POD-types, try to order structs as follows (first to last):
* long double (8 bytes, 16 bytes [64bit x86], 12 bytes [32bit x86])
* double (8 bytes)
* int64_t (8 bytes, 8 bytes [32bit ARM], 4 bytes [32bit x86])
* uint64_t (4 bytes [32bit], 8 bytes [32bit ARM], 8 bytes [64bit])
* pointer (4 bytes [32bit], 8 bytes [64bit] [1])
* intptr_t (4 bytes [32bit], 8 bytes [64bit] [1])
* uintptr_t (4 bytes [32bit], 8 bytes [64bit] [1])
* ptrdiff_t (4 bytes [32bit], 8 bytes [64bit] [1])
* ssize_t (4 bytes [32bit], 8 bytes [64bit])
* size_t (4 bytes [32bit], 8 bytes [64bit])
* jmp_buf (4 bytes)
* long (4 bytes [64bit Win], 8 bytes [64bit non-Win], 4 bytes [32bit])
* int32_t (4 bytes)
* unsigned (4 bytes)
* float (4 bytes)
* int (4 bytes)
* enum (4 bytes)
* int16_t (2 bytes)
* char (1 byte)
* bool (1 byte)
[1] PS3 uses 4 byte pointers despite having a 64bit processor
Struct members should be sorted by alignment. Therefore, structs
should be sorted by the largest type inside them.
For example, take a struct like this:
typedef struct
{
size_t capacity;
bool old_format;
bool compress;
bool fuzzy_archive_match;
bool autofix_paths;
char path[PATH_MAX_LENGTH];
char base_content_directory[PATH_MAX_LENGTH];
} playlist_config_t;
size_t has the biggest alignment here, so 'struct playlist_config_t' inside a struct should come before or after size_t.
*** BEST PRACTICES ***
* If we have pointers and size variable pairs, it's best to interleave them to increase the probability they go in the same cacheline. It also makes the code more readable, that these two variables are connected.
Example:
struct a
{
char* b;
size_t b_len;
char* c;
size_t c_len;
};
Stack size
----------
You have to assume that stack size is going to be limited in RetroArch. Some game consoles (and other embedded systems) might have a default stack size as low as 128Kb or less. Be conservative with stack size but don't try to put very small structs on heap either [to avoid memory fragmentation among other things].
Be mindful that heap allocations are slow compared to stack.
+12 -26
View File
@@ -3,7 +3,7 @@
If you are a developer who wishes to contribute to the development of _RetroArch_; or if you have
found a bug and wish to submit a minor patch and/or bug report, please read this document.
Active discussions happen on our [Discord](https://discord.gg/C4amCeV), mostly within
Active discussions happen on our [Discord](https://discordapp.com/invite/27Xxm2h), mostly within
the _Programming_ channel category. We value discussions that happen in real time around
these contributions.
@@ -14,39 +14,25 @@ If there are any issues, we are willing to have discussions about it.
## Submitting Bug Reports
Bug reports for _RetroArch_ may fall into a few categories:
Bug reports in _RetroArch_ may fall into one of two categories:
* _RetroArch_ itself, the user interface and API around all of the various cores.
* Individual _Core_, that interacts with _RetroArch_.
* Supplementary data provided within _RetroArch_, such as controller autoconfigs, databases,
thumbnails...
* The [documentation set](https://docs.libretro.com/)
* Individual _Core_, of which interact with _RetroArch_.
When submitting a bug report, ensure that the report is submitted to the correct repository.
* For _RetroArch_ itself, submit an issue to the [RetroArch](https://github.com/libretro/RetroArch)
repository. Please read and fill the issue template.
* For other cores, please use the search function within the [libretro Organization](https://github.com/libretro)
on GitHub. Issues that are specific to a core and not _RetroArch_ are likely to be closed
very quickly. If an issue is suspected with _RetroArch_, please make sure to test with
multiple cores to be sure that is is not isolated.
* For database content, submit an issue to
[libretro-database repo](https://github.com/libretro/libretro-database) or ask in the
_database_ channel on Discord.
* For controller autoconfigs, submit an issue to
[retroarch-joypad-autoconfig repo](https://github.com/libretro/retroarch-joypad-autoconfig)
* For actual thumbnail images, submit an issue to
[libretro-thumbnails](https://github.com/libretro-thumbnails/libretro-thumbnails) repo
or ask in the _database_ channel on Discord.
* For documentation, submit an issue to [libretro-docs](https://github.com/libretro/libretro-docs)
repo or ask in the _documentation_ channel.
* For translations, please see [here](https://docs.libretro.com/development/retroarch/new-translations-crowdin/).
For _RetroArch_ itself, it is done by reporting a bug within the
[RetroArch](https://github.com/libretro/RetroArch) repository. For other cores, please use
the search function within the [libretro Organization](https://github.com/libretro) on
GitHub. Issues that are specific to a core and not _RetroArch_ are likely to be closed very
quickly. If an issue is suspected with _RetroArch_, please make sure to test with multiple
cores to be sure that is is not isolated.
If the issue occurs during runtime, please paste the verbose log output:
* If using the _Pheonix_ interface, the log will be in _File_ -> _Show Log_.
* If using the main interface, enable verbose logging with _Settings_ -> _Logging_ ->
_Logging Verbosity_. Ensure both _Log to File_ and _Timestamp log Files_ is enabled.
Set frontend log level to _0 (Debug)_.
* Or run _RetroArch_ with the verbose (`-v`) flag and get the log from the console.
* Otherwise, run _RetroArch_ with the verbose (`-v`) flag.
If the error happens during compilation and/or building, paste the output of `./configure`
and `make` accordingly. If using an IDE, please paste any of the errors and log output.
@@ -64,7 +50,7 @@ may be merged in when it is fully approved. The final approval of merge requests
discretion of the project.
If you want to develop a larger feature or make broad changes, please do join our
[Discord](https://discord.gg/C4amCeV) server to discuss. The discussion is
[Discord](https://discordapp.com/invite/27Xxm2h) server to discuss. The discussion is
necessary to prevent the possibility of major work being done which will not be accepted at all.
## libretro API
+163 -306
View File
@@ -1,4 +1,4 @@
# Doxyfile 1.9.1
# Doxyfile 1.8.14
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -17,10 +17,10 @@
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the configuration
# file that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
# The default value is: UTF-8.
@@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = RetroArch
PROJECT_NAME = "RetroArch"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
@@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = docs
OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -93,14 +93,6 @@ ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
@@ -195,17 +187,7 @@ SHORT_NAMES = YES
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = YES
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
# such as
# /***************
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
# Javadoc-style will behave just like regular comments and it will not be
# interpreted by doxygen.
# The default value is: NO.
JAVADOC_BANNER = NO
JAVADOC_AUTOBRIEF = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
@@ -227,14 +209,6 @@ QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
# By default Python docstrings are displayed as preformatted text and doxygen's
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
# doxygen's special commands can be used and the contents of the docstring
# documentation blocks is shown as doxygen documentation.
# The default value is: YES.
PYTHON_DOCSTRING = YES
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
# documentation from any documented member that it re-implements.
# The default value is: YES.
@@ -264,12 +238,14 @@ TAB_SIZE = 4
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
ALIASES = "setby{1}=@par Set by^^The \1."
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
@@ -277,7 +253,7 @@ ALIASES = "setby{1}=@par Set by^^The \1."
# members will be omitted, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_FOR_C = NO
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
@@ -299,40 +275,28 @@ OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
# sources only. Doxygen will then generate output that is more tailored for that
# language. For instance, namespaces will be presented as modules, types will be
# separated into more groups, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_SLICE = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files). For instance to make doxygen treat .inc files
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
# use: inc=Fortran f=C.
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
# Fortran. In the later case the parser tries to guess whether the code is fixed
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen. When specifying no_extension you should add
# * to the FILE_PATTERNS.
#
# Note see also the list of default file extension mappings.
# the files are not read by doxygen.
EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See https://daringfireball.net/projects/markdown/ for details.
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@@ -344,7 +308,7 @@ MARKDOWN_SUPPORT = YES
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
# Minimum value: 0, maximum value: 99, default value: 5.
# Minimum value: 0, maximum value: 99, default value: 0.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
TOC_INCLUDE_HEADINGS = 0
@@ -434,7 +398,7 @@ INLINE_GROUPED_CLASSES = NO
# Man pages) or section (for LaTeX and RTF).
# The default value is: NO.
INLINE_SIMPLE_STRUCTS = YES
INLINE_SIMPLE_STRUCTS = NO
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
# enum is documented as struct, union, or enum with the name of the typedef. So
@@ -460,19 +424,6 @@ TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
# during processing. When set to 0 doxygen will based this on the number of
# cores available in the system. You can set it explicitly to a value larger
# than 0 to get more control over the balance between CPU load and processing
# speed. At this moment only the input processing can be done using multiple
# threads. Since this is still an experimental feature the default is set to 1,
# which efficively disables parallel processing. Please report any issues you
# encounter. Generating dot graphs in parallel is controlled by the
# DOT_NUM_THREADS setting.
# Minimum value: 0, maximum value: 32, default value: 1.
NUM_PROC_THREADS = 16
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@@ -491,13 +442,7 @@ EXTRACT_ALL = YES
# be included in the documentation.
# The default value is: NO.
EXTRACT_PRIVATE = NO
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
# methods of a class will be included in the documentation.
# The default value is: NO.
EXTRACT_PRIV_VIRTUAL = NO
EXTRACT_PRIVATE = YES
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
@@ -536,13 +481,6 @@ EXTRACT_LOCAL_METHODS = YES
EXTRACT_ANON_NSPACES = NO
# If this flag is set to YES, the name of an unnamed parameter in a declaration
# will be determined by the corresponding definition. By default unnamed
# parameters remain unnamed in the output.
# The default value is: YES.
RESOLVE_UNNAMED_PARAMS = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
# undocumented members inside documented classes or files. If set to NO these
# members will be included in the various overviews, but no documentation
@@ -560,8 +498,8 @@ HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# declarations. If set to NO, these declarations will be included in the
# documentation.
# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
@@ -580,18 +518,11 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
# able to match the capabilities of the underlying filesystem. In case the
# filesystem is case sensitive (i.e. it supports files in the same directory
# whose names only differ in casing), the option must be set to YES to properly
# deal with such files in case they appear in the input. For filesystems that
# are not case sensitive the option should be be set to NO to properly deal with
# output files written for symbols that only differ in casing, such as for two
# classes, one named CLASS and the other named Class, and to also support
# references to files without having to specify the exact matching casing. On
# Windows (including Cygwin) and MacOS, users should typically set this option
# to NO, whereas on Linux or other Unix flavors it should typically be set to
# YES.
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
@@ -601,7 +532,7 @@ CASE_SENSE_NAMES = YES
# scope will be hidden.
# The default value is: NO.
HIDE_SCOPE_NAMES = YES
HIDE_SCOPE_NAMES = NO
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
# append additional text to a page's title, such as Class Reference. If set to
@@ -640,7 +571,7 @@ INLINE_INFO = YES
# name. If set to NO, the members will appear in declaration order.
# The default value is: YES.
SORT_MEMBER_DOCS = NO
SORT_MEMBER_DOCS = YES
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
# descriptions of file, namespace and class members alphabetically by member
@@ -823,17 +754,13 @@ WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# parameter documentation, but not about the absence of documentation.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
# at the end of the doxygen process doxygen will return with a non-zero status.
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# a warning is encountered.
# The default value is: NO.
WARN_AS_ERROR = NO
@@ -864,13 +791,13 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = libretro-common
INPUT =
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see:
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
# possible encodings.
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
@@ -883,17 +810,56 @@ INPUT_ENCODING = UTF-8
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
# Note the list of default checked file patterns might differ from the list of
# default file extension mappings.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
# *.ucf, *.qsf and *.ice.
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
FILE_PATTERNS = *.h
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.idl \
*.ddl \
*.odl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.cs \
*.d \
*.php \
*.php4 \
*.php5 \
*.phtml \
*.inc \
*.m \
*.markdown \
*.md \
*.mm \
*.dox \
*.py \
*.pyw \
*.f90 \
*.f95 \
*.f03 \
*.f08 \
*.f \
*.for \
*.tcl \
*.vhd \
*.vhdl \
*.ucf \
*.qsf
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@@ -924,11 +890,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS = */libretro-common/rthreads/* \
*/libretro-common/formats/* \
*/libretro-common/crt/* \
*/libretro-common/samples/* \
*/libretro-common/include/glsym/*
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -939,9 +901,7 @@ EXCLUDE_PATTERNS = */libretro-common/rthreads/* \
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
EXCLUDE_SYMBOLS = bool \
void \
const
EXCLUDE_SYMBOLS =
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
# that contain example code fragments that are included (see the \include
@@ -1052,7 +1012,7 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# entity all documented functions referencing it will be listed.
# function all documented functions referencing it will be listed.
# The default value is: NO.
REFERENCED_BY_RELATION = NO
@@ -1089,7 +1049,7 @@ SOURCE_TOOLTIPS = YES
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
@@ -1111,44 +1071,6 @@ USE_HTAGS = NO
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see:
# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
# performance. This can be particularly helpful with template rich C++ code for
# which doxygen's built-in parser lacks the necessary type information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to
# YES then doxygen will add the directory of each input to the include path.
# The default value is: YES.
CLANG_ADD_INC_PATHS = YES
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the directory containing a file called compile_commands.json. This
# file is the compilation database (see:
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
# options used when the source files were built. This is equivalent to
# specifying the -p option to a clang tool, such as clang-check. These options
# will then be passed to the parser. Any options specified with CLANG_OPTIONS
# will be added as well.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
@@ -1160,14 +1082,20 @@ CLANG_DATABASE_PATH =
ALPHABETICAL_INDEX = YES
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX = retro_ \
RETRO_
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
@@ -1299,9 +1227,9 @@ HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via JavaScript. If disabled, the navigation index will
# are dynamically created via Javascript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
# page. Disable this option to support browsers that do not have JavaScript,
# page. Disable this option to support browsers that do not have Javascript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1331,14 +1259,13 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see:
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
# create a documentation set, doxygen will generate a Makefile in the HTML
# output directory. Running make will produce the docset in that directory and
# running make install will install the docset in
# environment (see: https://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1377,8 +1304,8 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see:
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
@@ -1408,7 +1335,7 @@ CHM_FILE =
HHC_LOCATION =
# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the main .chm file (NO).
# (YES) or that it should be included in the master .chm file (NO).
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@@ -1453,8 +1380,7 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1462,8 +1388,7 @@ QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1471,30 +1396,28 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
# The QHG_LOCATION tag can be used to specify the location (absolute path
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
# run qhelpgenerator on the generated .qhp file.
# The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
# generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
@@ -1545,7 +1468,7 @@ DISABLE_INDEX = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = YES
GENERATE_TREEVIEW = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
@@ -1571,17 +1494,6 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
# the HTML output. These images will generally look nicer at scaled resolutions.
# Possible values are: png (the default) and svg (looks nicer but requires the
# pdf2svg or inkscape tool).
# The default value is: png.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FORMULA_FORMAT = png
# Use this tag to change the font size of LaTeX formulas included as images in
# the HTML documentation. When you change the font size after a successful
# doxygen run you need to manually remove any form_*.png images from the HTML
@@ -1602,14 +1514,8 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
FORMULA_MACROFILE =
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# https://www.mathjax.org) which uses client side JavaScript for the rendering
# https://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@@ -1621,7 +1527,7 @@ USE_MATHJAX = NO
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
# http://docs.mathjax.org/en/latest/output.html) for more details.
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# The default value is: HTML-CSS.
@@ -1637,7 +1543,7 @@ MATHJAX_FORMAT = HTML-CSS
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
@@ -1651,8 +1557,7 @@ MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
# (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
@@ -1680,7 +1585,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using JavaScript. There
# implemented using a web server instead of a web client using Javascript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
@@ -1699,8 +1604,7 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see:
# https://xapian.org/).
# Xapian (see: https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@@ -1713,9 +1617,8 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see:
# https://xapian.org/). See the section "External Indexing and Searching" for
# details.
# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
@@ -1766,35 +1669,21 @@ LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
# chosen this is overwritten by pdflatex. For specific output languages the
# default can have been set differently, this depends on the implementation of
# the output language.
# Note that when enabling USE_PDFLATEX this option is only used for generating
# bitmaps for formulas in the HTML output, but not in the Makefile that is
# written to the output directory.
# The default file is: latex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
# Note: This tag is used in the Makefile / make.bat.
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
# (.tex).
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = makeindex
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
# generate index for LaTeX. In case there is no backslash (\) as first character
# it will be automatically added in the LaTeX code.
# Note: This tag is used in the generated output file (.tex).
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
# The default value is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_MAKEINDEX_CMD = makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
@@ -1879,11 +1768,9 @@ LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
# files. Set this option to YES, to get a higher quality PDF documentation.
#
# See also section LATEX_CMD_NAME for selecting the engine.
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
# higher quality PDF documentation.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1931,14 +1818,6 @@ LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
# LATEX_OUTPUT directory will be used.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -1978,9 +1857,9 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# configuration file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
# file, i.e. a series of assignments. You only have to provide replacements,
# missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
@@ -1989,8 +1868,8 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's configuration file. A template extensions file can be
# generated using doxygen -e rtf extensionFile.
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
@@ -2076,13 +1955,6 @@ XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
# namespace members in file scope as well, matching the HTML output.
# The default value is: NO.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
@@ -2122,10 +1994,6 @@ DOCBOOK_PROGRAMLISTING = NO
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to Sqlite3 output
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
@@ -2221,7 +2089,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DOXYGEN
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2288,6 +2156,12 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
@@ -2299,7 +2173,16 @@ EXTERNAL_PAGES = YES
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = NO
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
@@ -2319,9 +2202,9 @@ HIDE_UNDOC_RELATIONS = YES
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: YES.
# The default value is: NO.
HAVE_DOT = NO
HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
@@ -2398,31 +2281,9 @@ UML_LOOK = NO
# but if the number exceeds 15, the total amount of fields shown is limited to
# 10.
# Minimum value: 0, maximum value: 100, default value: 10.
# This tag requires that the tag UML_LOOK is set to YES.
UML_LIMIT_NUM_FIELDS = 10
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
# tag is set to YES, doxygen will add type and arguments for attributes and
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
# will not generate fields with class member information in the UML graphs. The
# class diagrams will look similar to the default class diagrams but using UML
# notation for the relationships.
# Possible values are: NO, YES and NONE.
# The default value is: NO.
# This tag requires that the tag UML_LOOK is set to YES.
DOT_UML_DETAILS = NO
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
# to display on a single line. If the actual line length exceeds this threshold
# significantly it will wrapped across multiple lines. Some heuristics are apply
# to avoid ugly line breaks.
# Minimum value: 0, maximum value: 1000, default value: 17.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_WRAP_THRESHOLD = 17
UML_LIMIT_NUM_FIELDS = 10
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
# collaboration graphs will show the relations between templates and their
@@ -2497,9 +2358,7 @@ DIRECTORY_GRAPH = YES
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
# png:gdiplus:gdiplus.
# The default value is: png.
@@ -2615,11 +2474,9 @@ DOT_MULTI_TARGETS = YES
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
# files that are used to generate the various graphs.
#
# Note: This setting is not only used for dot files but also for msc and
# plantuml temporary files.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_CLEANUP = YES
Loaded 100 of 8201 files, more files were not shown because too many files have changed in this diff. Show more