# Ambiente de build dos jogos de Nintendo DS (BlocksDS 1.25.0 + gcc 16.2.0 do Wonderful, instalados por # install-toolchain.sh). "source" neste arquivo e use bds_build; cada Builds/build-.sh define as # variaveis abaixo e chama bds_build. Saida: artifacts/build//.nds, igual em dois builds. # # SLUG nome da pasta do jogo (e da pasta de saida) # SRC_URL/SRC_SHA256/SRC_NAME tarball do fonte no commit fixo (SRC_NAME e o nome publicado em sources) # SRC_SUBDIR pasta do projeto dentro do tarball (padrao: a raiz) # PATCH (opcional) patch -p1 aplicado ao fonte # MAKE_ARGS (opcional) argumentos do make; NDS_NAME e o .nds que o make gera; OUT_NAME o nome final # AUDIO_DIRS (opcional) pastas de audio do projeto: o find do macOS nao entende o regex do Makefile do # BlocksDS, entao a lista de arquivos vai por SOURCES_AUDIO, em ordem alfabetica bds_root="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)" export WONDERFUL_TOOLCHAIN="${BLOCKSDS_ROOT:-$bds_root/artifacts/tools/wonderful-root}/opt/wonderful" export BLOCKSDS="$WONDERFUL_TOOLCHAIN/thirdparty/blocksds/core" export BLOCKSDSEXT="$WONDERFUL_TOOLCHAIN/thirdparty/blocksds/external" export PATH="$WONDERFUL_TOOLCHAIN/toolchain/gcc-arm-none-eabi/bin:$bds_root/artifacts/tools/make-4.4.1/bin:$PATH" export TZ=UTC LC_ALL=C bds_check() { if [ ! -x "$BLOCKSDS/tools/ndstool/ndstool" ]; then echo "BlocksDS nao instalado: rode src/FredGames.Bundler/Builds/blocksds/install-toolchain.sh" >&2; return 1 fi [ "$(cat "$BLOCKSDS/version.txt")" = "v1.25.0" ] || { echo "Precisa do BlocksDS v1.25.0 (achei $(cat "$BLOCKSDS/version.txt"))." >&2; return 1; } arm-none-eabi-gcc --version | head -1 | grep -q " 16.2.0" || { echo "Precisa do gcc 16.2.0 do Wonderful." >&2; return 1; } make --version | head -1 | grep -q "GNU Make 4" || { echo "Precisa do GNU Make 4 (artifacts/tools/make-4.4.1)." >&2; return 1; } } # bds_fetch : baixa para o cache e confere. bds_fetch() { mkdir -p "$(dirname "$3")" [ -f "$3" ] || curl -fsSL "$1" -o "$3" echo "$2 $3" | shasum -a 256 -c - >/dev/null || { echo "sha256 diferente em $3" >&2; return 1; } } # bds_crts: o fonte da parte MPL-2.0 (os crt0, scripts de ligacao e specs que o BlocksDS liga em todo programa) # em tar.gz deterministico, artifacts/build/blocksds-1.25.0/blocksds-crts-1.25.0.tar.gz. Sai do tarball do SDK # (v1.25.0, sha256 abaixo) e vai em "sources" de todo jogo. bds_crts() { local dir="$bds_root/artifacts/build/blocksds-1.25.0" tgz tgz="$dir/cache/blocksds-sdk-v1.25.0.tar.gz" bds_fetch https://codeberg.org/blocksds/sdk/archive/v1.25.0.tar.gz cfbd1028ede946df04ce57e2a18f306f538096642e589dbbcbf36f10a4498a73 "$tgz" if [ ! -f "$dir/blocksds-crts-1.25.0.tar.gz" ]; then rm -rf "$dir/sdk"; mkdir -p "$dir/sdk" tar -xzf "$tgz" -C "$dir/sdk" --strip-components 1 sdk/sys/crts python3 -I "$(dirname "${BASH_SOURCE[0]}")/../sprig-web/pack-source.py" "$dir/blocksds-crts-1.25.0.tar.gz" "$dir/sdk" sys/crts rm -rf "$dir/sdk" fi } bds_build() { bds_check local out="$bds_root/artifacts/build/$SLUG" cache="$bds_root/artifacts/build/$SLUG/cache" tree="$bds_root/artifacts/build/$SLUG/tree" bds_fetch "$SRC_URL" "$SRC_SHA256" "$cache/$SRC_NAME" bds_crts rm -rf "$tree" "$out/$OUT_NAME.nds"; mkdir -p "$tree" tar -xzf "$cache/$SRC_NAME" -C "$tree" --strip-components 1 [ -z "${PATCH:-}" ] || patch -d "$tree" -p1 < "$PATCH" >/dev/null local proj="$tree/${SRC_SUBDIR:-.}" audio=() if [ -n "${AUDIO_DIRS:-}" ]; then audio=("SOURCES_AUDIO=$(cd "$proj" && find -E -L $AUDIO_DIRS -regex '.*\.(it|mod|s3m|wav|xm)' | LC_ALL=C sort | tr '\n' ' ')") fi ( cd "$proj" && make "${audio[@]}" ${MAKE_ARGS[@]+"${MAKE_ARGS[@]}"} >"$out/build.log" 2>&1 ) || { tail -30 "$out/build.log" >&2; return 1; } cp "$proj/${NDS_NAME}" "$out/$OUT_NAME.nds" shasum -a 256 "$out/$OUT_NAME.nds" }