docs: explain generated project framework requirement

This commit is contained in:
Matthew Stanley
2026-08-23 11:53:57 -07:00
parent b38edca8e2
commit 239052f166
5 changed files with 66 additions and 4 deletions
+7
View File
@@ -489,6 +489,13 @@ pinned SDL3 release automatically. Then run:
powershell -ExecutionPolicy Bypass -File "C:\Projects\MyGameRecomp\build.ps1"
```
The generated project must keep the `psxrecomp/` framework folder beside
`CMakeLists.txt`; that folder contains `runtime/runtime.cmake`. If CMake says it
cannot find that file, the framework tree is missing or incomplete. For a git
checkout, run `git submodule update --init --recursive` from the project root.
For a project made by the released `psxrecomp.exe`, regenerate it from the full
CLI zip and keep the generated `psxrecomp/` folder.
The generated project also includes a shell build script for macOS and Linux:
```sh
+24 -1
View File
@@ -381,10 +381,17 @@ int build_project(const Options& options, const fs::path& exe_dir) {
const std::string cmake = fmt::format(
"cmake_minimum_required(VERSION 3.20)\n"
"set(PSXRECOMP_ROOT \"${{CMAKE_CURRENT_SOURCE_DIR}}/psxrecomp\")\n"
"if(NOT EXISTS \"${{PSXRECOMP_ROOT}}/runtime/runtime.cmake\")\n"
" message(FATAL_ERROR\n"
" \"PSXRecomp runtime is missing: ${{PSXRECOMP_ROOT}}/runtime/runtime.cmake\\n\"\n"
" \"This generated project needs the psxrecomp framework tree at ${{PSXRECOMP_ROOT}}.\\n\"\n"
" \"If this project came from git, run: git submodule update --init --recursive\\n\"\n"
" \"If this project came from psxrecomp.exe, regenerate it from the full CLI zip and keep the generated psxrecomp/ folder.\")\n"
"endif()\n"
"project({} C CXX)\n"
"set(CMAKE_C_STANDARD 99)\n"
"set(CMAKE_CXX_STANDARD 17)\n"
"set(PSXRECOMP_ROOT \"${{CMAKE_CURRENT_SOURCE_DIR}}/psxrecomp\")\n"
"set(PSX_RECOMP_UI OFF CACHE BOOL \"\" FORCE)\n"
"set(PSXRECOMP_BIOS_STEMS \"{}\" CACHE STRING \"\" FORCE)\n"
"include(\"${{PSXRECOMP_ROOT}}/runtime/runtime.cmake\")\n"
@@ -404,6 +411,11 @@ int build_project(const Options& options, const fs::path& exe_dir) {
write_file(options.output / "build.ps1",
"$ErrorActionPreference = 'Stop'\n"
"$Root = Split-Path -Parent $MyInvocation.MyCommand.Path\n"
"$RuntimeCMake = Join-Path $Root 'psxrecomp/runtime/runtime.cmake'\n"
"if (-not (Test-Path -LiteralPath $RuntimeCMake)) {\n"
" Write-Error \"PSXRecomp runtime is missing: $RuntimeCMake`nThis generated project needs the psxrecomp framework tree at '$Root\\psxrecomp'.`nIf this project came from git, run: git submodule update --init --recursive`nIf this project came from psxrecomp.exe, regenerate it from the full CLI zip and keep the generated psxrecomp folder.\"\n"
" exit 1\n"
"}\n"
"cmake -S $Root -B (Join-Path $Root 'build') -G Ninja -DCMAKE_BUILD_TYPE=Release -DPSX_RECOMP_UI=OFF\n"
"if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }\n"
"cmake --build (Join-Path $Root 'build') --config Release --parallel\n"
@@ -412,6 +424,13 @@ int build_project(const Options& options, const fs::path& exe_dir) {
"#!/usr/bin/env sh\n"
"set -eu\n"
"ROOT=$(CDPATH= cd -- \"$(dirname -- \"$0\")\" && pwd)\n"
"if [ ! -f \"$ROOT/psxrecomp/runtime/runtime.cmake\" ]; then\n"
" echo \"error: PSXRecomp runtime is missing: $ROOT/psxrecomp/runtime/runtime.cmake\" >&2\n"
" echo \"This generated project needs the psxrecomp framework tree at $ROOT/psxrecomp.\" >&2\n"
" echo \"If this project came from git, run: git submodule update --init --recursive\" >&2\n"
" echo \"If this project came from psxrecomp.exe, regenerate it from the full CLI zip and keep the generated psxrecomp folder.\" >&2\n"
" exit 1\n"
"fi\n"
"cmake -S \"$ROOT\" -B \"$ROOT/build\" -G Ninja -DCMAKE_BUILD_TYPE=Release -DPSX_RECOMP_UI=OFF\n"
"cmake --build \"$ROOT/build\" --config Release --parallel\n");
write_file(options.output / ".gitignore",
@@ -422,6 +441,10 @@ int build_project(const Options& options, const fs::path& exe_dir) {
"## Build\n\n"
"Install CMake, Ninja, and a C/C++ compiler. SDL3 is fetched automatically.\n"
"Then run `sh build.sh` on macOS/Linux or `.\\build.ps1` in PowerShell.\n\n"
"This project must keep the generated `psxrecomp/` framework folder beside\n"
"`CMakeLists.txt`. If it is missing, restore it from source control with\n"
"`git submodule update --init --recursive` or regenerate the project from\n"
"the full PSXRecomp CLI zip.\n\n"
"SDL3 is the default. To use SDL2 explicitly, configure once with\n"
"`cmake -S . -B build -DPSX_SDL_BACKEND=SDL2`; later build-script runs\n"
"preserve that cached selection.\n\n"
@@ -17,6 +17,9 @@ def main() -> int:
cli = (ROOT / "recompiler/src/main_cli.cpp").read_text(encoding="utf-8")
bios = (ROOT / "recompiler/src/main_bios.cpp").read_text(encoding="utf-8")
package = (ROOT / "tools/build_cli.py").read_text(encoding="utf-8")
new_project_cmake = (
ROOT / "tools/new_project_layout/templates/CMakeLists.txt.in"
).read_text(encoding="utf-8")
require(cli, 'bios_config = \\"psxrecomp/bios/{}\\"',
"generated game.toml does not name its BIOS profile")
@@ -33,6 +36,23 @@ def main() -> int:
require(cli, 'set(PSX_RECOMP_UI OFF CACHE BOOL \\"\\" FORCE)',
"self-contained CLI projects must not require a game-owned "
"recomp-ui checkout")
require(cli, 'PSXRecomp runtime is missing:',
"generated CLI project does not fail clearly when psxrecomp/ "
"is missing")
require(cli, 'git submodule update --init --recursive',
"generated CLI project missing-runtime error lacks the git "
"submodule recovery command")
require(cli, '$RuntimeCMake = Join-Path $Root',
"generated PowerShell build script lacks a runtime.cmake "
"preflight")
require(cli, '[ ! -f \\"$ROOT/psxrecomp/runtime/runtime.cmake\\" ]',
"generated shell build script lacks a runtime.cmake preflight")
require(new_project_cmake, 'PSXRecomp runtime is missing:',
"new-project-layout CMake template does not fail clearly when "
"psxrecomp/ is missing")
require(new_project_cmake, 'git submodule update --init --recursive',
"new-project-layout missing-runtime error lacks the git "
"submodule recovery command")
copy_pos = cli.find('fmt::print("[1/4] Copying build framework')
game_pos = cli.find('fmt::print("[2/4] Recompiling game executable')
@@ -1,8 +1,15 @@
cmake_minimum_required(VERSION 3.20)
project(@PROJECT_CMAKE_NAME@ LANGUAGES C CXX)
set(PSXRECOMP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/psxrecomp" CACHE PATH
"Path to psxrecomp")
if(NOT EXISTS "${PSXRECOMP_ROOT}/runtime/runtime.cmake")
message(FATAL_ERROR
"PSXRecomp runtime is missing: ${PSXRECOMP_ROOT}/runtime/runtime.cmake\n"
"This project expects the psxrecomp framework checkout at ${PSXRECOMP_ROOT}.\n"
"Run: git submodule update --init --recursive\n"
"If psxrecomp/ is not a submodule, set -DPSXRECOMP_ROOT=<path-to-psxrecomp>.")
endif()
project(@PROJECT_CMAKE_NAME@ LANGUAGES C CXX)
# --- Opt-in product surfaces (OFF by default in the framework) -------------
# Scaffold prompts / flags fill these. Without recomp-ui, PSX_RECOMP_UI is OFF.
@@ -39,4 +46,3 @@ foreach(_PSX_RUNTIME_CONFIG game.toml game_options.toml)
VERBATIM)
endif()
endforeach()
@@ -39,6 +39,12 @@ cmake -S . -B build-release -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build-release --target psx-runtime
```
`psxrecomp/runtime/runtime.cmake` must exist before configuring. If CMake says
the runtime is missing, the framework submodule is not checked out; run
`git submodule update --init --recursive`, or pass
`-DPSXRECOMP_ROOT=<path-to-psxrecomp>` when intentionally building against a
separate framework checkout.
Zip prefix for CI artifacts: `@ZIP_PREFIX@`.
## Symbols