|
|
@@ -1,60 +1,83 @@
|
|
|
-# Building M2make
|
|
|
+# M2make — build-order tutorial
|
|
|
|
|
|
-M2make is a front-end for the M2 Modula-2 compiler or GNU Modula-2 compiler.
|
|
|
-It's goal is to check the order of compilation of the different files of a project,
|
|
|
-compiling only what is necessary. It only a main file like this :
|
|
|
+`M2make` is a small build front-end for the V3 `M2` compiler and for GNU
|
|
|
+Modula-2. Given a main source file, it follows `IMPORT`/`FROM` imports,
|
|
|
+topologically sorts the modules, and runs the compiler in the right order.
|
|
|
|
|
|
+```sh
|
|
|
+M2make [-n] [-v] [-c m2|gm2] [-I dir] [-o out]
|
|
|
+ [--m2bin path] [--shim path] [--extra path]
|
|
|
+ [--m2flag flag] [--dialect pim|iso|gm2] [--separate] main.mod
|
|
|
```
|
|
|
-M2make toto.mod
|
|
|
-```
|
|
|
|
|
|
-I will use a topological sort to figure out the order of compiling,
|
|
|
-and which file needs to be compiled (if modified).
|
|
|
+## Build
|
|
|
+
|
|
|
+The portable source is `tools/m2make/M2make.mod`; the OS bridge is
|
|
|
+`m2make_os.c`. From the repository root:
|
|
|
+
|
|
|
+```sh
|
|
|
+cd tools/m2make
|
|
|
+./build_m2.sh # dogfood build with the V3 M2 compiler
|
|
|
+./build_gm2.sh # optional: build with GNU Modula-2
|
|
|
+```
|
|
|
|
|
|
-I needs to compile only what is necessary.
|
|
|
+Both produce a `M2make` binary; the dogfood binary is
|
|
|
+`tools/m2make/b_v3/M2make`.
|
|
|
|
|
|
-## Status (implemented in `tools/m2make`, GNU Modula-2)
|
|
|
+## One-shot build (default)
|
|
|
|
|
|
-`M2make [-n] [-v] [-c m2|gm2] [-I dir] [-o out] [--m2bin path] [--shim path] main.mod`
|
|
|
+```sh
|
|
|
+tools/m2make/b_v3/M2make \
|
|
|
+ --m2bin ./compiler/M2 \
|
|
|
+ --shim runtime/syslib/shim.c \
|
|
|
+ -o /tmp/prog prog.mod
|
|
|
+```
|
|
|
|
|
|
-- Follows `IMPORT`/`FROM` imports transitively from the main file,
|
|
|
- topologically sorts the modules (iterative DFS, cycle reported),
|
|
|
- skips the build when the output is newer than every source.
|
|
|
-- `m2` mode: one session (`M2` + `qbe` + `cc`), gated on M2's
|
|
|
- `Parsed correctly` verdict. `gm2` mode: per-file `gm2 -fiso -c`
|
|
|
- of stale units + ordered link.
|
|
|
-- One portable core (`M2make.mod` + `M2makeOS.def`, ISO Modula-2
|
|
|
- importing only `FileIO`/`M2makeOS`) compiles with both `gm2 -fiso`
|
|
|
- (`build_gm2.sh`) and the V3 `M2` driver (`build_m2.sh`); the
|
|
|
- OS layer (`stat`/`system`/text input) lives in `m2make_os.c`
|
|
|
- with per-compiler bindings (`M2makeC.def` for gm2,
|
|
|
- `EXTERNAL` for M2). See `tools/m2make/README.md` for the exact
|
|
|
- portable subset and limitations. `tests/run_tests.sh`: 18/18 green
|
|
|
- with both binaries.
|
|
|
+For V3 this runs one M2 session over all `.def`/`.mod` files, then `qbe`,
|
|
|
+then `cc` with the runtime shim. It gates on M2’s `Parsed correctly`
|
|
|
+verdict.
|
|
|
|
|
|
+## Separate-object build
|
|
|
|
|
|
-I will use a topological sort to figure out the order of compiling,
|
|
|
-and which file needs to be compiled (if modified).
|
|
|
+```sh
|
|
|
+tools/m2make/b_v3/M2make --separate \
|
|
|
+ --m2bin ./compiler/M2 \
|
|
|
+ --shim runtime/syslib/shim.c \
|
|
|
+ --dialect iso \
|
|
|
+ -o /tmp/prog prog.mod
|
|
|
+```
|
|
|
|
|
|
-I needs to compile only what is necessary.
|
|
|
+Each module is compiled with `M2 -c` against the ordered interfaces to
|
|
|
+`gen_ssa/<Module>.o`; the program object contains `main`, library objects
|
|
|
+contain only their code plus `<Module>_init`. All objects are linked with
|
|
|
+`cc` and the shim. This mode currently rebuilds every object; it does not
|
|
|
+yet do incremental `.def`-timestamp checks.
|
|
|
|
|
|
+## Options
|
|
|
|
|
|
-<!--It also needs eventually to use a project file with these elements :-->
|
|
|
+- `-n` — dry run: print the build order and command.
|
|
|
+- `-v` — verbose: report external modules and build order.
|
|
|
+- `-c m2|gm2` — compiler driver (default `m2`).
|
|
|
+- `-I dir` — extra search directory (repeatable; the main file’s directory
|
|
|
+ is always searched).
|
|
|
+- `-o out` — output executable (default: program module name).
|
|
|
+- `--m2bin path` — M2 driver (default `M2`).
|
|
|
+- `--shim path` — C runtime shim for V3 mode (default `shim.c`).
|
|
|
+- `--extra path` — extra C file linked after the shim.
|
|
|
+- `--m2flag flag` — one extra M2 argument (the fixpoint uses
|
|
|
+ `-legacyopen1d`).
|
|
|
+- `--dialect pim|iso|gm2` — add `lib/<dialect>`, `lib/common`, `lib/gm2`
|
|
|
+ and `runtime/syslib` to the search path. Use one dialect per session.
|
|
|
+- `--separate` — per-module objects instead of one session image.
|
|
|
|
|
|
-<!--[compiler]-->
|
|
|
-<!-- M2 or Gnu Modula-2-->
|
|
|
-<!-- -->
|
|
|
-<!--[systemlibs]-->
|
|
|
-<!-- system libraries to be included-->
|
|
|
-<!-- -->
|
|
|
-<!--[projectfiles]-->
|
|
|
-<!-- all the project files to be included in the project. -->
|
|
|
-<!-- -->
|
|
|
-<!--the last one can be deduced by M2make which will load the main file -->
|
|
|
-<!--and follow all the imports to be included. From that, it makes a -->
|
|
|
-<!--topologic sort and compiles what is necessary in the right order.-->
|
|
|
+## Current limits
|
|
|
|
|
|
-<!--[options]-->
|
|
|
-<!-- options to use with the compilers and to pass to the compile line.-->
|
|
|
+- `--separate` rebuilds every object; stale-object/ABI checks are deferred.
|
|
|
+- Generic instances are still resolved at client compile time.
|
|
|
+- The default one-shot mode remains the mode used by the suite, corpus and
|
|
|
+ self-hosting fixpoint.
|
|
|
+- `M2 -c` itself needs explicit imported interfaces; M2make is the
|
|
|
+ transitive resolver.
|
|
|
|
|
|
-
|
|
|
+See `TUTORIAL.md`, `docs/separate-compilation.md`, and
|
|
|
+`tools/m2make/README.md` for details.
|