From a2c3ae112b2263bb9c457207fa703a08ad753d67 Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Tue, 13 Jan 2026 16:29:02 -0500 Subject: [PATCH 1/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- data/core.json | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/data/core.json b/data/core.json index 2cfaf14..3f14e61 100755 --- a/data/core.json +++ b/data/core.json @@ -582,6 +582,27 @@ "mv build/flycast_libretro.so ." ] } + }, + "ffmpeg": { + "source": "https://github.com/libretro/RetroArch.git", + "branch": "a8d0ad0", + "directory": "libretro-ffmpeg", + "output": "ffmpeg_libretro.so", + "make": { + "file": "Makefile", + "args": "-C cores/libretro-ffmpeg HAVE_SSA=0", + "target": "" + }, + "symbols": 0, + "commands": { + "pre-make": [ + "./configure", + "cd cores/libretro-ffmpeg" + ], + "post-make": [ + "mv cores/libretro-ffmpeg/ffmpeg_libretro.so ." + ] + } }, "morpheuscast_xtreme": { "source": "https://github.com/KMFDManic/morpheuscast_xtreme", @@ -1022,6 +1043,29 @@ }, "symbols": 0 }, + "mame": { + "source": "https://github.com/libretro/mame", + "branch": "b207f9c", + "directory": "mame", + "output": "mame_libretro.so", + "make": { + "file": "Makefile.libretro", + "args": [ + "CROSS_BUILD=1", + "TARGETOS=linux", + "CC=gcc", + "CXX=g++", + "LD=ld", + "OVERRIDE_CC=aarch64-linux-gnu-gcc", + "OVERRIDE_CXX=aarch64-linux-gnu-g++", + "OVERRIDE_LD=aarch64-linux-gnu-g++", + "STRIP=aarch64-linux-gnu-strip", + "platform=aarch64" + ], + "target": "" + }, + "symbols": 0 + }, "mame2000": { "source": "https://github.com/libretro/mame2000-libretro", "branch": "2ec60f6", @@ -1321,6 +1365,19 @@ ] } }, + "mupen64plus": { + "source": "https://github.com/libretro/mupen64plus-libretro-nx.git", + "branch": "680e033", + "purge": 1, + "directory": "mupen64plus-libretro-nx", + "output": "mupen64plus_libretro.so", + "make": { + "file": "Makefile", + "args": "WITH_DYNAREC=aarch64", + "target": "" + }, + "symbols": 0 + }, "nekop2": { "source": "https://github.com/libretro/libretro-meowPC98", "branch": "dc905d4", @@ -1441,6 +1498,19 @@ }, "symbols": 0 }, + "parallel_n64": { + "source": "https://github.com/libretro/parallel-n64.git", + "branch": "1da824e", + "purge": 1, + "directory": "parallel-n64", + "output": "parallel_n64_libretro.so", + "make": { + "file": "Makefile", + "args": "WITH_DYNAREC=aarch64", + "target": "" + }, + "symbols": 0 + }, "pcsx_rearmed": { "source": "https://github.com/libretro/pcsx_rearmed", "branch": "228c14e", From 495f09bf1879acafbf3131878161a89539c8f5ba Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Tue, 13 Jan 2026 16:56:43 -0500 Subject: [PATCH 2/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- build.sh | 174 ++++++++++++++++++++++++++++++++++++++----------- data/core.json | 1 + 2 files changed, 138 insertions(+), 37 deletions(-) diff --git a/build.sh b/build.sh index d5c6362..9cfc424 100755 --- a/build.sh +++ b/build.sh @@ -41,6 +41,7 @@ EXCLUDE_CORES="" OPTION_SPECIFIED=0 UPDATE=0 CLEAN=0 +CORE_CLEAN_FLAG=0 # If argument '-p' or '--purge' provided first, set PURGE=1 if [ "$#" -gt 0 ]; then @@ -93,8 +94,10 @@ while [ "$#" -gt 0 ]; do break ;; -u | --update) - UPDATE=1 + [ "$OPTION_SPECIFIED" -ne 0 ] && USAGE + OPTION_SPECIFIED=1 shift + UPDATE=1 ;; -f | --force) FORCE=1 @@ -133,6 +136,28 @@ PATCH_DIR="$BASE_DIR/patch" # POSIX safe CPU count NPROC=$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1) +# Default behavior: nproc-1 (min 1) +# Override: export MAKE_CORES= (must be positive int) +if [ -z "${MAKE_CORES+x}" ] || [ -z "$MAKE_CORES" ]; then + if [ "$NPROC" -gt 1 ]; then + MAKE_CORES=$((NPROC - 1)) + else + MAKE_CORES=1 + fi +fi + +# Validate it's a positive integer +case "$MAKE_CORES" in + *[!0-9]*|"") + printf "Error: MAKE_CORES must be a positive integer (got '%s')\n" "$MAKE_CORES" >&2 + exit 1 + ;; +esac +if [ "$MAKE_CORES" -lt 1 ]; then + printf "Error: MAKE_CORES must be >= 1 (got '%s')\n" "$MAKE_CORES" >&2 + exit 1 +fi + # Safe directory removal helper SAFE_RM_DIR() { _TARGET="$1" @@ -219,7 +244,7 @@ else fi # Check for other required commands -for CMD in file git jq make patch pv readelf zip; do +for CMD in file git jq make patch pv readelf zip unzip cksum sort sed awk grep head cut tr find; do if ! command -v "$CMD" >/dev/null 2>&1; then printf "Error: Missing required command '%s'\n" "$CMD" >&2 exit 1 @@ -241,11 +266,17 @@ RETURN_TO_BASE() { RUN_COMMANDS() { printf "\nRunning '%s' commands\n" "$1" - CMD=$(printf '%s\n' "$2" | jq -r '.[]') - printf "Running:\n%s\n" "$CMD" - sh </dev/null || echo "") + MAKE_ARGS_STR="" + MAKE_ARGS_FILE="" + + if [ "$MAKE_ARGS_TYPE" = "array" ]; then + MAKE_ARGS_FILE="$BUILD_DIR/.make_args.${NAME}.$$" + : >"$MAKE_ARGS_FILE" + # newline-separated, one arg per line + echo "$MODULE" | jq -r '.make.args[]' >"$MAKE_ARGS_FILE" 2>/dev/null || : + # pretty display string + MAKE_ARGS_STR=$(tr '\n' ' ' <"$MAKE_ARGS_FILE" | sed 's/[[:space:]][[:space:]]*/ /g; s/[[:space:]]*$//') + elif [ "$MAKE_ARGS_TYPE" = "string" ]; then + MAKE_ARGS_STR=$(echo "$MODULE" | jq -r '.make.args' 2>/dev/null) + else + MAKE_ARGS_STR="" + fi + MAKE_TARGET=$(echo "$MODULE" | jq -r '.make.target') MAKE_ARCH='-mtune=cortex-a53 -mcpu=cortex-a53+crc+crypto' # Verify required keys if [ -z "$DIR" ] || [ -z "$OUTPUT_LIST" ] || [ -z "$SOURCE" ] || [ -z "$MAKE_FILE" ] || [ -z "$SYMBOLS" ]; then printf "Missing required configuration keys for '%s' in '%s'\n" "$NAME" "$CORE_CONFIG" >&2 + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -347,6 +400,7 @@ for NAME in $CORES; do if [ -z "$REMOTE_HASH" ]; then printf "Failed to get remote hash for '%s'\n" "$NAME" >&2 + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -372,19 +426,19 @@ for NAME in $CORES; do SAFE_RM_DIR "$BUILD_DIR/$CACHED_DIR" fi - # If PURGE is set, delete the repo folder *now* (even if we skip later) - # This implements: "purge is to delete the repo folder" + # If PURGE is set, delete the repo folder now if [ "$PURGE" -eq 1 ] || [ "$CORE_PURGE_FLAG" -eq 1 ]; then printf "Purging core repo directory: %s\n" "$CORE_DIR" rm -rf "$CORE_DIR" fi - # Skip when up to date (purge does not block skipping; we won't re-clone) + # Skip when up to date if [ "$FORCE" -eq 0 ] && \ [ "$CACHED_HASH" = "$REMOTE_HASH" ] && [ -f "$RETRO_DIR/$ZIP_NAME" ]; then printf "Core '%s' is up to date (hash: %s). Skipping build.\n" "$NAME" "$REMOTE_HASH" jq --arg name "$NAME" --arg hash "$REMOTE_HASH" --arg dir "$DIR" \ '(.[$name] = {"hash":$hash,"dir":$dir})' "$CACHE_FILE" >"$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -393,27 +447,28 @@ for NAME in $CORES; do printf "Core '%s' not found\n\n" "$DIR" # Clone if [ "$LATEST" -eq 1 ]; then - GC_CMD="git clone --progress --quiet --recurse-submodules -j$NPROC $SOURCE $CORE_DIR" + GC_CMD="git clone --progress --quiet --recurse-submodules -j"$MAKE_CORES" $SOURCE $CORE_DIR" elif [ -n "$BRANCH" ] && echo "$BRANCH" | grep -qE '^[0-9a-f]{7,40}$'; then - GC_CMD="git clone --progress --quiet --recurse-submodules -j$NPROC $SOURCE $CORE_DIR" + GC_CMD="git clone --progress --quiet --recurse-submodules -j"$MAKE_CORES" $SOURCE $CORE_DIR" else - GC_CMD="git clone --progress --quiet --recurse-submodules -j$NPROC" + GC_CMD="git clone --progress --quiet --recurse-submodules -j"$MAKE_CORES"" [ -n "$BRANCH" ] && GC_CMD="$GC_CMD -b $BRANCH" GC_CMD="$GC_CMD $SOURCE $CORE_DIR" fi - eval "$GC_CMD" || { printf "Failed to clone %s\n" "$SOURCE" >&2; continue; } + eval "$GC_CMD" || { printf "Failed to clone %s\n" "$SOURCE" >&2; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } # Enter repo to init submodules and optional commit checkout - cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; continue; } + cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } if [ "$LATEST" -eq 0 ] && [ -n "$BRANCH" ] && echo "$BRANCH" | grep -qE '^[0-9a-f]{7,40}$'; then - git fetch --all || { printf "Failed to fetch in %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; continue; } - git checkout --detach "$BRANCH" || { printf "Failed to checkout %s\n" "$BRANCH" >&2; RETURN_TO_BASE; continue; } + git fetch --all || { printf "Failed to fetch in %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git checkout --detach "$BRANCH" || { printf "Failed to checkout %s\n" "$BRANCH" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } fi git submodule update --init --recursive || { printf "Failed to update submodules for %s\n" "$NAME" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue } @@ -423,32 +478,33 @@ for NAME in $CORES; do fi # Enter repo for update and build - cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; continue; } + cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } # Ensure submodules are present git submodule update --init --recursive || { printf "Failed to update submodules for %s\n" "$NAME" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue } if [ $BEEN_CLONED -eq 0 ]; then if [ "$LATEST" -eq 1 ]; then printf "Updating '%s' to remote HEAD (latest)\n" "$NAME" - git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } - git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } + git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } git submodule sync --quiet - git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } + git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } elif [ -n "$BRANCH" ] && echo "$BRANCH" | grep -qE '^[0-9a-f]{7,40}$'; then printf "Repository already cloned. Fetching updates and checking out commit '%s'\n" "$BRANCH" - git fetch --all || { printf "Failed to fetch updates for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } - git checkout --detach "$BRANCH" || { printf "Failed to checkout commit '%s' for '%s'\n" "$BRANCH" "$NAME" >&2; RETURN_TO_BASE; continue; } + git fetch --all || { printf "Failed to fetch updates for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git checkout --detach "$BRANCH" || { printf "Failed to checkout commit '%s' for '%s'\n" "$BRANCH" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } else printf "Updating '%s' to remote HEAD\n" "$NAME" - git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } - git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } + git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } git submodule sync --quiet - git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } + git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } fi fi @@ -457,12 +513,14 @@ for NAME in $CORES; do if [ "$LOCAL_HASH" != "$REMOTE_HASH" ]; then printf "Warning: Local hash (%s) doesn't match remote hash (%s)\n" "$LOCAL_HASH" "$REMOTE_HASH" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi APPLY_PATCHES "$NAME" "$CORE_DIR" || { printf "Failed to apply patches for %s\n" "$NAME" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue } @@ -470,6 +528,7 @@ for NAME in $CORES; do if ! RUN_COMMANDS "pre-make" "$PRE_MAKE"; then printf "Pre-make commands failed for %s\n" "$NAME" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi fi @@ -477,7 +536,7 @@ for NAME in $CORES; do printf "Make Structure:" printf "\n\tFILE:\t%s" "$MAKE_FILE" printf "\n\tARCH:\t%s" "ARM64_A53" - printf "\n\tARGS:\t%s" "$MAKE_ARGS" + printf "\n\tARGS:\t%s" "$MAKE_ARGS_STR" printf "\n\tTARGET: %s\n" "$MAKE_TARGET" printf "\nBuilding '%s' ...\n" "$NAME" @@ -495,13 +554,33 @@ for NAME in $CORES; do # Run make; capture everything into build.log kill $PV_PID 2>/dev/null - if CFLAGS="$MAKE_ARCH" CXXFLAGS="$MAKE_ARCH" make -j"$NPROC" -f "$MAKE_FILE" $MAKE_ARGS $MAKE_TARGET >>"$LOGFILE" 2>&1; then + + # Build make argv safely (no eval) + set -- make -j"$MAKE_CORES" -f "$MAKE_FILE" + + if [ "$MAKE_ARGS_TYPE" = "array" ] && [ -n "$MAKE_ARGS_FILE" ] && [ -s "$MAKE_ARGS_FILE" ]; then + while IFS= read -r _a; do + [ -n "$_a" ] || continue + set -- "$@" "$_a" + done <"$MAKE_ARGS_FILE" + elif [ -n "$MAKE_ARGS_STR" ]; then + # legacy string split on whitespace (matches prior behavior) + # shellcheck disable=SC2086 + set -- "$@" $MAKE_ARGS_STR + fi + + if [ -n "$MAKE_TARGET" ] && [ "$MAKE_TARGET" != "null" ]; then + set -- "$@" "$MAKE_TARGET" + fi + + if CFLAGS="$MAKE_ARCH" CXXFLAGS="$MAKE_ARCH" "$@" >>"$LOGFILE" 2>&1; then printf "\nBuild succeeded: %s\n" "$NAME" jq --arg name "$NAME" --arg hash "$REMOTE_HASH" --arg dir "$DIR" \ '(.[$name] = {"hash":$hash,"dir":$dir})' "$CACHE_FILE" >"$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" else printf "\nBuild FAILED: %s - see %s\n" "$NAME" "$LOGFILE" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -512,6 +591,7 @@ for NAME in $CORES; do if ! RUN_COMMANDS "post-make" "$POST_MAKE"; then printf "Post-make commands failed for '%s'\n" "$NAME" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi fi @@ -529,6 +609,7 @@ for NAME in $CORES; do done if [ "$MISSING" -ne 0 ]; then RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -552,13 +633,14 @@ for NAME in $CORES; do mv "$OUTFILE" "$RETRO_DIR" || { printf "Failed to move '%s' for '%s' to '%s'\n" "$OUTFILE" "$NAME" "$RETRO_DIR" >&2 RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue 2 } done printf "\nIndexing and compressing outputs for '%s'\n" "$NAME" - cd "$RETRO_DIR" || { printf "Failed to enter directory %s\n" "$RETRO_DIR" >&2; RETURN_TO_BASE; continue; } + cd "$RETRO_DIR" || { printf "Failed to enter directory %s\n" "$RETRO_DIR" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } # Decide zip name based on .so file if present (multi-output) SOFILE=$(printf "%s\n" $OUTPUTS | grep '\.so$' | head -n1) @@ -612,18 +694,36 @@ for NAME in $CORES; do sort -k3 .index-extended -o .index-extended sort .index -o .index - # After build: if PURGE (global or per-core) was requested, delete the repo folder; otherwise try a clean - if [ "$PURGE" -eq 1 ] || [ "$CORE_PURGE_FLAG" -eq 1 ]; then - printf "\nPurging core repo directory: %s\n" "$CORE_DIR" - rm -rf "$CORE_DIR" - else - printf "Cleaning build environment for '%s'\n" "$NAME" - make -C "$CORE_DIR" clean >/dev/null 2>&1 || { - printf "Clean failed or not required\n" >&2 - } + # Clean stage: Remove build artifacts after packaging + if [ "$CLEAN" -eq 1 ] || [ "$CORE_CLEAN_FLAG" -eq 1 ]; then + printf "\nCleaning build artifacts in: %s\n" "$CORE_DIR" + + if [ -f "$CORE_DIR/Makefile" ]; then + # Core has a Makefile: use make clean + if ! make clean -C "$CORE_DIR" -j"$MAKE_CORES"; then + printf "Warning: make clean failed for %s\n" "$NAME" >&2 + fi + else + # No Makefile: manually remove non-source files + printf "No Makefile found, cleaning directory manually.\n" + + if [ -d "$CORE_DIR/.git" ]; then + # Keep the git repo, remove everything else + find "$CORE_DIR" -mindepth 1 -maxdepth 1 \ + ! -name ".git" \ + -exec rm -rf {} + + printf "Preserved git repo, removed build artifacts.\n" + else + # Not a git repo: remove entire directory + rm -rf "$CORE_DIR" + mkdir -p "$CORE_DIR" + printf "Removed and recreated directory since no .git was found.\n" + fi + fi fi RETURN_TO_BASE + [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" done ( diff --git a/data/core.json b/data/core.json index 3f14e61..40c25bc 100755 --- a/data/core.json +++ b/data/core.json @@ -1060,6 +1060,7 @@ "OVERRIDE_CXX=aarch64-linux-gnu-g++", "OVERRIDE_LD=aarch64-linux-gnu-g++", "STRIP=aarch64-linux-gnu-strip", + "LIBRETRO_CPU=aarch64", "platform=aarch64" ], "target": "" From 33c8a8ac82c5da0ea7b17b55dc1573715db84e9e Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Tue, 13 Jan 2026 19:04:11 -0500 Subject: [PATCH 3/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- build.sh | 83 +++++++++++++++++++++++++++++++++++++++++++++----- data/core.json | 32 +++++++++++-------- 2 files changed, 95 insertions(+), 20 deletions(-) diff --git a/build.sh b/build.sh index 9cfc424..b59e324 100755 --- a/build.sh +++ b/build.sh @@ -356,7 +356,7 @@ for NAME in $CORES; do fi MAKE_TARGET=$(echo "$MODULE" | jq -r '.make.target') - MAKE_ARCH='-mtune=cortex-a53 -mcpu=cortex-a53+crc+crypto' + MAKE_ARCH='-march=armv8-a+crc+crypto -mtune=cortex-a53' # Verify required keys if [ -z "$DIR" ] || [ -z "$OUTPUT_LIST" ] || [ -z "$SOURCE" ] || [ -z "$MAKE_FILE" ] || [ -z "$SYMBOLS" ]; then @@ -558,30 +558,97 @@ for NAME in $CORES; do # Build make argv safely (no eval) set -- make -j"$MAKE_CORES" -f "$MAKE_FILE" + # Transform one make arg into the final arg to pass to make. + # Prints exactly one line. + TRANSFORM_MAKE_ARG() { + _a=$1 + + case $_a in + OVERRIDE_CC=*) + _v=${_a#OVERRIDE_CC=} + case " $_v " in + *" -march="*|*" -mcpu="*|*" -mtune="*) + printf '%s\n' "OVERRIDE_CC=$_v" + ;; + *) + printf '%s\n' "OVERRIDE_CC=$_v $MAKE_ARCH" + ;; + esac + return 0 + ;; + OVERRIDE_CXX=*) + _v=${_a#OVERRIDE_CXX=} + case " $_v " in + *" -march="*|*" -mcpu="*|*" -mtune="*) + printf '%s\n' "OVERRIDE_CXX=$_v" + ;; + *) + printf '%s\n' "OVERRIDE_CXX=$_v $MAKE_ARCH" + ;; + esac + return 0 + ;; + OVERRIDE_LD=*) + _v=${_a#OVERRIDE_LD=} + case " $_v " in + *" -march="*|*" -mcpu="*|*" -mtune="*) + printf '%s\n' "OVERRIDE_LD=$_v" + ;; + *) + printf '%s\n' "OVERRIDE_LD=$_v $MAKE_ARCH" + ;; + esac + return 0 + ;; + esac + + printf '%s\n' "$_a" + } + + # Append args from JSON if [ "$MAKE_ARGS_TYPE" = "array" ] && [ -n "$MAKE_ARGS_FILE" ] && [ -s "$MAKE_ARGS_FILE" ]; then while IFS= read -r _a; do [ -n "$_a" ] || continue - set -- "$@" "$_a" + _t=$(TRANSFORM_MAKE_ARG "$_a") + [ -n "$_t" ] && set -- "$@" "$_t" done <"$MAKE_ARGS_FILE" elif [ -n "$MAKE_ARGS_STR" ]; then - # legacy string split on whitespace (matches prior behavior) + # legacy string split on whitespace # shellcheck disable=SC2086 - set -- "$@" $MAKE_ARGS_STR + for _a in $MAKE_ARGS_STR; do + _t=$(TRANSFORM_MAKE_ARG "$_a") + [ -n "$_t" ] && set -- "$@" "$_t" + done fi + # Add explicit make target if present if [ -n "$MAKE_TARGET" ] && [ "$MAKE_TARGET" != "null" ]; then set -- "$@" "$MAKE_TARGET" fi - if CFLAGS="$MAKE_ARCH" CXXFLAGS="$MAKE_ARCH" "$@" >>"$LOGFILE" 2>&1; then + # Debug: log actual argv we will run + printf "EXEC:" >>"$LOGFILE" + for __x in "$@"; do + printf " [%s]" "$__x" >>"$LOGFILE" + done + printf "\n" >>"$LOGFILE" + + printf "EXEC:" >>"$LOGFILE" + for __x in "$@"; do + printf " [%s]" "$__x" >>"$LOGFILE" + done + printf "\n" >>"$LOGFILE" + + # Run make; DO NOT export CFLAGS/CXXFLAGS globally (breaks host tools) + if "$@" >>"$LOGFILE" 2>&1; then printf "\nBuild succeeded: %s\n" "$NAME" jq --arg name "$NAME" --arg hash "$REMOTE_HASH" --arg dir "$DIR" \ '(.[$name] = {"hash":$hash,"dir":$dir})' "$CACHE_FILE" >"$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" else - printf "\nBuild FAILED: %s - see %s\n" "$NAME" "$LOGFILE" >&2 - RETURN_TO_BASE + printf "\nBuild FAILED: %s - see %s\n" "$NAME" "$LOGFILE" >&2 + RETURN_TO_BASE [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" - continue + continue fi END_TS=$(date +%s) diff --git a/data/core.json b/data/core.json index 40c25bc..79cbc1e 100755 --- a/data/core.json +++ b/data/core.json @@ -1051,18 +1051,26 @@ "make": { "file": "Makefile.libretro", "args": [ - "CROSS_BUILD=1", - "TARGETOS=linux", - "CC=gcc", - "CXX=g++", - "LD=ld", - "OVERRIDE_CC=aarch64-linux-gnu-gcc", - "OVERRIDE_CXX=aarch64-linux-gnu-g++", - "OVERRIDE_LD=aarch64-linux-gnu-g++", - "STRIP=aarch64-linux-gnu-strip", - "LIBRETRO_CPU=aarch64", - "platform=aarch64" - ], + "REGENIE=1", + "VERBOSE=1", + "OSD=retro", + "PYTHON_EXECUTABLE=python3", + "CONFIG=libretro", + "LIBRETRO_CPU=arm64", + "CROSS_BUILD=1", + "TARGETOS=linux", + "PLATFORM=arm64", + "platform=arm64", + "FORCE_DRC_C_BACKEND=1", + "OVERRIDE_CC=aarch64-linux-gnu-gcc", + "OVERRIDE_CXX=aarch64-linux-gnu-g++", + "OVERRIDE_LD=aarch64-linux-gnu-g++", + "STRIP=aarch64-linux-gnu-strip", + "UNAME=Linux raspberry 6.12.47+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.47-1+rpt1~bookworm (2025-09-16) aarch64 GNU/Linux", + "UNAME_M=aarch64", + "UNAME_P=aarch64", + "TARGET=mame" + ], "target": "" }, "symbols": 0 From 7cd825f77a78d3a1eab40f38ef3ba63a874d55bd Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Tue, 13 Jan 2026 19:44:40 -0500 Subject: [PATCH 4/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- build.sh | 239 +++++++++++++++++++++++-------------------------------- 1 file changed, 101 insertions(+), 138 deletions(-) diff --git a/build.sh b/build.sh index b59e324..bb91c4e 100755 --- a/build.sh +++ b/build.sh @@ -47,17 +47,17 @@ CORE_CLEAN_FLAG=0 if [ "$#" -gt 0 ]; then case "$1" in -p|--purge) - PURGE=1 - shift - ;; + PURGE=1 + shift + ;; -f|--force) - FORCE=1 - shift - ;; + FORCE=1 + shift + ;; -l|--latest) - LATEST=1 - shift - ;; + LATEST=1 + shift + ;; esac fi @@ -133,6 +133,35 @@ RETRO_DIR="$BASE_DIR/core" BUILD_DIR="$BASE_DIR/build" PATCH_DIR="$BASE_DIR/patch" +# Create a per-run temp directory for ALL scratch files (always cleaned up) +TMPDIR_BASE=${TMPDIR:-/tmp} +RUN_TMPDIR="$(mktemp -d "$TMPDIR_BASE/murcb.XXXXXX")" || { + printf "Error: mktemp failed\n" >&2 + exit 1 +} + +PV_PID="" + +CLEANUP() { + # Stop any progress loop + if [ -n "$PV_PID" ]; then + kill "$PV_PID" 2>/dev/null || true + PV_PID="" + fi + + # Remove all scratch files + if [ -n "$RUN_TMPDIR" ] && [ -d "$RUN_TMPDIR" ]; then + rm -rf -- "$RUN_TMPDIR" 2>/dev/null || true + fi + + # Best-effort return to base + cd "$BASE_DIR" 2>/dev/null || true +} + +# Always cleanup, including Ctrl+C +trap 'CLEANUP; exit 1' INT TERM HUP +trap 'CLEANUP' EXIT + # POSIX safe CPU count NPROC=$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1) @@ -223,40 +252,38 @@ UPDATE_ZIP() { # Detect proper aarch64 objcopy command. if command -v aarch64-linux-gnu-objcopy >/dev/null 2>&1; then - OBJCOPY=aarch64-linux-gnu-objcopy + OBJCOPY=aarch64-linux-gnu-objcopy elif command -v aarch64-linux-objcopy >/dev/null 2>&1; then - OBJCOPY=aarch64-linux-objcopy + OBJCOPY=aarch64-linux-objcopy else - printf "Error: Neither aarch64-linux-gnu-objcopy nor aarch64-linux-objcopy found\n" >&2 - exit 1 + printf "Error: Neither aarch64-linux-gnu-objcopy nor aarch64-linux-objcopy found\n" >&2 + exit 1 fi # Detect proper aarch64 strip command. if command -v aarch64-linux-gnu-strip >/dev/null 2>&1; then - STRIP=aarch64-linux-gnu-strip + STRIP=aarch64-linux-gnu-strip elif command -v aarch64-linux-strip >/dev/null 2>&1; then - STRIP=aarch64-linux-strip + STRIP=aarch64-linux-strip elif command -v strip >/dev/null 2>&1; then - STRIP=strip + STRIP=strip else - printf "Error: No suitable strip command found\n" >&2 - exit 1 + printf "Error: No suitable strip command found\n" >&2 + exit 1 fi # Check for other required commands for CMD in file git jq make patch pv readelf zip unzip cksum sort sed awk grep head cut tr find; do - if ! command -v "$CMD" >/dev/null 2>&1; then - printf "Error: Missing required command '%s'\n" "$CMD" >&2 - exit 1 - fi + if ! command -v "$CMD" >/dev/null 2>&1; then + printf "Error: Missing required command '%s'\n" "$CMD" >&2 + exit 1 + fi done # Create required directories mkdir -p "$RETRO_DIR" mkdir -p "$BUILD_DIR" -trap 'printf "\nAn error occurred. Returning to base directory.\n"; cd "$BASE_DIR"; exit 1' INT TERM - RETURN_TO_BASE() { cd "$BASE_DIR" || { printf "Failed to return to base directory\n" >&2 @@ -265,18 +292,17 @@ RETURN_TO_BASE() { } RUN_COMMANDS() { - printf "\nRunning '%s' commands\n" "$1" - # Print and run each line from the JSON array - printf '%s\n' "$2" | jq -r '.[]' | while IFS= read -r CMD; do - [ -n "$CMD" ] || continue - printf "Running:\n%s\n" "$CMD" - sh < "$CACHE_FILE" + echo "{}" > "$CACHE_FILE" fi for NAME in $CORES; do @@ -326,7 +352,7 @@ for NAME in $CORES; do fi # Required keys - DIR=$(echo "$MODULE" | jq -r '.directory') + DIR=$(echo "$MODULE" | jq -r '.directory') OUTPUT_LIST=$(echo "$MODULE" | jq -r '.output | if type=="string" then . else join(" ") end') SOURCE=$(echo "$MODULE" | jq -r '.source') SYMBOLS=$(echo "$MODULE" | jq -r '.symbols') @@ -343,11 +369,10 @@ for NAME in $CORES; do MAKE_ARGS_FILE="" if [ "$MAKE_ARGS_TYPE" = "array" ]; then - MAKE_ARGS_FILE="$BUILD_DIR/.make_args.${NAME}.$$" + # IMPORTANT: temp file goes in RUN_TMPDIR, never in /cores + MAKE_ARGS_FILE="$RUN_TMPDIR/.make_args.${NAME}.$$" : >"$MAKE_ARGS_FILE" - # newline-separated, one arg per line - echo "$MODULE" | jq -r '.make.args[]' >"$MAKE_ARGS_FILE" 2>/dev/null || : - # pretty display string + echo "$MODULE" | jq -r '.make.args[]' >"$MAKE_ARGS_FILE" 2>/dev/null || : MAKE_ARGS_STR=$(tr '\n' ' ' <"$MAKE_ARGS_FILE" | sed 's/[[:space:]][[:space:]]*/ /g; s/[[:space:]]*$//') elif [ "$MAKE_ARGS_TYPE" = "string" ]; then MAKE_ARGS_STR=$(echo "$MODULE" | jq -r '.make.args' 2>/dev/null) @@ -361,13 +386,12 @@ for NAME in $CORES; do # Verify required keys if [ -z "$DIR" ] || [ -z "$OUTPUT_LIST" ] || [ -z "$SOURCE" ] || [ -z "$MAKE_FILE" ] || [ -z "$SYMBOLS" ]; then printf "Missing required configuration keys for '%s' in '%s'\n" "$NAME" "$CORE_CONFIG" >&2 - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi - BRANCH=$(echo "$MODULE" | jq -r '.branch // ""') - PRE_MAKE=$(echo "$MODULE" | jq -r '.commands["pre-make"] // []') - POST_MAKE=$(echo "$MODULE" | jq -r '.commands["post-make"] // []') + BRANCH=$(echo "$MODULE" | jq -r '.branch // ""') + PRE_MAKE=$(echo "$MODULE" | jq -r '.commands["pre-make"] // []') + POST_MAKE=$(echo "$MODULE" | jq -r '.commands["post-make"] // []') CORE_PURGE_FLAG=$(echo "$MODULE" | jq -r '.purge // 0') case "$CORE_PURGE_FLAG" in 1) CORE_PURGE_FLAG=1 ;; @@ -400,7 +424,6 @@ for NAME in $CORES; do if [ -z "$REMOTE_HASH" ]; then printf "Failed to get remote hash for '%s'\n" "$NAME" >&2 - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -435,11 +458,10 @@ for NAME in $CORES; do # Skip when up to date if [ "$FORCE" -eq 0 ] && \ [ "$CACHED_HASH" = "$REMOTE_HASH" ] && [ -f "$RETRO_DIR/$ZIP_NAME" ]; then - printf "Core '%s' is up to date (hash: %s). Skipping build.\n" "$NAME" "$REMOTE_HASH" + printf "Core '%s' is up to date (hash: %s). Skipping build.\n" "$NAME" "$REMOTE_HASH" jq --arg name "$NAME" --arg hash "$REMOTE_HASH" --arg dir "$DIR" \ '(.[$name] = {"hash":$hash,"dir":$dir})' "$CACHE_FILE" >"$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" - continue + continue fi BEEN_CLONED=0 @@ -447,64 +469,62 @@ for NAME in $CORES; do printf "Core '%s' not found\n\n" "$DIR" # Clone if [ "$LATEST" -eq 1 ]; then - GC_CMD="git clone --progress --quiet --recurse-submodules -j"$MAKE_CORES" $SOURCE $CORE_DIR" + GC_CMD="git clone --progress --quiet --recurse-submodules -j$MAKE_CORES $SOURCE $CORE_DIR" elif [ -n "$BRANCH" ] && echo "$BRANCH" | grep -qE '^[0-9a-f]{7,40}$'; then - GC_CMD="git clone --progress --quiet --recurse-submodules -j"$MAKE_CORES" $SOURCE $CORE_DIR" + GC_CMD="git clone --progress --quiet --recurse-submodules -j$MAKE_CORES $SOURCE $CORE_DIR" else - GC_CMD="git clone --progress --quiet --recurse-submodules -j"$MAKE_CORES"" + GC_CMD="git clone --progress --quiet --recurse-submodules -j$MAKE_CORES" [ -n "$BRANCH" ] && GC_CMD="$GC_CMD -b $BRANCH" GC_CMD="$GC_CMD $SOURCE $CORE_DIR" fi - eval "$GC_CMD" || { printf "Failed to clone %s\n" "$SOURCE" >&2; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + eval "$GC_CMD" || { printf "Failed to clone %s\n" "$SOURCE" >&2; continue; } # Enter repo to init submodules and optional commit checkout - cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; continue; } if [ "$LATEST" -eq 0 ] && [ -n "$BRANCH" ] && echo "$BRANCH" | grep -qE '^[0-9a-f]{7,40}$'; then - git fetch --all || { printf "Failed to fetch in %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } - git checkout --detach "$BRANCH" || { printf "Failed to checkout %s\n" "$BRANCH" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git fetch --all || { printf "Failed to fetch in %s\n" "$CORE_DIR" >&2; RETURN_TO_BASE; continue; } + git checkout --detach "$BRANCH" || { printf "Failed to checkout %s\n" "$BRANCH" >&2; RETURN_TO_BASE; continue; } fi git submodule update --init --recursive || { printf "Failed to update submodules for %s\n" "$NAME" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue } - cd - > /dev/null + cd - >/dev/null 2>&1 printf "\n" BEEN_CLONED=1 fi # Enter repo for update and build - cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + cd "$CORE_DIR" || { printf "Failed to enter %s\n" "$CORE_DIR" >&2; continue; } # Ensure submodules are present git submodule update --init --recursive || { printf "Failed to update submodules for %s\n" "$NAME" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue } - if [ $BEEN_CLONED -eq 0 ]; then + if [ "$BEEN_CLONED" -eq 0 ]; then if [ "$LATEST" -eq 1 ]; then printf "Updating '%s' to remote HEAD (latest)\n" "$NAME" - git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } - git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } + git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } git submodule sync --quiet - git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } elif [ -n "$BRANCH" ] && echo "$BRANCH" | grep -qE '^[0-9a-f]{7,40}$'; then printf "Repository already cloned. Fetching updates and checking out commit '%s'\n" "$BRANCH" - git fetch --all || { printf "Failed to fetch updates for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } - git checkout --detach "$BRANCH" || { printf "Failed to checkout commit '%s' for '%s'\n" "$BRANCH" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git fetch --all || { printf "Failed to fetch updates for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } + git checkout --detach "$BRANCH" || { printf "Failed to checkout commit '%s' for '%s'\n" "$BRANCH" "$NAME" >&2; RETURN_TO_BASE; continue; } else printf "Updating '%s' to remote HEAD\n" "$NAME" - git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } - git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git fetch --quiet origin || { printf " fetch failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } + git reset --hard origin/HEAD || { printf " reset failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } git submodule sync --quiet - git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + git submodule update --init --recursive --quiet || { printf " submodule update failed for '%s'\n" "$NAME" >&2; RETURN_TO_BASE; continue; } fi fi @@ -513,14 +533,12 @@ for NAME in $CORES; do if [ "$LOCAL_HASH" != "$REMOTE_HASH" ]; then printf "Warning: Local hash (%s) doesn't match remote hash (%s)\n" "$LOCAL_HASH" "$REMOTE_HASH" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi APPLY_PATCHES "$NAME" "$CORE_DIR" || { printf "Failed to apply patches for %s\n" "$NAME" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue } @@ -528,7 +546,6 @@ for NAME in $CORES; do if ! RUN_COMMANDS "pre-make" "$PRE_MAKE"; then printf "Pre-make commands failed for %s\n" "$NAME" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi fi @@ -545,21 +562,14 @@ for NAME in $CORES; do printf '.' sleep 1 done) | pv -q -L 10 -N "Building $NAME" & - PV_PID=$! - trap 'kill $PV_PID 2>/dev/null' EXIT LOGFILE="$(dirname "$0")/build.log" START_TS=$(date +%s) - # Run make; capture everything into build.log - kill $PV_PID 2>/dev/null - # Build make argv safely (no eval) set -- make -j"$MAKE_CORES" -f "$MAKE_FILE" - # Transform one make arg into the final arg to pass to make. - # Prints exactly one line. TRANSFORM_MAKE_ARG() { _a=$1 @@ -567,36 +577,24 @@ for NAME in $CORES; do OVERRIDE_CC=*) _v=${_a#OVERRIDE_CC=} case " $_v " in - *" -march="*|*" -mcpu="*|*" -mtune="*) - printf '%s\n' "OVERRIDE_CC=$_v" - ;; - *) - printf '%s\n' "OVERRIDE_CC=$_v $MAKE_ARCH" - ;; + *" -march="*|*" -mcpu="*|*" -mtune="*) printf '%s\n' "OVERRIDE_CC=$_v" ;; + *) printf '%s\n' "OVERRIDE_CC=$_v $MAKE_ARCH" ;; esac return 0 ;; OVERRIDE_CXX=*) _v=${_a#OVERRIDE_CXX=} case " $_v " in - *" -march="*|*" -mcpu="*|*" -mtune="*) - printf '%s\n' "OVERRIDE_CXX=$_v" - ;; - *) - printf '%s\n' "OVERRIDE_CXX=$_v $MAKE_ARCH" - ;; + *" -march="*|*" -mcpu="*|*" -mtune="*) printf '%s\n' "OVERRIDE_CXX=$_v" ;; + *) printf '%s\n' "OVERRIDE_CXX=$_v $MAKE_ARCH" ;; esac return 0 ;; OVERRIDE_LD=*) _v=${_a#OVERRIDE_LD=} case " $_v " in - *" -march="*|*" -mcpu="*|*" -mtune="*) - printf '%s\n' "OVERRIDE_LD=$_v" - ;; - *) - printf '%s\n' "OVERRIDE_LD=$_v $MAKE_ARCH" - ;; + *" -march="*|*" -mcpu="*|*" -mtune="*) printf '%s\n' "OVERRIDE_LD=$_v" ;; + *) printf '%s\n' "OVERRIDE_LD=$_v $MAKE_ARCH" ;; esac return 0 ;; @@ -613,7 +611,6 @@ for NAME in $CORES; do [ -n "$_t" ] && set -- "$@" "$_t" done <"$MAKE_ARGS_FILE" elif [ -n "$MAKE_ARGS_STR" ]; then - # legacy string split on whitespace # shellcheck disable=SC2086 for _a in $MAKE_ARGS_STR; do _t=$(TRANSFORM_MAKE_ARG "$_a") @@ -633,21 +630,20 @@ for NAME in $CORES; do done printf "\n" >>"$LOGFILE" - printf "EXEC:" >>"$LOGFILE" - for __x in "$@"; do - printf " [%s]" "$__x" >>"$LOGFILE" - done - printf "\n" >>"$LOGFILE" - # Run make; DO NOT export CFLAGS/CXXFLAGS globally (breaks host tools) if "$@" >>"$LOGFILE" 2>&1; then + kill "$PV_PID" 2>/dev/null || true + PV_PID="" + printf "\nBuild succeeded: %s\n" "$NAME" jq --arg name "$NAME" --arg hash "$REMOTE_HASH" --arg dir "$DIR" \ '(.[$name] = {"hash":$hash,"dir":$dir})' "$CACHE_FILE" >"$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" else + kill "$PV_PID" 2>/dev/null || true + PV_PID="" + printf "\nBuild FAILED: %s - see %s\n" "$NAME" "$LOGFILE" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -658,7 +654,6 @@ for NAME in $CORES; do if ! RUN_COMMANDS "post-make" "$POST_MAKE"; then printf "Post-make commands failed for '%s'\n" "$NAME" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi fi @@ -676,7 +671,6 @@ for NAME in $CORES; do done if [ "$MISSING" -ne 0 ]; then RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue fi @@ -700,21 +694,19 @@ for NAME in $CORES; do mv "$OUTFILE" "$RETRO_DIR" || { printf "Failed to move '%s' for '%s' to '%s'\n" "$OUTFILE" "$NAME" "$RETRO_DIR" >&2 RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" continue 2 } done printf "\nIndexing and compressing outputs for '%s'\n" "$NAME" - cd "$RETRO_DIR" || { printf "Failed to enter directory %s\n" "$RETRO_DIR" >&2; RETURN_TO_BASE; [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE"; continue; } + cd "$RETRO_DIR" || { printf "Failed to enter directory %s\n" "$RETRO_DIR" >&2; RETURN_TO_BASE; continue; } # Decide zip name based on .so file if present (multi-output) SOFILE=$(printf "%s\n" $OUTPUTS | grep '\.so$' | head -n1) if [ -n "$SOFILE" ]; then ZIP_NAME="$(basename "$SOFILE").zip" else - # fallback to original behavior set -- $OUTPUTS if [ "$#" -eq 1 ]; then ZIP_NAME="$(basename "$1").zip" @@ -761,36 +753,7 @@ for NAME in $CORES; do sort -k3 .index-extended -o .index-extended sort .index -o .index - # Clean stage: Remove build artifacts after packaging - if [ "$CLEAN" -eq 1 ] || [ "$CORE_CLEAN_FLAG" -eq 1 ]; then - printf "\nCleaning build artifacts in: %s\n" "$CORE_DIR" - - if [ -f "$CORE_DIR/Makefile" ]; then - # Core has a Makefile: use make clean - if ! make clean -C "$CORE_DIR" -j"$MAKE_CORES"; then - printf "Warning: make clean failed for %s\n" "$NAME" >&2 - fi - else - # No Makefile: manually remove non-source files - printf "No Makefile found, cleaning directory manually.\n" - - if [ -d "$CORE_DIR/.git" ]; then - # Keep the git repo, remove everything else - find "$CORE_DIR" -mindepth 1 -maxdepth 1 \ - ! -name ".git" \ - -exec rm -rf {} + - printf "Preserved git repo, removed build artifacts.\n" - else - # Not a git repo: remove entire directory - rm -rf "$CORE_DIR" - mkdir -p "$CORE_DIR" - printf "Removed and recreated directory since no .git was found.\n" - fi - fi - fi - RETURN_TO_BASE - [ -n "$MAKE_ARGS_FILE" ] && rm -f "$MAKE_ARGS_FILE" done ( From 513b31baab25b3f0ecb5ceed12df9d0638f66256 Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Tue, 13 Jan 2026 20:19:06 -0500 Subject: [PATCH 5/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- build.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index bb91c4e..5355c9b 100755 --- a/build.sh +++ b/build.sh @@ -750,9 +750,28 @@ for NAME in $CORES; do fi echo "$ZIP_NAME" >>.index - sort -k3 .index-extended -o .index-extended + sort -k3 .index-extended -o .index-extended sort .index -o .index + # After packaging: purge repo if requested, otherwise try cleaning build artifacts + if [ "$PURGE" -eq 1 ] || [ "$CORE_PURGE_FLAG" -eq 1 ]; then + printf "\nPurging core repo directory: %s\n" "$CORE_DIR" + rm -rf -- "$CORE_DIR" + else + printf "\nCleaning build environment for '%s'\n" "$NAME" + ( + cd "$CORE_DIR" 2>/dev/null || exit 0 + + # Prefer cleaning using the same makefile we built with + make -f "$MAKE_FILE" clean -j"$MAKE_CORES" >/dev/null 2>&1 && exit 0 + + # Fallback: common clean target + make clean -j"$MAKE_CORES" >/dev/null 2>&1 && exit 0 + + exit 0 + ) || : + fi + RETURN_TO_BASE done From b0b39b221068d8df129fda8b904f8125fd5b1d6a Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Wed, 14 Jan 2026 11:30:21 -0500 Subject: [PATCH 6/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- .../base/Media Player/assign/Media Player/ffmpeg.ini | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 system/base/Media Player/assign/Media Player/ffmpeg.ini diff --git a/system/base/Media Player/assign/Media Player/ffmpeg.ini b/system/base/Media Player/assign/Media Player/ffmpeg.ini new file mode 100755 index 0000000..04aaa55 --- /dev/null +++ b/system/base/Media Player/assign/Media Player/ffmpeg.ini @@ -0,0 +1,11 @@ +[mpv] +name=FFMpeg +core=ffmpeg_libretro.so + +[launch] +prep= +exec=/opt/muos/script/launch/lr-general.sh +done= + +[friendly] +ffmpeg From 4d790251a788664b69c872aacddac524a7ad5eca Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Wed, 14 Jan 2026 11:32:20 -0500 Subject: [PATCH 7/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- system/base/Media Player/assign/Media Player/ffmpeg.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/base/Media Player/assign/Media Player/ffmpeg.ini b/system/base/Media Player/assign/Media Player/ffmpeg.ini index 04aaa55..ffdac3e 100755 --- a/system/base/Media Player/assign/Media Player/ffmpeg.ini +++ b/system/base/Media Player/assign/Media Player/ffmpeg.ini @@ -1,4 +1,4 @@ -[mpv] +[ffmpeg] name=FFMpeg core=ffmpeg_libretro.so From 982237a4e3648150a8c08534a3362f15a02bec55 Mon Sep 17 00:00:00 2001 From: Duncanyoyo1 Date: Thu, 15 Jan 2026 04:18:02 -0500 Subject: [PATCH 8/8] Add ffmpeg, mame, paralleln64 and mupen64plus builds --- build.sh | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/build.sh b/build.sh index 5355c9b..b341b57 100755 --- a/build.sh +++ b/build.sh @@ -292,17 +292,33 @@ RETURN_TO_BASE() { } RUN_COMMANDS() { - printf "\nRunning '%s' commands\n" "$1" - printf '%s\n' "$2" | jq -r '.[]' | while IFS= read -r CMD; do - [ -n "$CMD" ] || continue - printf "Running:\n%s\n" "$CMD" - sh <"$_CMD_FILE" || return 1 + + if ! printf '%s\n' "$_JSON" | jq -r '.[]' >"$_CMD_FILE" 2>/dev/null; then + printf "Failed to parse '%s' commands JSON\n" "$_PHASE" >&2 + return 1 + fi + + # Echo what will run + while IFS= read -r _CMD; do + [ -n "$_CMD" ] || continue + printf "Running:\n%s\n" "$_CMD" + done <"$_CMD_FILE" + + # Run the whole phase in a subshell: + # - commands share state with each other (cd works inside the phase) + # - nothing leaks into the main build (so -C paths don't become dir/dir) + ( + # fail fast within the phase + set -e + . "$_CMD_FILE" + ) } APPLY_PATCHES() { @@ -750,7 +766,7 @@ for NAME in $CORES; do fi echo "$ZIP_NAME" >>.index - sort -k3 .index-extended -o .index-extended + sort -k3 .index-extended -o .index-extended sort .index -o .index # After packaging: purge repo if requested, otherwise try cleaning build artifacts