feat: profile the retroarch frontend config reads

AmberELEC and ROCKNIX install a retroarch.cfg whose system_directory
points every core at the BIOS folder. retroarch.yml (type utility, no
file, no system) reads that key, and ROCKNIX's systemfiles_in_content_dir,
at the RetroArch each one compiles: v1.22.2 and bdba046f. all_libretro
never picks a utility profile, and lists naming retroarch gain no file.

A libretro core option a frontend record writes stays the core's to
read: RetroDECK's pcsx2_bios keeps lrps2 as its reader.
This commit is contained in:
Abdessamad Derraz committed 2026-11-11 12:06:28 +01:00
1 parent 8770b9c067
commit b8ed9b735a
3 files changed
+96 -2

No files matched your search

+58
View File
@@ -0,0 +1,58 @@
emulator: "RetroArch"
type: utility
core_classification: other
source: "https://github.com/libretro/RetroArch"
upstream: "https://github.com/libretro/RetroArch"
profiled_date: "2026-11-11"
source_commit: "69a4f0ea1e8aaf442ae4858f2e7f2b31a1776576"
core_version: "v1.22.2"
version_basis:
kind: tag
tag: "v1.22.2"
distance: 0
display_name: "RetroArch (libretro frontend)"
cores:
- retroarch
systems: []
pin_build:
- platform: amberelec
repo: "https://github.com/AmberELEC/AmberELEC"
revision: "a21975bfb1a3af68f66e07a931b994b523e1e6e2"
path: "packages/games/tools/retroarch/package.mk"
variable: PKG_VERSION
value: "69a4f0ea1e8aaf442ae4858f2e7f2b31a1776576"
- platform: rocknix
repo: "https://github.com/ROCKNIX/distribution"
revision: "20261101"
path: "projects/ROCKNIX/packages/emulators/libretro/retroarch/package.mk"
variable: PKG_VERSION
value: "bdba046fa6766380bc2457532f38e589df769aaf"
config_reads:
- file: "retroarch.cfg"
platforms: [amberelec]
source_ref: "retroarch.c:6968-6969, 7148-7155, 7244, configuration.c:3469, 3779, 3824, 3863-3884, 5014-5018, libretro-common/file/config_file.c:840"
keys:
- key: "system_directory"
source_ref: "configuration.c:1645, 4063-4069, 4110-4115, 4346-4347, libretro-common/file/config_file.c:1180-1189, libretro-common/file/file_path.c:1060-1098, runloop.c:1935-1976"
condition: "systemfiles_in_content_dir false (its default, config.def.h:925); LIBRETRO_SYSTEM_DIRECTORY in the environment replaces the value, an empty value hands the content's folder"
- file: "retroarch.cfg"
platforms: [rocknix]
source_ref: "retroarch.c:7272-7273, 7452-7459, 7548, configuration.c:3565, 3886, 3931, 3970-4010, 5174-5176, libretro-common/file/config_file.c:817"
keys:
- key: "system_directory"
source_ref: "configuration.c:1688, 4193-4199, 4240-4245, 4494-4495, libretro-common/file/config_file.c:1190-1199, libretro-common/file/file_path.c:1066-1100, runloop.c:1949-1990"
condition: "systemfiles_in_content_dir false; LIBRETRO_SYSTEM_DIRECTORY in the environment replaces the value, an empty value hands the content's folder"
- key: "systemfiles_in_content_dir"
source_ref: "configuration.c:1870, runloop.c:1949-1990"
condition: "true hands the content's folder in place of system_directory"
notes: |
The libretro frontend. It loads each core and answers
RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY with the system_directory of the
config it was started with (-c, else the default path), a leading ~
expanded to $HOME. The cores read their BIOS files below that folder, so
their profiles hold the files and this one holds none.
ref: retroarch.c:7148-7155, configuration.c:3824, runloop.c:1935-1976
files: []
+10 -2
View File
@@ -468,7 +468,12 @@ def config_evidence(
readers: list[str] = []
uncovered = list(keys)
loaded = False
for key in _named_profiles(record, profiles, platform) or sorted(profiles):
named = _named_profiles(record, profiles, platform)
if file == CORE_OPTIONS:
# A core option is read by the core RetroArch runs, not by the
# frontend a record names (RetroDECK's retroarch component).
named = [k for k in named if "libretro" in str(profiles[k].get("type") or "")]
for key in named or sorted(profiles):
profile = profiles[key]
handles = _handle_refs(profile)
for read in profile.get("config_reads") or []:
@@ -1319,7 +1324,10 @@ class LauncherLayer:
for key in self._profiles_named(emulator, profiles, relevant)
}
# RetroDECK names its frontend, retroarch, and the core option it
# writes, pcsx2_bios, names the core.
# writes, pcsx2_bios, names the core: a libretro core option
# belongs to a libretro core.
if place.build == "libretro" and place.kind == "core_option":
owners = {k for k in owners if "libretro" in str(profiles[k].get("type") or "")}
if not owners:
owners = set(setting_readers(place.passes_to, profiles, relevant))
for key in sorted(owners):
+28
View File
@@ -265,6 +265,34 @@ class Invariants(unittest.TestCase):
self.assertEqual(_config_reads_without_build(path, {"config_reads": closed}), [])
class CoreOptions(unittest.TestCase):
def test_a_core_option_is_read_by_the_core_not_the_frontend(self) -> None:
"""RetroDECK's retroarch component writes pcsx2_bios: the frontend
names the record, the core RetroArch runs reads the option."""
profiles = {
"retroarch": {"emulator": "RetroArch", "type": "utility", "cores": ["retroarch"],
"config_reads": [{"file": "retroarch.cfg", "source_ref": "a.c:1",
"keys": [{"key": "system_directory",
"source_ref": "a.c:2"}]}]},
"lrps2": {"emulator": "LRPS2", "type": "libretro", "cores": ["lrps2"],
"config_reads": [{"file": "core options", "source_ref": "main.cpp:1",
"keys": [{"key": "pcsx2_bios",
"source_ref": "main.cpp:2"}]}]},
}
option = {
"emulator": "retroarch", "build": "libretro", "kind": "core_option",
"names": ["scph10000.bin"], "passes_to": "core option pcsx2_bios",
"installs": {"path": "$core_options", "source_ref": "prepare.sh:24"},
"overrides": [], "source_ref": "rd_config/retroarch-core-options.cfg:515",
}
evidence = config_evidence(option, profiles, "retrodeck")
self.assertTrue(evidence.proven, evidence.missing)
self.assertEqual(evidence.readers, ("lrps2",))
system = {**option, "kind": "passes_path", "passes_to": "retroarch.cfg system_directory",
"source_ref": "rd_config/retroarch.cfg:44"}
self.assertEqual(config_evidence(system, profiles, "retrodeck").readers, ("retroarch",))
class BuildRefs(unittest.TestCase):
def test_reads_for_a_shipped_build_are_read_at_that_build(self) -> None:
document = {