|
|
@@ -1,7 +1,8 @@
|
|
|
MODULE M2make;
|
|
|
(* M2make: build-order front-end for the M2 and GNU Modula-2 compilers.
|
|
|
Usage: M2make [-n] [-v] [-c m2|gm2] [-I dir] [-o out]
|
|
|
- [--m2bin path] [--shim path] main.mod
|
|
|
+ [--m2bin path] [--shim path] [--extra path]...
|
|
|
+ [--pkg-config pkg]... [--lib lib]... main.mod
|
|
|
Follows IMPORT/FROM imports from main.mod transitively, sorts the
|
|
|
modules topologically, skips the build when the output is newer
|
|
|
than every source, otherwise invokes the selected compiler.
|
|
|
@@ -20,7 +21,8 @@ CONST
|
|
|
MaxMods = 256;
|
|
|
MaxDeps = 64;
|
|
|
MaxDirs = 16;
|
|
|
- MaxArgs = 64;
|
|
|
+ MaxArgs = 128;
|
|
|
+ MaxExtras = 16;
|
|
|
StackCap = 264;
|
|
|
NameStride = 64;
|
|
|
PathStride = 256;
|
|
|
@@ -29,7 +31,7 @@ TYPE
|
|
|
Name = ARRAY [0..63] OF CHAR;
|
|
|
Path = ARRAY [0..255] OF CHAR;
|
|
|
Line = ARRAY [0..2047] OF CHAR;
|
|
|
- Cmd = ARRAY [0..2047] OF CHAR;
|
|
|
+ Cmd = ARRAY [0..4095] OF CHAR;
|
|
|
|
|
|
VAR
|
|
|
nMods: CARDINAL;
|
|
|
@@ -56,7 +58,10 @@ VAR
|
|
|
mainPath, outName, m2bin, shimPath: Path;
|
|
|
m2Flags: Cmd;
|
|
|
dialect: Name;
|
|
|
- extraC: Path; (* extra C file linked in m2 mode (may be empty) *)
|
|
|
+ extraPool: ARRAY [0 .. MaxExtras * PathStride - 1] OF CHAR;
|
|
|
+ pkgPool: ARRAY [0 .. MaxExtras * PathStride - 1] OF CHAR;
|
|
|
+ libPool: ARRAY [0 .. MaxExtras * PathStride - 1] OF CHAR;
|
|
|
+ nExtras, nPkgs, nLibs: CARDINAL;
|
|
|
nDirs: CARDINAL;
|
|
|
progName: Name;
|
|
|
wantProg: BOOLEAN;
|
|
|
@@ -257,6 +262,28 @@ BEGIN
|
|
|
END
|
|
|
END PutDir;
|
|
|
|
|
|
+PROCEDURE GetPool(VAR pool: ARRAY OF CHAR; idx: CARDINAL;
|
|
|
+ VAR dst: Path);
|
|
|
+VAR k: CARDINAL;
|
|
|
+BEGIN
|
|
|
+ k := 0;
|
|
|
+ WHILE k <= HIGH(dst) DO
|
|
|
+ dst[k] := pool[idx * PathStride + k];
|
|
|
+ INC(k)
|
|
|
+ END
|
|
|
+END GetPool;
|
|
|
+
|
|
|
+PROCEDURE PutPool(VAR pool: ARRAY OF CHAR; idx: CARDINAL;
|
|
|
+ src: ARRAY OF CHAR);
|
|
|
+VAR k: CARDINAL;
|
|
|
+BEGIN
|
|
|
+ k := 0;
|
|
|
+ WHILE k <= HIGH(src) DO
|
|
|
+ pool[idx * PathStride + k] := src[k];
|
|
|
+ INC(k)
|
|
|
+ END
|
|
|
+END PutPool;
|
|
|
+
|
|
|
(* ---------------- console output ---------------- *)
|
|
|
|
|
|
PROCEDURE Out(s: ARRAY OF CHAR);
|
|
|
@@ -291,8 +318,9 @@ END Die;
|
|
|
PROCEDURE Usage;
|
|
|
BEGIN
|
|
|
Out("Usage: M2make [-n] [-v] [-c m2|gm2] [-I dir] [-o out]"); OutLn;
|
|
|
- Out(" [--m2bin path] [--shim path] [--extra path]
|
|
|
- [--m2flag flag] [--dialect pim|iso|gm2] [--separate] main.mod"); OutLn
|
|
|
+ Out(" [--m2bin path] [--shim path] [--extra path]..."); OutLn;
|
|
|
+ Out(" [--pkg-config pkg]... [--lib lib]..."); OutLn;
|
|
|
+ Out(" [--m2flag flag] [--dialect pim|iso|gm2] [--separate] main.mod"); OutLn
|
|
|
END Usage;
|
|
|
|
|
|
(* ---------------- module table ---------------- *)
|
|
|
@@ -705,6 +733,13 @@ BEGIN
|
|
|
IF SrcNewer(tmpP, outT) THEN RETURN TRUE END;
|
|
|
INC(k)
|
|
|
END;
|
|
|
+ IF SrcNewer(shimPath, outT) THEN RETURN TRUE END;
|
|
|
+ k := 0;
|
|
|
+ WHILE k < nExtras DO
|
|
|
+ GetPool(extraPool, k, tmpP);
|
|
|
+ IF SrcNewer(tmpP, outT) THEN RETURN TRUE END;
|
|
|
+ INC(k)
|
|
|
+ END;
|
|
|
RETURN FALSE
|
|
|
END NeedBuild;
|
|
|
|
|
|
@@ -820,6 +855,51 @@ BEGIN
|
|
|
Copy(segA, cmd)
|
|
|
END AppendSeg;
|
|
|
|
|
|
+PROCEDURE AppendExtras(VAR cmd: ARRAY OF CHAR);
|
|
|
+VAR k: CARDINAL;
|
|
|
+BEGIN
|
|
|
+ k := 0;
|
|
|
+ WHILE k < nExtras DO
|
|
|
+ GetPool(extraPool, k, tmpP);
|
|
|
+ IF Len(tmpP) > 0 THEN AppendTok(cmd, tmpP) END;
|
|
|
+ INC(k)
|
|
|
+ END
|
|
|
+END AppendExtras;
|
|
|
+
|
|
|
+PROCEDURE AppendPkgConfigs(VAR cmd: ARRAY OF CHAR);
|
|
|
+VAR k: CARDINAL;
|
|
|
+BEGIN
|
|
|
+ k := 0;
|
|
|
+ WHILE k < nPkgs DO
|
|
|
+ GetPool(pkgPool, k, tmpP);
|
|
|
+ IF Len(tmpP) > 0 THEN
|
|
|
+ AppendSeg(cmd, " $(pkg-config --cflags --libs ");
|
|
|
+ AppendSeg(cmd, tmpP);
|
|
|
+ AppendSeg(cmd, ")")
|
|
|
+ END;
|
|
|
+ INC(k)
|
|
|
+ END
|
|
|
+END AppendPkgConfigs;
|
|
|
+
|
|
|
+PROCEDURE AppendLibs(VAR cmd: ARRAY OF CHAR);
|
|
|
+VAR k: CARDINAL;
|
|
|
+BEGIN
|
|
|
+ k := 0;
|
|
|
+ WHILE k < nLibs DO
|
|
|
+ GetPool(libPool, k, tmpP);
|
|
|
+ IF Len(tmpP) > 0 THEN
|
|
|
+ AppendSeg(cmd, " ");
|
|
|
+ IF (tmpP[0] = "-") OR (tmpP[0] = "/") THEN
|
|
|
+ AppendSeg(cmd, tmpP)
|
|
|
+ ELSE
|
|
|
+ AppendSeg(cmd, "-l");
|
|
|
+ AppendSeg(cmd, tmpP)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ INC(k)
|
|
|
+ END
|
|
|
+END AppendLibs;
|
|
|
+
|
|
|
PROCEDURE BuildM2(out: ARRAY OF CHAR);
|
|
|
VAR cmd: Cmd; k: CARDINAL; m: CARDINAL; rc: INTEGER;
|
|
|
BEGIN
|
|
|
@@ -849,7 +929,9 @@ BEGIN
|
|
|
AppendSeg(cmd, progName);
|
|
|
AppendSeg(cmd, ".s ");
|
|
|
AppendTok(cmd, shimPath);
|
|
|
- IF Len(extraC) > 0 THEN AppendTok(cmd, extraC) END;
|
|
|
+ AppendExtras(cmd);
|
|
|
+ AppendPkgConfigs(cmd);
|
|
|
+ AppendLibs(cmd);
|
|
|
AppendSeg(cmd, " -o ");
|
|
|
AppendTok(cmd, out);
|
|
|
AppendSeg(cmd, " -lm");
|
|
|
@@ -904,9 +986,10 @@ END SepObjStale;
|
|
|
PROCEDURE AbiStampOK (): BOOLEAN;
|
|
|
(* Content check for the object ABI/flags stamp. This is deliberately
|
|
|
a small build-system marker, not a per-object binary format. *)
|
|
|
-VAR h: M2makeOS.RdFile; line: Line; want: Path; ok: BOOLEAN;
|
|
|
+VAR h: M2makeOS.RdFile; line: Line; want, stamp: Path; ok: BOOLEAN;
|
|
|
BEGIN
|
|
|
- h := M2makeOS.OpenRead(AbiStampPath);
|
|
|
+ Copy(AbiStampPath, stamp);
|
|
|
+ h := M2makeOS.OpenRead(stamp);
|
|
|
IF h = NIL THEN RETURN FALSE END;
|
|
|
ok := M2makeOS.ReadLine(h, line, HIGH(line) + 1);
|
|
|
M2makeOS.CloseRead(h);
|
|
|
@@ -944,7 +1027,7 @@ PROCEDURE BuildM2Separate(out: ARRAY OF CHAR);
|
|
|
VAR cmd: Cmd; k, m: CARDINAL; rc: INTEGER;
|
|
|
obj, src, ssafile, sfile, flags: Path;
|
|
|
outT: LONGINT; compiledAny, linkNeeded, abiOK, hasGeneric: BOOLEAN;
|
|
|
- gi, k2: INTEGER;
|
|
|
+ gi: INTEGER; k2: CARDINAL;
|
|
|
BEGIN
|
|
|
Zero(cmd);
|
|
|
abiOK := AbiStampOK();
|
|
|
@@ -1067,8 +1150,11 @@ BEGIN
|
|
|
INC(k)
|
|
|
END;
|
|
|
IF SrcNewer(shimPath, outT) THEN linkNeeded := TRUE END;
|
|
|
- IF Len(extraC) > 0 THEN
|
|
|
- IF SrcNewer(extraC, outT) THEN linkNeeded := TRUE END
|
|
|
+ k := 0;
|
|
|
+ WHILE k < nExtras DO
|
|
|
+ GetPool(extraPool, k, tmpP);
|
|
|
+ IF SrcNewer(tmpP, outT) THEN linkNeeded := TRUE END;
|
|
|
+ INC(k)
|
|
|
END
|
|
|
END
|
|
|
END;
|
|
|
@@ -1093,7 +1179,9 @@ BEGIN
|
|
|
INC(k)
|
|
|
END;
|
|
|
AppendTok(tmpCmd, shimPath);
|
|
|
- IF Len(extraC) > 0 THEN AppendTok(tmpCmd, extraC) END;
|
|
|
+ AppendExtras(tmpCmd);
|
|
|
+ AppendPkgConfigs(tmpCmd);
|
|
|
+ AppendLibs(tmpCmd);
|
|
|
AppendSeg(tmpCmd, " -o ");
|
|
|
AppendTok(tmpCmd, out);
|
|
|
AppendSeg(tmpCmd, " -lm");
|
|
|
@@ -1192,6 +1280,9 @@ BEGIN
|
|
|
END;
|
|
|
INC(k)
|
|
|
END;
|
|
|
+ AppendExtras(seg);
|
|
|
+ AppendPkgConfigs(seg);
|
|
|
+ AppendLibs(seg);
|
|
|
AppendCmd(cmd, seg)
|
|
|
END;
|
|
|
IF Len(cmd) = 0 THEN
|
|
|
@@ -1257,6 +1348,9 @@ BEGIN
|
|
|
Zero(m2Flags);
|
|
|
dialect[0] := CHR(0);
|
|
|
nDirs := 0;
|
|
|
+ nExtras := 0;
|
|
|
+ nPkgs := 0;
|
|
|
+ nLibs := 0;
|
|
|
na := 0;
|
|
|
LOOP
|
|
|
IF na >= MaxArgs THEN Die("M2make: too many arguments", 2) END;
|
|
|
@@ -1343,7 +1437,29 @@ BEGIN
|
|
|
M2makeOS.ExitNow(2)
|
|
|
END;
|
|
|
INC(na);
|
|
|
- Copy(s, extraC)
|
|
|
+ IF nExtras >= MaxExtras THEN Die("M2make: too many --extra files", 2) END;
|
|
|
+ PutPool(extraPool, nExtras, s);
|
|
|
+ INC(nExtras)
|
|
|
+ ELSIF Cmp(s, "--pkg-config") = 0 THEN
|
|
|
+ ok := M2makeOS.GetArg(na, s, HIGH(s) + 1);
|
|
|
+ IF NOT ok THEN
|
|
|
+ Out("M2make: --pkg-config expects a package"); OutLn;
|
|
|
+ M2makeOS.ExitNow(2)
|
|
|
+ END;
|
|
|
+ INC(na);
|
|
|
+ IF nPkgs >= MaxExtras THEN Die("M2make: too many --pkg-config packages", 2) END;
|
|
|
+ PutPool(pkgPool, nPkgs, s);
|
|
|
+ INC(nPkgs)
|
|
|
+ ELSIF Cmp(s, "--lib") = 0 THEN
|
|
|
+ ok := M2makeOS.GetArg(na, s, HIGH(s) + 1);
|
|
|
+ IF NOT ok THEN
|
|
|
+ Out("M2make: --lib expects a library"); OutLn;
|
|
|
+ M2makeOS.ExitNow(2)
|
|
|
+ END;
|
|
|
+ INC(na);
|
|
|
+ IF nLibs >= MaxExtras THEN Die("M2make: too many --lib entries", 2) END;
|
|
|
+ PutPool(libPool, nLibs, s);
|
|
|
+ INC(nLibs)
|
|
|
ELSIF (Cmp(s, "-h") = 0) OR (Cmp(s, "--help") = 0) THEN
|
|
|
Usage;
|
|
|
M2makeOS.ExitNow(0)
|