cmake: generate the game database without needing sh

libretro-build-windows-x64 fails in the GameDatabaseBuiltin.cpp step:

  Generating GameDatabaseBuiltin.cpp from GameIndex.yaml
  'sh' is not recognized as an internal or external command
  error MSB8066: Custom build ... exited with code 9009

The custom command shells out to tools/gen_gamedb_builtin.sh, and the MSVC
runner has no sh (nor od or awk). Drive the same generation through CMake's
own script mode instead, so the only dependency is the CMake already running
the build.

Verified against the shell version on the shipped GameIndex.yaml: both emit
1819912 bytes, matching the input exactly, and the two byte sequences are
identical. The generated file also passes a compile check.

The .sh stays for the static-Makefile rule, which is POSIX-only anyway; both
now carry a note to keep them in sync.

One CMake wrinkle worth recording: its regex flavour has no {n} repetition,
so the 20-bytes-per-row split is built by repeating the pattern in a loop.
Written the obvious way it silently does nothing and emits the whole array
as a single 9MB line.
This commit is contained in:
WizzardSK committed 2026-08-26 21:58:20 +02:00
1 parent a81d2f59d8
commit 543eed9aec
3 files changed
+58 -6

No files matched your search

+10 -6
View File
@@ -1,14 +1,18 @@
# All flags, libraries, etc, that are shared between PCSX2 compilation files
# GameDatabaseBuiltin.cpp is generated from the shipped GameIndex.yaml at
# build time (tools/gen_gamedb_builtin.sh, POSIX shell + od + awk only),
# mirroring the static-Makefile rule.
# build time. Driven through CMake's own script mode rather than the shell
# version in tools/gen_gamedb_builtin.sh: the MSVC Windows runner has no sh,
# where the shell rule failed with "'sh' is not recognized as an internal or
# external command". The .sh stays for the static-Makefile rule, which is
# POSIX-only anyway - keep the two in sync.
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/GameDatabaseBuiltin.cpp
COMMAND sh ${CMAKE_SOURCE_DIR}/tools/gen_gamedb_builtin.sh
${CMAKE_SOURCE_DIR}/bin/resources/GameIndex.yaml
${CMAKE_CURRENT_BINARY_DIR}/GameDatabaseBuiltin.cpp
COMMAND ${CMAKE_COMMAND}
-DYAML=${CMAKE_SOURCE_DIR}/bin/resources/GameIndex.yaml
-DOUT=${CMAKE_CURRENT_BINARY_DIR}/GameDatabaseBuiltin.cpp
-P ${CMAKE_SOURCE_DIR}/tools/gen_gamedb_builtin.cmake
DEPENDS ${CMAKE_SOURCE_DIR}/bin/resources/GameIndex.yaml
${CMAKE_SOURCE_DIR}/tools/gen_gamedb_builtin.sh
${CMAKE_SOURCE_DIR}/tools/gen_gamedb_builtin.cmake
COMMENT "Generating GameDatabaseBuiltin.cpp from GameIndex.yaml"
VERBATIM)
+46
View File
@@ -0,0 +1,46 @@
# Generate GameDatabaseBuiltin.cpp from bin/resources/GameIndex.yaml.
#
# Script-mode CMake, so the only dependency is the CMake already running the
# build. The shell version this replaces needed sh + od + awk, which the MSVC
# Windows runner does not have ("'sh' is not recognized as an internal or
# external command").
#
# Usage: cmake -DYAML=<in> -DOUT=<out.cpp> -P gen_gamedb_builtin.cmake
if(NOT DEFINED YAML OR NOT DEFINED OUT)
message(FATAL_ERROR "YAML and OUT must be set")
endif()
file(READ "${YAML}" hex HEX)
if(hex STREQUAL "")
message(FATAL_ERROR "${YAML} is empty or unreadable")
endif()
# "0a1b..." -> "0x0a,0x1b,...", then a newline every 20 bytes so the generated
# file is not one multi-megabyte line.
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," body "${hex}")
# CMake's regex has no {n} repetition, so the 20-byte row is spelled out.
set(row "")
foreach(i RANGE 1 20)
string(APPEND row "0x..,")
endforeach()
string(REGEX REPLACE "(${row})" "\\1\n\t" body "${body}")
file(WRITE "${OUT}"
"// Auto-generated from bin/resources/GameIndex.yaml. Do not edit by hand.
// Generated at build time by tools/gen_gamedb_builtin.cmake.
//
// Embeds the PCSX2 game-compatibility database into the core so it works
// without an external <systemdir>/resources/GameIndex.yaml.
#include <cstddef>
extern const unsigned char g_gameDatabaseBuiltin[];
extern const size_t g_gameDatabaseBuiltinSize;
const unsigned char g_gameDatabaseBuiltin[] = {
\t${body}
};
const size_t g_gameDatabaseBuiltinSize = sizeof(g_gameDatabaseBuiltin);
")
+2
View File
@@ -1,6 +1,8 @@
#!/bin/sh
# Generate GameDatabaseBuiltin.cpp from bin/resources/GameIndex.yaml.
# POSIX shell + od + awk only -- no new build dependencies.
# Used by the static Makefile. The CMake build drives gen_gamedb_builtin.cmake
# instead, because the MSVC Windows runner has no sh; keep the two in sync.
# Usage: gen_gamedb_builtin.sh <yaml> <out.cpp>
set -e
YAML="$1"; OUT="$2"