X-Git-Url: https://deadsoftware.ru/gitweb?p=cpc.git;a=blobdiff_plain;f=src%2Fgeneric%2FDsw%2FMod%2FMakeMain.cp;h=ad0ead7eb2d123284edf9388fa1e50b62c15026d;hp=6512555a8fd33bef5be1006dd08d986a7049e337;hb=HEAD;hpb=afeb8a7fb135a5d8b7d40399b61e6e1e283fe4b0 diff --git a/src/generic/Dsw/Mod/MakeMain.cp b/src/generic/Dsw/Mod/MakeMain.cp index 6512555..ad0ead7 100644 --- a/src/generic/Dsw/Mod/MakeMain.cp +++ b/src/generic/Dsw/Mod/MakeMain.cp @@ -37,6 +37,8 @@ MODULE DswMakeMain; debugJobs = FALSE; TYPE + Name = ARRAY 256 OF CHAR; + String = POINTER TO ARRAY OF CHAR; Selector = POINTER TO RECORD @@ -47,6 +49,7 @@ MODULE DswMakeMain; Module = POINTER TO RECORD name: DevCPT.Name; + library: DevCPT.Name; odc: Files.Name; depth: INTEGER; (* 0: leaf, MAX: root *) dir: DevCPM.Directory; @@ -56,8 +59,14 @@ MODULE DswMakeMain; worker: DswProcs.Process; END; + Library = POINTER TO RECORD + name: Name; + library: Name; + next: Library; + END; + VAR (* options *) - auto, trap, clean, symonly: BOOLEAN; + auto, trap, clean, symonly, nocode1, nocode2: BOOLEAN; exe, target, base: String; jobs: INTEGER; @@ -67,6 +76,7 @@ MODULE DswMakeMain; modList, lnkList, cmpList: ARRAY maxImps OF Module; def: Selector; (* with head, global list of selectors *) dirList: DevCPM.Directory; + libList: Library; PROCEDURE Error (IN str, p0, p1: ARRAY OF CHAR; i2: INTEGER); VAR p2: ARRAY 32 OF CHAR; @@ -113,6 +123,11 @@ MODULE DswMakeMain; END END Define; + PROCEDURE DefineNew (IN n: ARRAY OF CHAR); + BEGIN + Define(n, FALSE); + END DefineNew; + PROCEDURE AddModule (IN n: ARRAY OF CHAR; selectors: Selector; dir: DevCPM.Directory); VAR i, res: INTEGER; m: Module; BEGIN @@ -133,6 +148,49 @@ MODULE DswMakeMain; END END AddModule; + PROCEDURE AddLibrary (IN key, val: ARRAY OF CHAR); + VAR x: Library; + BEGIN + x := libList; + WHILE (x # NIL) & (x.name$ # key$) DO x := x.next END; + IF x # NIL THEN x.library := val$ + ELSE NEW(x); x.name := key$; x.library := val$; x.next := libList; libList := x + END + END AddLibrary; + + PROCEDURE AddLib (IN s: ARRAY OF CHAR); + VAR key, val: Name; i, j: INTEGER; + BEGIN + i := 0; j := 0; + WHILE (s[i] # 0X) & (s[i] # "=") DO + key[j] := s[i]; + INC(j); + INC(i) + END; + key[j] := 0X; + j := 0; + IF s[i] = "=" THEN + INC(i); + WHILE s[i] # 0X DO + val[j] := s[i]; + INC(j); + INC(i) + END + END; + val[j] := 0X; + IF key # "" THEN AddLibrary(key, val) + ELSE Error("empty library key", "", "", 0) + END + END AddLib; + + PROCEDURE FindLib (IN key: ARRAY OF CHAR): Library; + VAR x: Library; + BEGIN + x := libList; + WHILE (x # NIL) & (x.name$ # key$) DO x := x.next END; + RETURN x + END FindLib; + PROCEDURE StrToInt (IN s: ARRAY OF CHAR; def: INTEGER): INTEGER; VAR x, res: INTEGER; BEGIN @@ -156,9 +214,12 @@ MODULE DswMakeMain; Log.String("Usage: cpmake [options] module..."); Log.Ln; Log.String("Options:"); Log.Ln; Log.String(" -a Enable automatic dependency resolution"); Log.Ln; + Log.String(" -b Do not compile modules"); Log.Ln; + Log.String(" -x Do not link objects"); Log.Ln; Log.String(" -c Remove all generated files"); Log.Ln; Log.String(" -s Generate symbol files only"); Log.Ln; Log.String(" -d selector Add selector"); Log.Ln; + Log.String(" -r lib[=s] Replace library name on link stage"); Log.Ln; Log.String(" -t target Specify target rules"); Log.Ln; Log.String(" -o file Generate object file"); Log.Ln; Log.String(" -j num Specifies the number of jobs to run simultaneously"); Log.Ln; @@ -173,14 +234,17 @@ MODULE DswMakeMain; exe := NIL; auto := FALSE; jobs := 1; def.next := NIL; mno := 0; rno := 0; target := NewStr("default"); base := NewStr("cprules"); LOOP - CASE DswOpts.GetOpt("acd:sgGo:t:j:f:") OF + CASE DswOpts.GetOpt("acbxd:sgGo:t:j:f:r:h") OF | "a": auto := TRUE + | "b": nocode1 := TRUE + | "x": nocode2 := TRUE | "c": clean := TRUE | "g": trap := TRUE | "G": Kernel.intTrap := TRUE | "s": symonly := TRUE | "f": base := DswOpts.str | "d": Define(DswOpts.str, TRUE) + | "r": AddLib(DswOpts.str) | "h": Help | "j": jobs := MIN(MAX(StrToInt(DswOpts.str, 1), 1), maxJobs) | "o": exe := DswOpts.str @@ -194,11 +258,13 @@ MODULE DswMakeMain; END END ParseArgs; - PROCEDURE ReadDefines; - VAR loc: Files.Locator; name: Files.Name; m: DswDocuments.Model; r: DswDocuments.Reader; i, res: INTEGER; + PROCEDURE ReadLines (loc: Files.Locator; IN name: Files.Name; p: PROCEDURE (IN s: ARRAY OF CHAR)); + VAR s: Name; m: DswDocuments.Model; r: DswDocuments.Reader; i, res: INTEGER; BEGIN - loc := Files.dir.This(base).This(target); - DswDocuments.Open(loc, "defines", m, res); + ASSERT(loc # NIL, 20); + ASSERT(name # "", 21); + ASSERT(p # NIL, 22); + DswDocuments.Open(loc, name, m, res); IF res = 0 THEN r := m.NewReader(NIL); r.SetPos(0); @@ -206,13 +272,14 @@ MODULE DswMakeMain; WHILE ~r.eot DO i := 0; WHILE ~r.eot & (r.char <= 20X) DO r.Read END; - WHILE ~r.eot & (r.char > 20X) DO name[i] := r.char; r.Read; INC(i) END; - IF i # 0 THEN name[i] := 0X; Define(name, FALSE) END + WHILE ~r.eot & (r.char > 20X) DO s[i] := r.char; r.Read; INC(i) END; + IF i # 0 THEN s[i] := 0X; p(s) END END END - END ReadDefines; + END ReadLines; PROCEDURE CheckParams; + VAR loc: Files.Locator; BEGIN IF (exe # NIL) & (exe^ = "") THEN Error("specified empty file name for exe", "", "", 0) @@ -223,7 +290,9 @@ MODULE DswMakeMain; IF base^ = "" THEN Error("specified empty path to cpmake rules", "", "", 0) END; - ReadDefines + loc := Files.dir.This(base).This(target); + ReadLines(loc, "defines", DefineNew); + ReadLines(loc, "libs", AddLib) END CheckParams; (* --------- loader --------- *) @@ -283,7 +352,7 @@ MODULE DswMakeMain; IF sym = eql THEN DevCPS.Get(sym) ELSE INCL(DevCPM.options, DevCPM.noCode) END; - IF sym = string THEN INCL(m.flags, library); DevCPS.Get(sym) + IF sym = string THEN INCL(m.flags, library); m.library := DevCPS.str$; DevCPS.Get(sym) ELSE err(string) END; CheckSym(rbrak) @@ -363,33 +432,37 @@ MODULE DswMakeMain; Kernel.FastCollect END CheckModule; - PROCEDURE MakePath (IN dir, name: Files.Name; IN type: Files.Type; OUT path: Files.Name); + PROCEDURE GetModText (IN base, sub, name: Files.Name; OUT path: Files.Name; OUT text: DswDocuments.Model); + VAR res: INTEGER; loc: Files.Locator; BEGIN ASSERT(name # "", 21); - IF dir = "" THEN path := modDir + "/" + name - ELSE path := dir + "/" + modDir + "/" + name + IF sub = "" THEN + loc := Files.dir.This(base); + IF base = "" THEN path := name + ELSE path := base + "/" + name + END + ELSE + loc := Files.dir.This(base).This(sub).This(modDir); + IF base = "" THEN path := sub + "/" + modDir + "/" + name + ELSE path := base + "/" + sub + "/" + modDir + "/" + name + END END; - Kernel.MakeFileName(path, type) - END MakePath; + DswDocuments.Open(loc, name, text, res) + END GetModText; - PROCEDURE Open (loc: Files.Locator; IN sub, name: Files.Name; OUT path: Files.Name; OUT text: DswDocuments.Model); - VAR res: INTEGER; + PROCEDURE Open (IN base, sub, name: Files.Name; OUT path: Files.Name; OUT text: DswDocuments.Model); + VAR cp, odc: Files.Name; BEGIN - ASSERT(loc # NIL, 20); - ASSERT(name # "", 21); - (* !!! use Kernel.MakeFileName instead ".ext" concat !!! *) - MakePath(sub, name, "cp", path); - DswDocuments.Open(loc, name + ".cp", text, res); + ASSERT(name # "", 20); + Files.dir.GetFileName(name, "cp", cp); (* !!! *) + GetModText(base, sub, cp, path, text); IF text = NIL THEN - MakePath(sub, name, "odc", path); - DswDocuments.Open(loc, name + ".odc", text, res); + Files.dir.GetFileName(name, "odc", odc); (* !!! *) + GetModText(base, sub, odc, path, text); IF (text = NIL) & (sub = "") THEN - MakePath(sysDir, name, "cp", path); - loc := Files.dir.This(sysDir).This(modDir); - DswDocuments.Open(loc, name + ".cp", text, res); + GetModText(base, sysDir, cp, path, text); IF text = NIL THEN - MakePath(sysDir, name, "odc", path); - DswDocuments.Open(loc, name + ".odc", text, res); + GetModText(base, sysDir, odc, path, text); IF text = NIL THEN path := "" END @@ -400,17 +473,18 @@ MODULE DswMakeMain; PROCEDURE GetSource (IN modName: ARRAY OF CHAR; list: DevCPM.Directory; OUT path: Files.Name; OUT s: String); VAR - sub, name: Files.Name; loc: Files.Locator; base: DevCPM.Directory; - text: DswDocuments.Model; r: DswDocuments.Reader; i, res: INTEGER; + sub, name: Files.Name; + base: DevCPM.Directory; + text: DswDocuments.Model; + r: DswDocuments.Reader; + i, res: INTEGER; BEGIN s := NIL; path := ""; base := list; Kernel.SplitName(modName, sub, name); - loc := Files.dir.This(sub).This(modDir); - Open(loc, sub, name, path, text); + Open("", sub, name, path, text); WHILE (text = NIL) & (base # NIL) DO ASSERT(base.legacy, 100); - loc := Files.dir.This(base.path).This(sub).This(modDir); - Open(loc, sub, name, path, text); + Open(base.path, sub, name, path, text); base := base.next END; IF text # NIL THEN @@ -473,7 +547,7 @@ MODULE DswMakeMain; CheckModule(m, src, ok); IF ~ok THEN INC(err) END ELSE - Error("unable to open module ^1", m.name$, "", 0) + Error("unable to open module ^0", m.name$, "", 0) END; INC(i) END; @@ -519,8 +593,39 @@ MODULE DswMakeMain; RETURN ready END Ready; + PROCEDURE PrepareCompilerDeps (m: Module; p: DswProcs.Process; root, libsOnly: BOOLEAN); + VAR i: INTEGER; s: ARRAY 3 OF CHAR; lib: Library; + BEGIN + IF ~(trace IN m.flags) THEN + INCL(m.flags, trace); + FOR i := 0 TO m.mno - 1 DO + PrepareCompilerDeps(m.imp[i], p, FALSE, libsOnly) + END; + IF ~libsOnly OR (library IN m.flags) THEN + IF library IN m.flags THEN s := "-l" ELSE s := "-m" END; + IF root THEN s[1] := CAP(s[1]) END; + IF library IN m.flags THEN + lib := FindLib(m.library$); + IF lib # NIL THEN + IF lib.library$ # "" THEN + p.PutParam(s); + p.PutParam(lib.library$) + END + ELSE + p.PutParam(s); + p.PutParam(m.library$) + END + ELSE + p.PutParam(s); + p.PutParam(m.name$) + END + END; + EXCL(m.flags, trace) + END + END PrepareCompilerDeps; + PROCEDURE PrepareCompiler (m: Module): DswProcs.Process; - VAR p: DswProcs.Process; s: Selector; + VAR p: DswProcs.Process; s: Selector; i: INTEGER; BEGIN ASSERT(m # NIL, 20); ASSERT(m.odc # "", 21); @@ -528,6 +633,8 @@ MODULE DswMakeMain; p := DswProcs.dir.New(); p.Program(base + "/" + target + "/" + "build"); p.PutParam(m.odc); + IF nocode1 THEN p.PutParam("-b") END; + IF nocode2 THEN p.PutParam("-x") END; IF force IN m.flags THEN p.PutParam("-f") END; IF symonly OR (library IN m.flags) THEN p.PutParam("-s") END; s := def.next; @@ -536,6 +643,9 @@ MODULE DswMakeMain; p.PutParam(s.name$); s := s.next END; + FOR i := 0 TO m.mno - 1 DO + PrepareCompilerDeps(m.imp[i], p, TRUE, FALSE); + END; RETURN p END PrepareCompiler; @@ -602,6 +712,11 @@ MODULE DswMakeMain; p.PutParam(lnkList[i].name$) END END; + FOR i := 0 TO mno - 1 DO + IF library IN lnkList[i].flags THEN + PrepareCompilerDeps(lnkList[i], p, FALSE, TRUE) + END + END; p.Execute(ok); IF ok THEN p.Wait;