#!/usr/bin/env bash # Compila o The Powder Toy do fredygames.com: o simulador de fisica da equipe do The Powder Toy (GPL-3.0, # fonte coreana Mallangche MIT) em WebAssembly, com o Emscripten 6.0.10 e as portas SDL2, libpng, zlib e # bzip2 dele, mais tres bibliotecas compiladas aqui a partir dos tarballs oficiais: FFTW 3.3.10 (GPL-2+, # gravidade newtoniana), JsonCpp 1.9.6 (MIT/dominio publico) e Lua 5.2.4 (MIT, compilada como C++ com # ligacao C, como nas builds oficiais). Este script e o patch fazem parte do codigo-fonte publicado junto # do jogo. # # source /emsdk_env.sh # emsdk install 6.0.10 && emsdk activate 6.0.10 # src/FredGames.Bundler/Builds/build-powder-toy.sh # # Precisa do meson 1.9.1, do ninja 1.13.0 e do pkgconf 2.5.1 (pip install meson==1.9.1 ninja==1.13.0 # pkgconf==2.5.1.post2 num venv; aqui em artifacts/tools/meson-venv, ou no PATH). # # Fontes: os tarballs conferidos pelo SHA-256 e guardados em artifacts/cache/powder-toy/ (o site hospeda os # mesmos arquivos). Na pasta de fontes do site, o script acha os tarballs e o patch ao lado dele. # # Opcoes do meson: -Dhttp=false (sem rede: sem navegador de saves, login, votos, atualizacoes nem scripts # online), Lua 5.2, sem instalacao no sistema, sem tag de VCS. # # powder-toy-fredygames.patch: # - build sem pthreads (a pagina do site nao tem isolamento de origem para SharedArrayBuffer): a # gravidade e as tarefas rodam na thread principal e a renderizacao em thread fica desligada; # - o jogo nunca abre paginas de outros sites (Platform::OpenURI nao faz nada); # - sem mapas de codigo-fonte na saida. # # Saida: artifacts/build/powder-toy-100.1.400/powder.{js,wasm}, que o bundle.yaml do jogo confere pelo # SHA-256. set -euo pipefail VERSION=100.1.400 TPT_SHA256=75cd971e1b2d6789f9e35b75926b76d037a564ad9291fa852ad9996c8ac40c96 FFTW=3.3.10 FFTW_SHA256=56c932549852cddcfafdab3820b0200c7742675be92179e59e6215b340e26467 JSONCPP=1.9.6 JSONCPP_SHA256=f93b6dd7ce796b13d02c108bc9f79812245a82e577581c4c9aabe57075c90ea2 LUA=5.2.4 LUA_SHA256=b9e2e4aad6789b3b63a056d442f7b39f0ecfca3ae0f1fc0ae4e9614401b69f4b EMSCRIPTEN=6.0.10 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="$root/artifacts/build/powder-toy-$VERSION" cache="$root/artifacts/cache/powder-toy" if ! emcc --version 2>/dev/null | head -1 | grep -q " $EMSCRIPTEN "; then echo "Precisa do Emscripten $EMSCRIPTEN no PATH (source /emsdk_env.sh)." >&2 exit 1 fi [ -x "$root/artifacts/tools/meson-venv/bin/meson" ] && export PATH="$root/artifacts/tools/meson-venv/bin:$PATH" meson --version | grep -qx 1.9.1 || { echo "Precisa do meson 1.9.1." >&2; exit 1; } ninja --version | grep -q '^1\.13\.0' || { echo "Precisa do ninja 1.13.0." >&2; exit 1; } # O executavel nativo do pkgconf (o "pkg-config" do pip e um involucro em Python que o meson recusa). pkgcfg=$(python3 -c 'import os, pkgconf; print(os.path.join(os.path.dirname(pkgconf.__file__), ".bin", "pkgconf"))' 2>/dev/null || command -v pkg-config) "$pkgcfg" --version | grep -qx 2.5.1 || { echo "Precisa do pkgconf 2.5.1." >&2; exit 1; } # Arquivo auxiliar: em powder-toy/ (repositorio) ou ao lado do script (pasta de fontes do site). aux() { if [ -f "$here/powder-toy/$1" ]; then echo "$here/powder-toy/$1"; else echo "$here/$1"; fi } # Tarball: ao lado do script, ou baixado para o cache. fetch() { # nome url sha256 local f if [ -f "$here/$1" ]; then f="$here/$1"; else f="$cache/$1" if [ ! -f "$f" ]; then mkdir -p "$cache" curl -fsSL -o "$f.part" "$2" mv "$f.part" "$f" fi fi echo "$3 $f" | shasum -a 256 -c - >&2 echo "$f" } tpt_tar=$(fetch "the-powder-toy-$VERSION.tar.gz" \ "https://github.com/The-Powder-Toy/The-Powder-Toy/archive/refs/tags/v$VERSION.tar.gz" "$TPT_SHA256") fftw_tar=$(fetch "fftw-$FFTW.tar.gz" "https://fftw.org/fftw-$FFTW.tar.gz" "$FFTW_SHA256") json_tar=$(fetch "jsoncpp-$JSONCPP.tar.gz" \ "https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/$JSONCPP.tar.gz" "$JSONCPP_SHA256") lua_tar=$(fetch "lua-$LUA.tar.gz" "https://www.lua.org/ftp/lua-$LUA.tar.gz" "$LUA_SHA256") rm -rf "$out" mkdir -p "$out/deps/lib/pkgconfig" "$out/deps/include" deps="$out/deps" exc="-sDISABLE_EXCEPTION_CATCHING=0" # FFTW, precisao simples, sem threads. Compila dentro da propria arvore (caminhos relativos). tar xzf "$fftw_tar" -C "$out" ( cd "$out/fftw-$FFTW" emconfigure ./configure --prefix="$deps" --enable-float \ --disable-fortran --disable-shared --enable-static --disable-doc CFLAGS="-O2" >/dev/null emmake make -j8 >/dev/null emmake make install >/dev/null ) # JsonCpp: so os tres arquivos da biblioteca. tar xzf "$json_tar" -C "$out" ( cd "$out/jsoncpp-$JSONCPP" for f in json_reader json_value json_writer; do em++ -O2 -std=c++17 $exc -Iinclude -Isrc/lib_json -c "src/lib_json/$f.cpp" -o "$f.o" done emar rcs "$deps/lib/libjsoncpp.a" json_reader.o json_value.o json_writer.o cp -R include/json "$deps/include/" ) cat > "$deps/lib/pkgconfig/jsoncpp.pc" < "$deps/lib/pkgconfig/lua5.2-c++.pc" < "$out/emscripten.ini" </dev/null ninja -C build >/dev/null cp build/powder.js build/powder.wasm . ) shasum -a 256 "$out/powder.js" "$out/powder.wasm"