Skip to content

0.15x Build Process Proposal

jvilk edited this page Jan 8, 2014 · 3 revisions

What’s wrong with the current build process?

The current JSMESS build process is fragmented and hard to understand. It is no longer the case that a new user can pop in, type a simple command, and have a working build. We now have auxiliary tools that must be first understood and run to generate system-specific Makefiles, and a template for Textfiles/Archive.org that differs from the one generated from the build process.

Goals

  • One command
  • Actionable errors
  • Produces a library for the specified system that can be trivially dropped into any web site
  • Produces a demo equivalent to that used on Textfiles/Archive.org

Approach

Parts of the proposed approach may be considered controversial, but I hope they seem reasonable once reading my justifications.

Produce a library that incorporates the new loader

Currently, we produce a stupid chunk of JavaScript that needs to be dropped into our loader before anyone can use JSMESS on their website. It seems evident to me that this should be a part of JSMESS; we need to expose a web developer-friendly API for incorporating JSMESS into arbitrary web pages.

The HTML template used in the loader will not be a component of this library; the "first cut" of the loader should allow a web developer to pass an arbitrary div element to JSMESS, which we will populate with the needed controls and apply the needed styles programmatically.

Further versions of the loader could allow the developer to control how and where particular things are displayed (e.g. Fullscreen/mute buttons/gamepad text), but that's not a priority at the moment.

Abandon Template-based Approach

When I originally constructed the makefile, I was overzealous in pursuing a robust template-based system. Currently, the makefile uses sed to alter the contents of the HTML template present in the templates directory to create a demo website. This worked fine for awhile, but now that we have a new loader, it's no longer required.

Instead, we should produce a library along with a configuration JSON file, and a simple HTML document that passes the JSON configuration to the JSMESS loader.

Abandon Make

I love Make, and I abused the heck out of it in our current makefile... but I think it should be abandoned for a more portable and useful build solution.

I absolutely loathe Grunt, but I believe we should use it for our build process. This might be seen as controversial. Why should we shift our build process to Grunt?

Pros:

  • If we use TypeScript, our build process can be typechecked at compile time.
    • Very useful, since our build process is quite complex and expensive to test!
      • Typo a make variable name? Good luck debugging!
    • If you know JavaScript, TypeScript is trivial to pick up -- it's JavaScript with types and some syntactical sugar.
  • Grunt build files are just JavaScript, which means it is:
    • Trivial to produce JSON configuration information at build time, which the loader uses.
    • Trivial to invoke current scripts for generating MAME/MESS subtargets prior to invoking make on MAME/MESS.
    • Trivial to check and ensure that the Emscripten submodule is present.
    • Much easier to reuse chunks build logic for:
      • Native builds.
      • 64-bit builds.
      • Debug builds.
    • No more portability hacks (e.g. sed subroutine in current makefile)
    • Extremely simply to build and incorporate a menu for which systems should be built -- no more awkward SYSTEM=magic string!
  • Can use rich library of Node modules to enhance build process.
    • Including http-server, which allows us to run a fast full-fledged HTTP server locally with support for GZipped files!
  • Extremely familiar to web development community.
    • Standard build process is two steps:
      • npm install to pull in dependencies
      • grunt to install
  • Might be easier to express future helpers or encode existing helpers in JavaScript, although this is not required.

Cons:

  • Grunt has no built-ins for running tasks in parallel; you tell it the sequence of tasks to run for particular targets.
    • Thankfully, all of the JSMESS build steps are pretty much serial.
  • Grunt has no built-ins for determining if a task can be skipped.
    • Trivial to emulate Make's modification-time logic for the actual expensive steps (e.g. compiling LLVM bitcode into JavaScript).
  • Some of our current contributors might not be familiar with Grunt.

[Optional] Remove MAME/MESS source code from repository

Initially, we modified the MAME/MESS build process as a necessity; otherwise, Emscripten wouldn't compile it. These changes are now incorporated upstream in the MAME/MESS repository, which means that we only need to drop in subtargets into the MAME/MESS tree to build JSMESS.

Our new build process can easily download the source code to a particular MAME/MESS release and extract it to the appropriate location prior to generating subtarget files. We will no longer need to maintain a separate fork of the MAME/MESS code.