#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$( cd -- "$(dirname -- "${BASH_SOURCE[0]}")" pwd )" CORE_DIR="$ROOT_DIR/third_party/NP2kai/sdl" # Apply the small PS4-specific core patch before validating or compiling. "$ROOT_DIR/tools/apply-np2kai-patches.sh" MAKEFILE="$CORE_DIR/Makefile.libretro" LOG_FILE="$ROOT_DIR/np2kai-ps4-core-build.log" BUILD_JOBS="${NP2KAI_BUILD_JOBS:-1}" if [[ ! "$BUILD_JOBS" =~ ^[1-9][0-9]*$ ]]; then echo "ERROR: NP2KAI_BUILD_JOBS debe ser un entero mayor que cero." exit 1 fi if [[ -z "${OO_PS4_TOOLCHAIN:-}" ]]; then echo "ERROR: OO_PS4_TOOLCHAIN is not set." echo 'Run: export OO_PS4_TOOLCHAIN="$HOME/Dev/PS4/OpenOrbis/PS4Toolchain"' exit 1 fi if [[ ! -d "$OO_PS4_TOOLCHAIN/include" ]]; then echo "ERROR: Invalid OpenOrbis toolchain: $OO_PS4_TOOLCHAIN" exit 1 fi for tool in clang clang++ make python3; do if ! command -v "$tool" >/dev/null 2>&1; then echo "ERROR: Required tool not found: $tool" exit 1 fi done if command -v llvm-ar >/dev/null 2>&1; then AR_BIN="$(command -v llvm-ar)" elif command -v ar >/dev/null 2>&1; then AR_BIN="$(command -v ar)" else echo "ERROR: Neither llvm-ar nor ar was found." exit 1 fi # Remove the reject left by the first patch attempt. rm -f "$MAKEFILE.rej" if ! grep -q 'platform), ps4' "$MAKEFILE"; then echo "Adding OpenOrbis platform block while preserving line endings..." MAKEFILE_PATH="$MAKEFILE" python3 <<'PY' from pathlib import Path import os import re import sys path = Path(os.environ["MAKEFILE_PATH"]) raw = path.read_bytes() # Preserve the Makefile's existing newline convention. newline = b"\r\n" if b"\r\n" in raw else b"\n" anchor_re = re.compile( rb"(?m)^# PS2\r?\n" rb"else ifeq \(\$\(platform\), ps2\)\r?\n" ) match = anchor_re.search(raw) if match is None: print("ERROR: Could not locate the PS2 platform block.", file=sys.stderr) sys.exit(1) lines = [ b"# PS4 / OpenOrbis", b"else ifeq ($(platform), ps4)", b"\tifeq ($(OO_PS4_TOOLCHAIN),)", b"\t\t$(error OO_PS4_TOOLCHAIN must point to the OpenOrbis PS4Toolchain directory)", b"\tendif", b"", b"\tTARGET := $(TARGET_NAME)_libretro_ps4.a", b"", b"\tCC = clang", b"\tCXX = clang++", b"\tAR = llvm-ar", b"", b"\t# PS4 is little-endian x86-64. Build PIC for the PIE eboot.", b"\tENDIANNESS_DEFINES := -DLSB_FIRST -DLOCAL_LE=1", b"\tPLATFORM_DEFINES := -D__ORBIS__ -D__PS4__ -DORBIS -DPS4", b"\tPLATFORM_DEFINES += --target=x86_64-pc-freebsd12-elf", b"\tPLATFORM_DEFINES += -isysroot $(OO_PS4_TOOLCHAIN)", b"\tPLATFORM_DEFINES += -isystem $(OO_PS4_TOOLCHAIN)/include", b"\tPLATFORM_DEFINES += -funwind-tables", b"", b"\t# Only C++ translation units need the libc++ headers.", b"\tCXXFLAGS += -isystem $(OO_PS4_TOOLCHAIN)/include/c++/v1", b"", b"\tfpic := -fPIC", b"\tSTATIC_LINKING = 1", b"\tDISABLE_GCC_SECURITY_FLAGS = 1", b"", b"\t# First portability pass: avoid thread/async dependencies.", b"\tSUPPORT_NP2_THREAD = 0", b"\tSUPPORT_ASYNC_CPU = 0", b"", ] block = newline.join(lines) + newline patched = raw[:match.start()] + block + raw[match.start():] path.write_bytes(patched) print( "Inserted PS4 platform block using " + ("CRLF" if newline == b"\r\n" else "LF") + " line endings." ) PY fi if ! grep -q 'platform), ps4' "$MAKEFILE"; then echo "ERROR: The PS4 platform block is still missing." exit 1 fi exec > >(tee "$LOG_FILE") 2>&1 echo "== NP2kai PS4 static-core build ==" echo "Toolchain : $OO_PS4_TOOLCHAIN" echo "Compiler : $(command -v clang)" echo "C++ : $(command -v clang++)" echo "Archiver : $AR_BIN" echo "Core dir : $CORE_DIR" echo "Jobs : $BUILD_JOBS" echo cd "$CORE_DIR" # Serial first build: keep the first portability error readable. make -f Makefile.libretro \ platform=ps4 \ NP2KAI_VERSION=rev.22 \ NP2KAI_HASH=e2dc904 \ CC=clang \ CXX=clang++ \ AR="$AR_BIN" \ clean make -f Makefile.libretro \ platform=ps4 \ NP2KAI_VERSION=rev.22 \ NP2KAI_HASH=e2dc904 \ CC=clang \ CXX=clang++ \ AR="$AR_BIN" \ -j"$BUILD_JOBS" TARGET="$CORE_DIR/np2kai_libretro_ps4.a" echo echo "== Result ==" if [[ ! -f "$TARGET" ]]; then echo "ERROR: Build finished without producing $TARGET" exit 1 fi file "$TARGET" ls -lh "$TARGET" echo echo "First archive members:" "$AR_BIN" t "$TARGET" | head -20 || true echo echo "SUCCESS: $TARGET"