From 9f7c460369278d8abefd68f73fe81a19205ec314 Mon Sep 17 00:00:00 2001 From: Xevion Date: Tue, 22 Jul 2025 10:06:13 -0500 Subject: [PATCH] chore: ignore ephemeral submodules, build.css --- .gitignore | 5 +- scripts/build.sh => build.sh | 14 +-- build.ts | 194 +++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+), 8 deletions(-) rename scripts/build.sh => build.sh (85%) create mode 100644 build.ts diff --git a/.gitignore b/.gitignore index 04f88cd..a16b32c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ /target /dist .idea -*.dll \ No newline at end of file +*.dll +rust-sdl2-emscripten/ +assets/build.css +emsdk/ \ No newline at end of file diff --git a/scripts/build.sh b/build.sh similarity index 85% rename from scripts/build.sh rename to build.sh index 848b689..598edc0 100644 --- a/scripts/build.sh +++ b/build.sh @@ -38,7 +38,7 @@ fi if [ "$skip_emsdk" = 'false' ]; then echo "Activating Emscripten" # SDL2-TTF requires 3.1.43, fails to build on latest - ./../emsdk/emsdk activate 3.1.43 + ../emsdk/emsdk activate 3.1.43 source ../emsdk/emsdk_env.sh fi @@ -59,15 +59,15 @@ mkdir -p dist output_folder="target/wasm32-unknown-emscripten/$build_type" cp assets/index.html dist -cp assets/*.woff* dist +# cp assets/*.woff* dist cp assets/build.css dist cp assets/favicon.ico dist -cp $output_folder/spiritus.wasm dist -cp $output_folder/spiritus.js dist +cp $output_folder/pacman.wasm dist +cp $output_folder/pacman.js dist # only if .data file exists -cp $output_folder/deps/spiritus.data dist -if [ -f $output_folder/spiritus.wasm.map ]; then - cp $output_folder/spiritus.wasm.map dist +cp $output_folder/deps/pacman.data dist +if [ -f $output_folder/pacman.wasm.map ]; then + cp $output_folder/pacman.wasm.map dist fi if [ "$serve" = 'true' ]; then diff --git a/build.ts b/build.ts new file mode 100644 index 0000000..54a88fb --- /dev/null +++ b/build.ts @@ -0,0 +1,194 @@ +import { $ } from "bun"; + +// This is a bun script, run with `bun run build.ts` + +import * as path from "path"; +import * as fs from "fs/promises"; + +async function clean() { + console.log("Cleaning..."); + await $`cargo clean`; + await $`rm -rf ./dist/`; + console.log("Cleaned..."); +} + +async function setupEmscripten() { + const emsdkDir = "./emsdk"; + const emsdkExists = await fs + .access(emsdkDir) + .then(() => true) + .catch(() => false); + + if (!emsdkExists) { + console.log("Cloning Emscripten SDK..."); + await $`git clone https://github.com/emscripten-core/emsdk.git`; + } else { + console.log("Emscripten SDK already exists, skipping clone."); + } + + const emscriptenToolchainPath = path.join(emsdkDir, "upstream", "emscripten"); + const toolchainInstalled = await fs + .access(emscriptenToolchainPath) + .then(() => true) + .catch(() => false); + + if (!toolchainInstalled) { + console.log("Installing Emscripten toolchain..."); + await $`./emsdk/emsdk install 3.1.43`; + } else { + console.log( + "Emscripten toolchain 3.1.43 already installed, skipping install." + ); + } + + console.log("Activating Emscripten..."); + await $`./emsdk/emsdk activate 3.1.43`; + console.log("Emscripten activated."); + + // Set EMSDK environment variable for subsequent commands + process.env.EMSDK = path.resolve(emsdkDir); + + const emsdkPython = path.join(path.resolve(emsdkDir), "python"); + const emsdkNode = path.join(path.resolve(emsdkDir), "node", "16.20.0_64bit"); // Adjust node version if needed + const emsdkBin = path.join(path.resolve(emsdkDir), "upstream", "emscripten"); + process.env.PATH = `${emsdkPython}:${emsdkNode}:${emsdkBin}:${process.env.PATH}`; +} + +async function buildWeb(release: boolean) { + console.log("Building WASM with Emscripten..."); + if (release) { + await $`cargo build --target=wasm32-unknown-emscripten --release`; + } else { + await $`cargo build --target=wasm32-unknown-emscripten`; + } + + console.log("Generating CSS..."); + await $`pnpx postcss-cli ./assets/styles.scss -o ./assets/build.css`; + + console.log("Copying WASM files..."); + const buildType = release ? "release" : "debug"; + const outputFolder = `target/wasm32-unknown-emscripten/${buildType}`; + await $`mkdir -p dist`; + await $`cp assets/index.html dist`; + await $`cp assets/*.woff* dist`; + await $`cp assets/build.css dist`; + await $`cp assets/favicon.ico dist`; + await $`cp ${outputFolder}/spiritus.wasm dist`; + await $`cp ${outputFolder}/spiritus.js dist`; + + // Check if .data file exists before copying + try { + await fs.access(`${outputFolder}/deps/spiritus.data`); + await $`cp ${outputFolder}/deps/spiritus.data dist`; + } catch (e) { + console.log("No spiritus.data file found, skipping copy."); + } + + // Check if .map file exists before copying + try { + await fs.access(`${outputFolder}/spiritus.wasm.map`); + await $`cp ${outputFolder}/spiritus.wasm.map dist`; + } catch (e) { + console.log("No spiritus.wasm.map file found, skipping copy."); + } + + console.log("WASM files copied."); +} + +async function serve() { + console.log("Serving WASM with Emscripten..."); + await $`python3 -m http.server -d ./dist/ 8080`; +} + +async function main() { + const args = process.argv.slice(2); + + let release = false; + let serveFiles = false; + let skipEmscriptenSetup = false; + let cleanProject = false; + let target = "web"; // Default target + + for (const arg of args) { + switch (arg) { + case "-r": + release = true; + break; + case "-s": + serveFiles = true; + break; + case "-e": + skipEmscriptenSetup = true; + break; + case "-c": + cleanProject = true; + break; + case "--target=linux": + target = "linux"; + break; + case "--target=windows": + target = "windows"; + break; + case "--target=web": + target = "web"; + break; + case "-h": + case "--help": + console.log(` +Usage: ts-node build.ts [options] + +Options: + -r Build in release mode + -s Serve the WASM files once built (for web target) + -e Skip EMSDK setup (GitHub workflow only) + -c Clean the target/dist directory + --target=[web|linux|windows] Specify target platform (default: web) + -h, --help Show this help message + `); + return; + } + } + + if (cleanProject) { + await clean(); + } + + if (!skipEmscriptenSetup && target === "web") { + await setupEmscripten(); + } + + switch (target) { + case "web": + await buildWeb(release); + if (serveFiles) { + await serve(); + } + break; + case "linux": + console.log("Building for Linux..."); + if (release) { + await $`cargo build --release`; + } else { + await $`cargo build`; + } + console.log("Linux build complete."); + break; + case "windows": + console.log("Building for Windows..."); + if (release) { + await $`cargo build --release --target=x86_64-pc-windows-msvc`; // Assuming MSVC toolchain + } else { + await $`cargo build --target=x86_64-pc-windows-msvc`; + } + console.log("Windows build complete."); + break; + default: + console.error("Invalid target specified."); + process.exit(1); + } +} + +main().catch((err) => { + console.error(err); + process.exit(1); +});