DIRECTORY Atom, BasicTime, CommandTool, ExtendADotOut, FS, IO, MakeDo, MakeDoGrossHack, MakeDoParsers, MakeDoPorting, MakeDoPrivate, MobDefs, Mobery, MobListerUtils, PBasics, PFS, PFSNames, RefTab, Rope, SimpleFeedback, UserProfile; CcDeps: CEDAR MONITOR IMPORTS Atom, BasicTime, CommandTool, FS, IO, MakeDo, MakeDoParsers, MakeDoPorting, MakeDoPrivate, Mobery, MobListerUtils, PBasics, 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, depInfo: ExtendADotOut.DependencyInfo, 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, bschemeNode: Node _ NIL, boot: BOOL _ FALSE, depInfo: ExtendADotOut.DependencyInfo _ 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 ~ CommandTool.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.Cat[c2cTail, ".o"]; c2coTailLength: INT = c2coTail.Length[]; sxoTail: ROPE = Rope.Cat[sxTail, ".o"]; sxoTailLength: INT = sxoTail.Length[]; c2ccTail: ROPE = Rope.Cat[c2cTail, ".c"]; sxcTail: ROPE = Rope.Cat[sxTail, ".c"]; mobExt: ROPE = "mob"; mobTail: ROPE = Rope.Cat[".", mobExt]; mesaTail: ROPE = ".mesa"; cedarTail: ROPE = ".cedar"; configTail: ROPE = ".config"; schemeTail: ROPE = ".scheme"; bschemeTail: ROPE = ".bscheme"; 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 ]; knownLocalDirs: LIST OF DirAndClass = LIST[ DirAndClass[dir: "sun3", class: "sun3", switches: "-c -g"], DirAndClass[dir: "sun4", class: "sun4", switches: "-c -g"], DirAndClass[dir: "sun4-o3", class: "sun4", switches: "-c -O3", altSwitches: "-c -O2"], DirAndClass[dir: "sun4o3", class: "sun4", switches: "-c -O3", altSwitches: "-c -O2"], DirAndClass[dir: "29k", class: "amd29000", switches: "-c -g"], DirAndClass[dir: "sun4-profiled", class: "sun4", switches: "-c -p"], DirAndClass[dir: "sun4-gprof", class: "sparc", switches: "-c -pg"], DirAndClass[dir: "rs6000", class: "rs6000", switches: "-c -g"], DirAndClass[dir: "rs6000o", class: "rs6000", switches: "-c -O", altSwitches: "-c -O"], DirAndClass[dir: "rs6000-o", class: "rs6000", switches: "-c -O", altSwitches: "-c -O"], DirAndClass[dir: "mipsl", class: "mipsl", switches: "-c -g", altSwitches: "-c -g"], DirAndClass[dir: "mipsl-o", class: "mipsl", switches: "-c -O", altSwitches: "-c -O"], DirAndClass[dir: "mips", class: "mips", switches: "-c -g", altSwitches: "-c -g"], DirAndClass[dir: "mips-o", class: "mips", switches: "-c -O", altSwitches: "-c -O"] ]; -- 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.bschemeNode _ GetNode[Rope.Cat[baseName, shortName, bschemeTail], fileClass]; md.configNode _ GetNode[Rope.Cat[baseName, shortName, clusterTail], fileClass]; cmdFrom _ LIST[md.mesaNode, md.bschemeNode, md.configNode]}; ENDCASE => ERROR; sought _ md.oNode; class _ CcClass; [from, cmd] _ RederiveWork[md]; makes _ LIST[md.oNode]; RETURN}; GetSwitches: PROC [sp: PFS.PATH] 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[]}; RETURN}; MesafySwitches: PROC [switches, defaultMsw: ROPE] RETURNS [ROPE] = { IF switches.Length = 0 THEN switches _ IO.PutFR["-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.PutFR["-mSw \"%q\"", [rope[switches]] ]; RETURN [switches]}; SupportIsLoaded: PROC [] RETURNS [BOOL] ~ { moberies, moblisteries, pfs: BOOL; moberies _ PBasics.IsBound[LOOPHOLE[Mobery.ReadStampTable]] AND PBasics.IsBound[LOOPHOLE[Mobery.StampTableSubset]]; moblisteries _ PBasics.IsBound[LOOPHOLE[MobListerUtils.PrintVersion]]; pfs _ PBasics.IsBound[LOOPHOLE[PFS.PathFromRope]] AND PBasics.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]; thisDepInfo: ExtendADotOut.DependencyInfo; 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]; thisDepInfo _ CurDepInfo[node: sn]; IF thisDepInfo # NIL AND ContainsDepInfo[md.depInfo] THEN { StampInDepInfo: PROC [name: ROPE, depInfo: ExtendADotOut.DependencyInfo] RETURNS [stamp: MobDefs.VersionStamp _ MobDefs.NullVersion] ~ { FOR list: LIST OF ExtendADotOut.ObjectID _ depInfo.dependList, list.rest WHILE list # NIL DO id: ExtendADotOut.ObjectID ~ list.first; IF Rope.Equal[s1: id.name, s2: name] THEN RETURN [id.stamp]; ENDLOOP; }; stampUsed: MobDefs.VersionStamp ~ StampInDepInfo[thisName, md.depInfo]; IF thisDepInfo.self.stamp # stampUsed THEN { out: IO.STREAM _ IO.ROS[]; out.PutF["Version stamp of %g (", IO.rope[thisName]]; TRUSTED {MobListerUtils.PrintVersion[thisDepInfo.self.stamp, out, TRUE]}; out.PutF[") is different from the version stamp used to create %g (", IO.rope[md.oName]]; TRUSTED {MobListerUtils.PrintVersion[stampUsed, out, TRUE]}; out.PutF[")"]; consistent _ FALSE; reason _ out.RopeFromROS[]; RETURN [TRUE]; }; } ELSE { diff: ROPE _ NIL; NoteDiff: PROC [name, stampClass: ROPE, stamp: MobDefs.VersionStamp] RETURNS [BOOL] --Mobery.EnumerateStampProc-- ~ { elt: ROPE ~ IO.PutFR["%g: %g!%08x%08x", [rope[stampClass]], [rope[name]], [cardinal[stamp[0]]], [cardinal[stamp[1]]] ]; IF diff=NIL THEN diff _ elt ELSE diff _ diff.Cat[", ", elt]; RETURN [FALSE]}; IF md.stampTable = NIL THEN md.stampTable _ CurStampTab[node: md.oNode]; thisStampTable _ CurStampTab[node: sn]; Mobery.EnumerateStampTableDifference[thisStampTable, md.stampTable, NoteDiff]; IF diff#NIL THEN { consistent _ FALSE; reason _ IO.PutFR["Some stamps (%g) in %g are not in %g", [rope[diff]], [rope[thisName]], [rope[md.oName]] ]; RETURN [TRUE]; }; } }; 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; oLength: INT; [md.oCreateTime, oLength]_ InnerGetInfo[md.oNode]; IF oLength=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.depInfo _ CurDepInfo[node: md.oNode]; IF NOT ContainsDepInfo[md.depInfo] THEN md.stampTable _ CurStampTab[node: md.oNode]; md.oReadable _ md.depInfo # NIL OR 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, depInfo: NIL, stampTable: NIL]] ]; IF created = MakeDo.notExistTime THEN { sr.stampTable _ NIL; sr.depInfo _ 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] }; ContainsDepInfo: PROC [depInfo: ExtendADotOut.DependencyInfo] RETURNS [BOOL] ~ INLINE { IF depInfo = NIL THEN RETURN [FALSE]; RETURN [depInfo.action.class # null]; }; CurDepInfo: ENTRY PROC [node: Node] RETURNS [depInfo: ExtendADotOut.DependencyInfo] ~ { ENABLE UNWIND => {}; sr: StampTableRef _ NARROW[node.GetProp[$StampTable]]; created: BasicTime.GMT _ InnerGetCreated[node]; fileName: ROPE ~ node.PublicPartsOfNode[].name; len: INT ~ Rope.Length[fileName]; ExpandNamesInDepInfo: PROC [depInfo: ExtendADotOut.DependencyInfo, fileName: ROPE] RETURNS [newInfo: ExtendADotOut.DependencyInfo] ~ { FromSlash: PROC [old: CHAR] RETURNS [CHAR] ~ { IF old = '/ THEN RETURN ['>]; RETURN [old]; }; base: ROPE; selfName: ROPE ~ depInfo.self.name; selfConverted: ROPE; IF selfName.Fetch[0] = '/ THEN { selfConverted _ FS.ExpandName[selfName].fullFName; depInfo.self.name _ selfConverted; base _ NIL; } ELSE { tailPos: INT; selfConverted _ Rope.Translate[base: selfName, translator: FromSlash]; tailPos _ fileName.FindBackward[s2: selfConverted, case: TRUE]; IF tailPos = -1 THEN RETURN [NIL]; base _ fileName.Substr[len: tailPos]; depInfo.self.name _ FS.ExpandName[name: selfConverted, wDir: base].fullFName; }; FOR list: LIST OF ExtendADotOut.ObjectID _ depInfo.dependList, list.rest WHILE list # NIL DO id: ExtendADotOut.ObjectID _ list.first; IF id.name.Fetch[0] # '/ THEN IF base = NIL THEN RETURN [NIL] ELSE { tailConverted: ROPE ~ Rope.Translate[base: id.name, translator: FromSlash]; newName: ROPE ~ FS.ExpandName[name: tailConverted, wDir: base].fullFName; list.first.name _ newName; }; ENDLOOP; RETURN [depInfo]; }; <> GetIt: PROC [] RETURNS [depInfo: ExtendADotOut.DependencyInfo _ NIL] ~ { <