summary_m2make.md 2.6 KB

Summary — M2make (build-order front-end)

Tag m2make-1.0 (2f243ed). Main suite 107/107; tools/m2make tests 18/18 with both compiler back-ends.

What it is

M2make builds an M2 (V3) or GNU Modula-2 project from one main file. It follows IMPORT/FROM transitively, topologically sorts the modules (iterative DFS, cycles reported), skips the build when the output is newer than every source, and otherwise drives the chosen compiler.

M2make [-n] [-v] [-c m2|gm2] [-I dir] [-o out]
       [--m2bin path] [--shim path] main.mod
  • -n dry run, -v verbose, -c m2|gm2 compiler (default m2).
  • m2 mode: one session (M2 + qbe + cc), gated on M2's Parsed correctly verdict.
  • gm2 mode: recompiles only stale units (gm2 -fiso -c) and links in topological order.
  • Exit codes: 0 ok/nothing to do, 1 build failure (incl. cycles), 2 usage.

Layout

  • tools/m2make/M2make.mod — portable ISO core (imports only FileIO + M2makeOS); compiles unchanged under both compilers.
  • tools/m2make/M2makeOS.def + m2make_os.c — OS layer (stat/system/text input/argv), with per-compiler bindings: M2makeC.def (FOR "C") + M2makeOS_gm2.mod for gm2, M2makeOS_v3.mod (EXTERNAL) for V3.
  • build_gm2.sh → b_gm2/M2make; build_m2.sh → b_v3/M2make; tests/run_tests.sh (18 cases, both binaries).
  • m2make.md — design notes (topological sort, "compile only what is necessary", future project-file idea).

Source conventions (both compilers must accept)

M2make.mod stays in the intersection of what V3 and gm2 implement (all learned via probes; see tools/m2make/README.md): no _ in identifiers, CHR(0) not 0C, declaration before use, NUL-terminated strings, flat 1D arrays only, no reliance on AND/OR short-circuit, LONGINT only via VAR out-parameters, exits via M2makeOS.ExitNow. Avoids SYSTEM/Storage in portable code.

Change bundled here

runtime/syslib/FileIO.mod: NextParameter now starts at argv index 1 (skips the program name), matching the gm2 host FileIO — required for M2make under V3 to see its arguments.

Limitations (documented)

File names must match module names; one main file per run; no spaces in paths; m2 mode rebuilds the whole session image when any source is stale (per-file incrementality is gm2-only); gm2 -c objects land in the cwd (same-named modules collide).

Next

The restrictions above exist because of two V3 bugs surfaced here: nested-array loads (a[i][j], 233) and nested-array elements passed as open-array actuals (double load → segfault). Fixing those removes the "flat 1D arrays only" workaround.