<<>> <> <> <> <> <> <> <> <> <> <> <<>> DIRECTORY Atom, Basics, BasicTime, Commander, CommanderOps, FileNames, FS, IO, MakeDo, MakeDoGrossHack, MakeDoParsers, MakeDoPorting, MakeDoPrivate, MobDefs, Mobery, MobListerUtils, PFS, PFSNames, RefTab, Rope, SimpleFeedback, UserProfile; CcDeps: CEDAR MONITOR IMPORTS Atom, Basics, BasicTime, Commander, CommanderOps, FileNames, FS, IO, MakeDo, MakeDoParsers, MakeDoPorting, MakeDoPrivate, Mobery, MobListerUtils, PFS, PFSNames, RefTab, Rope, SimpleFeedback, UserProfile EXPORTS MakeDoGrossHack <> <> = BEGIN OPEN MakeDo, MDPs:MakeDoParsers; ShouldNotHappen: ERROR = CODE; ROPE: TYPE = Rope.ROPE; StampTableRef: TYPE = REF StampTableRep; StampTableRep: TYPE = RECORD [ created: BasicTime.GMT, <> stampTable: Mobery.StampTable, depInfoValid: BOOL ¬ FALSE, stampTableValid: BOOL ¬ FALSE]; <> <<>> SourceData: TYPE = REF SourceDataRep; SourceDataRep: TYPE = RECORD [ <> switchesPath: PFS.PATH, --absolute oName: ROPE, --absolute, unspecified format baseName: ROPE, --working directory in FS format subName: ROPE, --output subdirectory (eg, sun4/); may be NIL shortName: ROPE, --the part after last directory delim and before .c2c.o sourceType: MDPs.SourceType ¬ Unknown, genesis: Genesis, supports: RefTab.Ref, --node => $T mesaNode, cedarNode, configNode, switchesNode, oNode, cNode: Node ¬ NIL, <> <> stampTable: Mobery.StampTable ¬ NIL, <> oCreateTime: BasicTime.GMT, oReadable: BOOL, <> <> useAltSwitches: BOOL, --GROSS HACK! supportsInvalid: BOOL ¬ FALSE, cmd: ROPE ¬ NIL ]; Genesis: TYPE ~ {C, Cedar, Scheme}; installDir: ROPE ~ FileNames.CurrentWorkingDirectory[]; installed, badInstall: BOOL ¬ FALSE; dolog: BOOL ¬ FALSE; myRouterName: ATOM ~ Atom.MakeAtom["MakeDo.CcDeps"]; findAltSwitches: BOOL ¬ FALSE; <> c2cTail: ROPE = ".c2c"; sxTail: ROPE = ".sx"; c2coTail: ROPE = Rope.Concat[c2cTail, ".o"]; c2coTailLength: INT = c2coTail.Length[]; sxoTail: ROPE = Rope.Concat[sxTail, ".o"]; sxoTailLength: INT = sxoTail.Length[]; c2ccTail: ROPE = Rope.Concat[c2cTail, ".c"]; sxcTail: ROPE = Rope.Concat[sxTail, ".c"]; mobExt: ROPE = "mob"; mobTail: ROPE = Rope.Concat[".", mobExt]; mesaTail: ROPE = ".mesa"; cedarTail: ROPE = ".cedar"; configTail: ROPE = ".config"; schemeTail: ROPE = ".scheme"; clusterTail: ROPE = ".cluster"; switchesTail: ROPE = ".switches"; libTail: ROPE = ".a"; libTailLen: INT ~ libTail.Length[]; oTail: ROPE = ".o"; oTailLen: INT ~ oTail.Length[]; cTail: ROPE = ".c"; DirAndClass: TYPE = RECORD [ dir: ROPE, -- the directory name -- class: ROPE, -- the corresponding machine class -- switches: ROPE, -- the default switches -- altSwitches: ROPE ¬ NIL --the alternate switches => GROSS HACK ]; ClassDir: TYPE ~ RECORD [ dir: ROPE, switches: ROPE]; UserClass: TYPE ~ RECORD[ class: ROPE, classDirs: LIST OF ClassDir]; userClassList: LIST OF UserClass; currentClass: ROPE _ NIL; currentClassDirs: LIST OF ClassDir _ NIL; cg: ROPE ~ "-c -g"; cO: ROPE ~ "-c -O"; cgf: ROPE ~ "-c -g -fsingle"; cOf: ROPE ~ "-c -O -fsingle"; cO2f: ROPE ~ "-c -O2 -fsingle"; cO3f: ROPE ~ "-c -O3 -fsingle"; knownLocalDirs: LIST OF DirAndClass ¬ LIST[ DirAndClass[dir: "sun3", class: "sun3", switches: cgf], DirAndClass[dir: "sun4-debug", class: "sun4", switches: cgf], DirAndClass[dir: "sun4", class: "sun4", switches: cO2f, altSwitches: cgf], DirAndClass[dir: "sun4-o3", class: "sun4", switches: cO3f, altSwitches: cO2f], DirAndClass[dir: "sun4o3", class: "sun4", switches: cO3f, altSwitches: cO2f], DirAndClass[dir: "29k", class: "amd29000", switches: cgf], DirAndClass[dir: "sun4-profiled", class: "sun4", switches: "-c -p -fsingle"], DirAndClass[dir: "sun4-gprof", class: "sparc", switches: "-c -pg -fsingle"], DirAndClass[dir: "rs6000", class: "rs6000", switches: cgf], DirAndClass[dir: "rs6000o", class: "rs6000", switches: cOf], DirAndClass[dir: "rs6000-o", class: "rs6000", switches: cOf], DirAndClass[dir: "mipsl", class: "mipsl", switches: cg], DirAndClass[dir: "mipsl-o", class: "mipsl", switches: cO], DirAndClass[dir: "mips", class: "mips", switches: cg], DirAndClass[dir: "mips-o", class: "mips", switches: cO] ]; -- if in these directories, we issue this -mach -- CcClass: ActionClass ¬ NEW [ActionClassRep ¬ [ CheckConsistency: CheckConsistency, Rederive: RederiveSource, ClearCaches: ClearCaches ]]; ClearCaches: PROC [ac: ActionClass] ~ { MDPs.FlushCache[]; installed ¬ badInstall ¬ FALSE; }; SetOLevel: PUBLIC PROC [high: BOOL] ~ {findAltSwitches ¬ NOT high}; SourceFind: PROC [resultName: ROPE, finderData: REF ANY] RETURNS [found: BOOLEAN, sought: Node, makes, cmdFrom: NodeList, from: From, cmd: ROPE, class: ActionClass, foundData: REF ANY] -- FinderProc -- ~ { <> <> shortName: ROPE; -- the part after last directory delim and before .c2c.o middleName: ROPE; --either .c2c, .sx, or null subName: ROPE ¬ NIL; --output subdirectory (eg, sun4/); may be NIL localDir: PFS.PATH; --output subdirectory (eg, sun4/); may be null baseDir: PFS.PATH; --full expanded name, up to, but not including, the sun3 directory part baseName, oName, cName, switchesName: ROPE; oExpanded: PFS.PATH; oSteps: INTEGER; oNode, cNode: Node; genesis: Genesis; md: SourceData; resNameLen: INT ~ resultName.Length[]; found ¬ NOT badInstall; IF NOT found THEN RETURN; found ¬ resNameLen > oTailLen AND resultName.EqualSubstrs[start1: resNameLen-oTailLen, s2: oTail, case: FALSE]; <> IF NOT found THEN RETURN; IF NOT installed THEN InstallMe[]; found ¬ NOT badInstall; IF NOT found THEN RETURN; oExpanded ¬ PFS.AbsoluteName[PFS.PathFromRope[resultName !PFS.Error => {found ¬ FALSE; CONTINUE}]]; IF NOT found THEN RETURN; oSteps ¬ oExpanded.ComponentCount[]; IF resNameLen >= c2coTailLength AND resultName.EqualSubstrs[start1: resNameLen - c2coTailLength, s2: c2coTail, case: FALSE] THEN {genesis ¬ Cedar; middleName ¬ c2cTail} ELSE IF resNameLen >= sxoTailLength AND resultName.EqualSubstrs[start1: resNameLen - sxoTailLength, s2: sxoTail, case: FALSE] THEN {genesis ¬ Scheme; middleName ¬ sxTail} ELSE {genesis ¬ C; middleName ¬ NIL}; IF oSteps > 1 AND genesis#Scheme THEN { localDir ¬ oExpanded.SubName[oSteps-2, 1, FALSE, TRUE]; subName ¬ PFS.RopeFromPath[localDir]; IF RemoteMachClassAndSwitches[subName, knownLocalDirs, findAltSwitches].mach = NIL THEN {localDir ¬ oExpanded.SubName[oSteps-2, 0]; subName ¬ NIL}; <> } ELSE localDir ¬ oExpanded.SubName[0, 0]; baseDir ¬ oExpanded.SubName[0, oSteps-1-localDir.ComponentCount[], TRUE, TRUE]; {shortComp: PFSNames.Component ¬ oExpanded.ShortName[]; shortComp.name.len ¬ shortComp.name.len - middleName.Length[] - oTailLen; shortName ¬ shortComp.ComponentRope[]}; {bpn: ROPE ~ PFS.RopeFromPath[baseDir]; oName ¬ bpn.Cat[subName, shortName, middleName, oTail]; baseName ¬ FS.ExpandName[bpn].fullFName}; cName ¬ baseName.Cat[shortName, middleName, cTail]; switchesName ¬ oName.Concat[switchesTail]; oNode ¬ GetNode[oName, fileClass]; cNode ¬ GetNode[cName, fileClass]; foundData ¬ md ¬ NEW [SourceDataRep ¬ [ switchesPath: PFS.PathFromRope[switchesName], oName: oName, baseName: baseName, subName: subName, shortName: shortName, genesis: genesis, supports: RefTab.Create[], switchesNode: GetNode[switchesName, fileClass], oNode: oNode, cNode: cNode, oReadable: genesis#Cedar, oCreateTime: MakeDo.notExistTime, useAltSwitches: findAltSwitches ]]; SELECT genesis FROM C => cmdFrom ¬ LIST[md.cNode, md.switchesNode]; Cedar => { md.mesaNode ¬ GetNode[Rope.Cat[baseName, shortName, mesaTail], fileClass]; md.cedarNode ¬ GetNode[Rope.Cat[baseName, shortName, cedarTail], fileClass]; md.configNode ¬ GetNode[Rope.Cat[baseName, shortName, configTail], fileClass]; cmdFrom ¬ LIST[md.cedarNode, md.mesaNode, md.configNode, md.switchesNode]}; Scheme => { md.mesaNode ¬ GetNode[Rope.Cat[baseName, shortName, schemeTail], fileClass]; md.configNode ¬ GetNode[Rope.Cat[baseName, shortName, clusterTail], fileClass]; cmdFrom ¬ LIST[md.mesaNode, md.configNode]}; ENDCASE => ERROR; sought ¬ md.oNode; class ¬ CcClass; [from, cmd] ¬ RederiveWork[md]; makes ¬ LIST[md.oNode]; RETURN}; GetSwitches: PROC [sp: PFS.PATH, defaultMsw: ROPE] RETURNS [switches: ROPE ¬ NIL] = { ss: IO.STREAM ¬ NIL; ss ¬ PFS.StreamOpen[sp !PFS.Error => CONTINUE]; IF ss # NIL THEN { [] ¬ ss.SkipWhitespace[]; IF NOT ss.EndOf[] THEN switches ¬ IO.GetLineRope[ss]; ss.Close[]}; IF switches.Length = 0 THEN switches ¬ IO.PutFR1["-mSw \"%q\"", [rope[defaultMsw]] ] ELSE IF switches.Fetch[0] = '; THEN switches ¬ IO.PutFR["-mSw \"%q\" %g", [rope[defaultMsw]], [rope[switches.Substr[1]]] ] ELSE switches ¬ IO.PutFR1["-mSw \"%q\"", [rope[switches]] ]; RETURN}; SupportIsLoaded: PROC [] RETURNS [BOOL] ~ { moberies, moblisteries, pfs: BOOL; moberies ¬ Basics.IsBound[LOOPHOLE[Mobery.ReadStampTable]] AND Basics.IsBound[LOOPHOLE[Mobery.StampTableSubset]]; moblisteries ¬ Basics.IsBound[LOOPHOLE[MobListerUtils.PrintVersion]]; <> pfs ¬ Basics.IsBound[LOOPHOLE[PFS.PathFromRope]] AND Basics.IsBound[LOOPHOLE[PFS.AbsoluteName]]; RETURN [moberies AND moblisteries AND pfs]; }; InstallMe: PROC ~ { foundFile, failed: BOOL; IF SupportIsLoaded[] THEN { installed ¬ TRUE; RETURN; }; [foundFile, failed] ¬ MakeDoPrivate.MDInstall[installDir, "CcDepsSupport"]; badInstall ¬ failed OR NOT foundFile; installed ¬ TRUE; IF NOT foundFile THEN Warning[Rope.Cat["Couldn't install CcDeps support because couldn't find ", installDir, "CcDepsSupport.Install (see ", MakeDoPorting.logPath, "CcDepsSupport.InstallLog); proceeding without knowledge of Cc"]] ELSE IF failed THEN Warning[Rope.Cat["Couldn't install CcDeps support because of error in install file (", installDir, "CcDepsSupport.Install) (see ", MakeDoPorting.logPath, "CcDepsSupport.InstallLog); proceeding without knowledge of Cc"]]; RETURN}; CheckConsistency: PROC [a: Action, result: Node] RETURNS [consistent: BOOL, reason: ROPE] --ConsistencyChecker-- = <> <> BEGIN md: SourceData = NARROW[a.PublicPartsOfAction[].foundData]; switchesCreate: BasicTime.GMT = InnerGetCreated[md.switchesNode]; curCTime: Time = InnerGetCreated[md.cNode] ; -- Creation time of the C node -- resultExists: BOOL; supportFound: BOOL ¬ FALSE; CheckSupport: PROC [key, val: REF ANY] RETURNS [stop: BOOL ¬ FALSE] --RefTab.EachPairAction-- ~ { <> <> sn: Node = MakeDo.NarrowToNode[key]; thisTime: Time = InnerGetCreated[sn]; thisName: ROPE ~ sn.PublicPartsOfNode[].name; thisIsLib: BOOL ~ IsLibName[thisName]; <> thisStampTable: Mobery.StampTable; IF thisTime = MakeDo.notExistTime THEN RETURN [FALSE]; supportFound ¬ TRUE; IF NOT resultExists THEN RETURN [supportFound]; IF BasicTime.Period[thisTime, md.oCreateTime] < 0 THEN { consistent ¬ FALSE; reason ¬ IO.PutFR[".o file created at %g but %g was created at %g", [time[md.oCreateTime]], [rope[thisName]], [time[thisTime]] ]; RETURN [TRUE]; }; IF thisIsLib OR md.genesis#Cedar THEN RETURN [FALSE]; <> <> <> <> <> <> <> <> <<};>> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<}>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<}>> }; Log["check consistency for %g\n", IO.rope[md.oName]]; UpdateSupport[md]; resultExists ¬ md.oCreateTime # MakeDo.notExistTime; SELECT md.sourceType FROM Mesa, Config, PlainC, Scheme, Cluster => NULL; Unknown => RETURN [TRUE, "No source is known for this result"]; ENDCASE => ERROR ShouldNotHappen; IF resultExists AND NOT md.oReadable THEN RETURN [FALSE, ".o file not readable"]; IF switchesCreate # MakeDo.notExistTime THEN { supportFound ¬ TRUE; IF resultExists AND BasicTime.Period[md.oCreateTime, switchesCreate] > 0 THEN RETURN [FALSE, "switches file created later than result"]}; consistent ¬ TRUE; reason ¬ "all version stamps match"; [] ¬ md.supports.Pairs[CheckSupport]; IF NOT supportFound THEN RETURN [TRUE, "no inputs exist to indicate inconsistency"]; IF NOT resultExists THEN RETURN [FALSE, "some inputs but no result exists"]; END; UpdateSupport: PROC [md: SourceData] = { <> <> oldO: Time = md.oCreateTime; length: INT; [md.oCreateTime, length] ¬ InnerGetInfo[md.oNode]; IF length=0 THEN md.oCreateTime ¬ MakeDo.notExistTime; IF md.oCreateTime = MakeDo.notExistTime THEN RETURN; IF oldO = md.oCreateTime AND NOT md.supportsInvalid THEN RETURN; <> IF md.genesis=Cedar THEN { <> <> <> md.stampTable ¬ CurStampTab[node: md.oNode]; <> md.oReadable ¬ md.stampTable # NIL; }; md.supportsInvalid ¬ FALSE; }; CurStampTab: ENTRY PROC [node: Node] RETURNS [stampTable: Mobery.StampTable] ~ { <> ENABLE UNWIND => {}; sr: StampTableRef ¬ NARROW[node.GetProp[$StampTable]]; created: BasicTime.GMT ¬ InnerGetCreated[node]; fileName: ROPE ~ node.PublicPartsOfNode[].name; GetIt: PROC [] RETURNS [stampTable: Mobery.StampTable] ~ INLINE { Log["ReadStampTable for %g\n", IO.rope[fileName]]; stampTable ¬ Mobery.ReadStampTable[fileName !FS.Error => {stampTable ¬ NIL; CONTINUE}]; Log[".. %g\n", IO.rope[IF stampTable = NIL THEN "F" ELSE "S"]]; RETURN [stampTable]; }; IF sr = NIL THEN node.SetProp[ prop: $StampTable, val: sr ¬ NEW [StampTableRep ¬ [ created: notExistTime, <> stampTable: NIL]] ]; IF created = MakeDo.notExistTime THEN { sr.stampTable ¬ NIL; <> sr.stampTableValid ¬ sr.depInfoValid ¬ TRUE; RETURN [stampTable: sr.stampTable]; -- cached value -- }; IF created = sr.created THEN { IF NOT sr.stampTableValid THEN { sr.stampTableValid ¬ TRUE; sr.stampTable ¬ GetIt[]; }; RETURN [stampTable: sr.stampTable]; -- cached value -- }; sr.created ¬ created; sr.stampTableValid ¬ TRUE; sr.depInfoValid ¬ FALSE; sr.stampTable ¬ GetIt[]; stampTable ¬ sr.stampTable; RETURN [stampTable: stampTable] }; <> <> <> <<};>> <<>> <> <> < {};>> <> <> <> <> <> <> <> <];>> <> <<};>> <> <> <> <> <> <> <<};>> <> <> <> <> <> <> <> <> <> <> <<};>> <> <> <<};>> <<<> <> <> <> <> <<]];>> <<};>>>> <> <<<