diff --git a/README.md b/README.md index b83885a2..8553082d 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/recompiler/src/main_cli.cpp b/recompiler/src/main_cli.cpp index 3acb7f54..69e85273 100644 --- a/recompiler/src/main_cli.cpp +++ b/recompiler/src/main_cli.cpp @@ -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" diff --git a/recompiler/tests/test_cli_project_packaging.py b/recompiler/tests/test_cli_project_packaging.py index 518dd6e3..10e82334 100644 --- a/recompiler/tests/test_cli_project_packaging.py +++ b/recompiler/tests/test_cli_project_packaging.py @@ -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') diff --git a/tools/new_project_layout/templates/CMakeLists.txt.in b/tools/new_project_layout/templates/CMakeLists.txt.in index 21406e0d..d5f4ddf0 100644 --- a/tools/new_project_layout/templates/CMakeLists.txt.in +++ b/tools/new_project_layout/templates/CMakeLists.txt.in @@ -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=.") +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() - diff --git a/tools/new_project_layout/templates/README.md.in b/tools/new_project_layout/templates/README.md.in index 539116c3..f978342d 100644 --- a/tools/new_project_layout/templates/README.md.in +++ b/tools/new_project_layout/templates/README.md.in @@ -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=` when intentionally building against a +separate framework checkout. + Zip prefix for CI artifacts: `@ZIP_PREFIX@`. ## Symbols