Created
March 7, 2026 19:50
-
-
Save jaames/b5189434870e1c6d5193a100e3ca248b to your computer and use it in GitHub Desktop.
WOWCUBE custom build script (sorry it's Typescript)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { dirname, relative, resolve } from 'path'; | |
| import { fileURLToPath } from 'url'; | |
| import { execSync, spawnSync } from 'child_process'; | |
| import { $, cd, within } from 'zx'; | |
| import { homedir } from 'os'; | |
| // import Watcher from 'watcher'; | |
| import { | |
| escapePath, | |
| listFilesWithExtensions, | |
| makeDirIfNeeded, | |
| toArrayString | |
| } from './utils.mts'; | |
| const __dirname = dirname(fileURLToPath(import.meta.url)); | |
| const ARGS = process.argv.slice(2); | |
| // Run app in emulator after building | |
| const FLAG_RUN = ARGS.includes('--run'); | |
| const PROJECT_DIR = resolve(__dirname, '../Cubemaker'); | |
| const SOURCE_FILE_EXTS = ['.c', '.cc', '.cpp']; | |
| const SOURCE_DIR = resolve(PROJECT_DIR, 'src'); | |
| const SOURCE_FILES = await listFilesWithExtensions(SOURCE_DIR, SOURCE_FILE_EXTS); | |
| const SOURCE_PATHS = SOURCE_FILES.map(file => resolve(SOURCE_DIR, file)); | |
| const SOURCE_MANIFEST = resolve(PROJECT_DIR, `wowcubeapp-build.json`); | |
| const WOWCUBE_SDK_BASE_PATH = resolve(homedir(), `Documents/WowCube/WOWCube Development Kit.app/Contents/sdk`); | |
| const WOWCUBE_SDK_VERSION_MAJOR = 6; | |
| const WOWCUBE_SDK_VERSION_MINOR = 3; | |
| const WOWCUBE_SDK_VERSION = `${WOWCUBE_SDK_VERSION_MAJOR}.${WOWCUBE_SDK_VERSION_MINOR}`; | |
| const WOWCUBE_SDK_TOOLS_PATH = resolve(homedir(), `WOWCube Development Kit/Tools/cpp/bin`); | |
| const WOWCUBE_SDK_COMPILER_PATH = resolve(WOWCUBE_SDK_TOOLS_PATH, 'wasm32-wasip1-clang++'); | |
| const WOWCUBE_SDK_BUILD_PATH = resolve(WOWCUBE_SDK_BASE_PATH, 'tools/wowcube-build'); | |
| const WOWCUBE_SDK_EMULATOR_PATH = resolve(WOWCUBE_SDK_BASE_PATH, '../MacOS/WOWCube Emulator'); | |
| const WOWCUBE_SDK_PATH = resolve(WOWCUBE_SDK_BASE_PATH, `${WOWCUBE_SDK_VERSION}`); | |
| const WOWCUBE_SDK_CPP_PATH = resolve(WOWCUBE_SDK_PATH, 'cpp'); | |
| const WOWCUBE_SDK_SRC_PATHS = [ | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'AppManager.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'native.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Screen.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Scene.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'NetworkMessage.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Sound.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Gfx/Background.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Gfx/OffscreenRenderTarget.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Gfx/Sprite.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Gfx/Text.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Gfx/AnimatedSprite.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'SaveMessage.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Scramble.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Gfx/QRCode.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Splashscreen.cpp'), | |
| resolve(WOWCUBE_SDK_CPP_PATH, 'Gfx/SpriteAtlas.cpp'), | |
| ].map(file => escapePath(file)); | |
| const BUILD_WASM = resolve(PROJECT_DIR, 'binary/Cubemaker.wasm'); | |
| const BUILD_CUBFILE = resolve(PROJECT_DIR, 'binary/Cubemaker.cub'); | |
| await makeDirIfNeeded(resolve(PROJECT_DIR, 'binary')); | |
| // Compile with clang | |
| const compileCpp = () => { | |
| console.log('compiling wasm...'); | |
| spawnSync(`${escapePath(WOWCUBE_SDK_COMPILER_PATH)} ` + [ | |
| // List source files first | |
| SOURCE_PATHS.join(' '), | |
| WOWCUBE_SDK_SRC_PATHS.join(' '), | |
| // Compiler flags | |
| `-std=c++17`, | |
| `-Oz`, | |
| `-flto`, | |
| `-fno-exceptions`, | |
| `-mexec-model=reactor`, | |
| `-z stack-size=10240`, | |
| `-Wl",--initial-memory=65536,--export=run,--export=on_init,--strip-all,--lto-O3"`, | |
| `-DABI_VERSION_MAJOR=${WOWCUBE_SDK_VERSION_MAJOR}`, | |
| `-DABI_VERSION_MINOR=${WOWCUBE_SDK_VERSION_MINOR}`, | |
| `-I${escapePath(WOWCUBE_SDK_CPP_PATH)}`, | |
| // Output WASM | |
| `-o ${BUILD_WASM}`, | |
| ].filter(Boolean).join(' '), { | |
| stdio: 'inherit', | |
| shell: true, | |
| }); | |
| }; | |
| const build = () => { | |
| console.log('building cubfile...'); | |
| spawnSync(`${escapePath(WOWCUBE_SDK_BUILD_PATH)} ` + [ | |
| SOURCE_MANIFEST, | |
| BUILD_CUBFILE | |
| ].filter(Boolean).join(' '), { | |
| stdio: 'inherit', | |
| shell: true, | |
| }); | |
| }; | |
| const runInEmulator = () => { | |
| console.log('running in emulator...'); | |
| spawnSync(`${escapePath(WOWCUBE_SDK_EMULATOR_PATH)} ` + [ | |
| SOURCE_MANIFEST, | |
| `--project-run "${BUILD_CUBFILE}"`, | |
| `--run` | |
| ].filter(Boolean).join(' '), { | |
| stdio: 'inherit', | |
| shell: true, | |
| }); | |
| }; | |
| // TODO | |
| // https://github.com/wowcube/WOWCubeSDK_VSCodeExtension/blob/b64775c3cafab2503115afd278eb834c684faeb5/src/WOWCubeBuildTaskProvider.ts#L1562 | |
| compileCpp(); | |
| build(); | |
| if (FLAG_RUN) | |
| runInEmulator(); | |
| // if (FLAG_WATCH) { | |
| // console.log(FMT_GREEN, 'Watching for changes...'); | |
| // const watcher = new Watcher(SOURCE_DIR, { recursive: true }); | |
| // watcher.on('change', async (file) => { | |
| // console.log(FMT_BLUE, `File ${ relative(SOURCE_DIR, file) } changed, recompiling...`); | |
| // compile(); | |
| // }); | |
| // } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment