# 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. ```sh 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.