Files
Pac-Man/build.ts

195 lines
5.2 KiB
TypeScript

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);
});