private void Parse() { this.dependencies.Add(this.projectFile); using (XmlTextReader reader = new XmlTextReader(IronRootDirectory.PathTo(this.projectFile))) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (string.Compare(reader.Name, "Compile") == 0) { this.dependencies.Add(this.projectFile.getNewSourcePath(reader.GetAttribute("Include"))); } else if (string.Compare(reader.Name, "PropertyGroup") == 0) { this.ParseOutput(reader); } } } reader.Close(); } if (this.outputType != null && this.assemblyName != null) //// && outputPath != null) { string path = Path.Combine(this.projectFile.getDirPath(), string.Format("{0}.{1}", this.assemblyName, this.OutputTypeToExtension(this.outputType))); ////Console.WriteLine("{0}: generating {1}", this.projectFile.getRelativePath(), path); this.outputs.Add(new BuildObject(path)); } else { throw new UserError(string.Format("Project {0} doesn't seem to have output specification in the expected format", this.projectFile.getRelativePath())); } }
private void Parse() { this.dependencies.Add(this.solutionFile); using (StreamReader stream = new StreamReader(IronRootDirectory.PathTo(this.solutionFile))) { Regex regex = new Regex(@"Project\([\S]+\)[\s]+=[\s]+([^$]*)", RegexOptions.IgnoreCase); string line; while ((line = stream.ReadLine()) != null) { MatchCollection matches = regex.Matches(line); if (matches.Count > 0) { SourcePath projFile = this.solutionFile.getNewSourcePath(matches[0].Groups[1].Value.Split("\", ".ToCharArray())[5]); ////Console.WriteLine(String.Format("Found project file {0}", projFile.getFilesystemPath())); VSProjectParser proj = new VSProjectParser(projFile); this.dependencies.AddRange(proj.getDependencies()); this.outputs.AddRange(proj.getOutputs()); } } stream.Close(); } }
public override IVerbWorker getWorker(WorkingDirectory workingDirectory) { // Scrub the "makeflags" environment variable from our environment // so we don't pass it down to our worker process. Some users may // have things there that conflict with our usage. Process myProcess = System.Diagnostics.Process.GetCurrentProcess(); StringDictionary environmentVariables = myProcess.StartInfo.EnvironmentVariables; environmentVariables.Remove("MAKEFLAGS"); List <string> args = new List <string>(); args.Add(string.Format("OBJ={0}\\obj", workingDirectory.PathTo(this.outputPathSuffix))); args.Add(string.Format("BIN={0}", workingDirectory.PathTo(this.outputPathSuffix))); args.Add("-f"); args.Add(workingDirectory.PathTo(this.makefile)); // TODO: Remove reliance on workingDirOverride, which currently hides dependency issues and other problems. return(new ProcessInvokeAsyncWorker( workingDirectory, this, getNmakeExecutable().getRelativePath(), ////"c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin/nmake.exe", args.ToArray(), ProcessExitCodeHandling.NonzeroIsFailure, workingDirOverride: IronRootDirectory.PathTo(this.makefile.getDirPath()), failureBase: getDiagnosticsBase(), //allowAbsoluteExe: true, allowAbsoluteArgs: true)); }
public override IVerbWorker getWorker(WorkingDirectory workingDirectory) { // TODO: We shouldn't be using absolute paths to any of these things. // Change this to allow VS and SDKs to be installed anywhere. string linker = @"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\link.exe"; string vc_lib_dir = @"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib"; string sdk_dir = @"C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86"; string kernel_lib = @"C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86\kernel32.Lib"; string standalone_support_lib = getStandaloneLib().getRelativePath(); SourcePath zero1 = new SourcePath("tools\\scripts\\zero.obj", SourcePath.SourceType.Tools); SourcePath zero2 = new SourcePath("tools\\scripts\\zero2.obj", SourcePath.SourceType.Tools); // TODO: Fail more gracefully? Or better yet, move these into iron/tools. if (!Directory.Exists(vc_lib_dir)) { throw new FileNotFoundException("Missing Visual C++ library directory: " + vc_lib_dir); } if (!Directory.Exists(sdk_dir) || !File.Exists(kernel_lib)) { throw new FileNotFoundException("Missing Windows SDK libraries: " + sdk_dir + ", " + kernel_lib + @". Try installing the Windows SDK from: \\research\Root\Products\Developers\Windows Driver Kit 8.1"); } // TODO: Unpack/generate these automatically. // TODO: Brian, we're really not going to want to cache these big, empty sources. Or compress? All big (>10MB) files. // are mostly zeros. if (!File.Exists(IronRootDirectory.PathTo(zero1)) || !File.Exists(IronRootDirectory.PathTo(zero2))) { throw new FileNotFoundException("Missing object files of zeroes: " + zero1 + ", " + zero2 + ". Try running: tools\\scripts\\build-standalone-init.sh"); } List <string> args = new List <string>() { "/DEBUG", "/subsystem:console", "/LARGEADDRESSAWARE", "/fixed" }; args.Add(objFile.getRelativePath()); args.Add(zero1.getRelativePath()); args.Add(zero2.getRelativePath()); args.Add(standalone_support_lib); args.Add(@"""" + kernel_lib + @""""); args.Add("\"/libpath:" + vc_lib_dir + '"'); args.Add("\"/libpath:" + sdk_dir + '"'); args.Add("/out:" + outputObject.getRelativePath()); args.Add("/entry:" + this.entryPoint); args.Add("/base:" + this.baseAddr); args.Add("/PDB:" + this.getPdb()); return(new ProcessInvokeAsyncWorker( workingDirectory, this, linker, args.ToArray(), ProcessExitCodeHandling.NonzeroIsFailure, getDiagnosticsBase(), allowAbsoluteExe: true, allowAbsoluteArgs: true)); }
/// <summary> /// Gets information about an object in this repository. /// Will add missing source objects to the repository as needed. /// </summary> /// <param name="obj">The object to look up.</param> /// <returns>Information about the object.</returns> /// <remarks> /// Returns null if obj isn't in this run's cache. /// Cannot return value.disposition==Stale, I guess? /// </remarks> private RepositoryEntry GetValue(BuildObject obj) { if (this.entries.ContainsKey(obj)) { return(this.entries[obj]); } else { SourcePath src = obj as SourcePath; if (src != null) { // Special case to get local source files into the // repository (and the item cache). // REVIEW: Should we require that source files are explicitly added? try { // Complain if someone uses tabs or non-CRLF line endings in a source file. // Visual Studio is pretty insistent on using tabs in solution (.sln) files, so we let it. if ((src.Type == SourcePath.SourceType.Src) && (src.getExtension() != ".sln")) { if (!Util.CheckSourceFileForBadCharacters(IronRootDirectory.PathTo(obj))) { throw new SourceConfigurationError("Bad characters (tabs?) or non-CRLF line endings in source file " + obj.getRelativePath()); } } string hash = Util.hashFilesystemPath(IronRootDirectory.PathTo(obj)); this.itemCache.StoreItemFromFile(ItemCacheContainer.Sources, hash, IronRootDirectory.PathTo(obj)); this.Add(obj, new Fresh(), hash, null); } catch (IOException) { throw new SourceConfigurationError("Cannot find source path " + obj.getRelativePath()); } return(this.entries[obj]); } else { return(null); } } }
private void parseCustomManifest(SourcePath basePath) { SourcePath manifest = basePath.getNewSourcePath("nubuild-manifest.txt"); this.dependencies.Add(manifest); using (StreamReader stream = new StreamReader(IronRootDirectory.PathTo(manifest))) { string origline; while ((origline = stream.ReadLine()) != null) { string line = origline.Trim(); if (line.Length == 0) { continue; } if (line.Substring(0, 1) == "#") { continue; } string[] parts = line.Split(); if (parts.Length != 2) { throw new UserError(string.Format("{0}: badly formed manifest line {1}", IronRootDirectory.PathTo(manifest), origline)); } if ("output".Equals(parts[0])) { this.outputs.Add(new BuildObject(Path.Combine(basePath.getDirPath(), parts[1]))); } else if ("dependency".Equals(parts[0])) { this.dependencies.Add(basePath.getNewSourcePath(parts[1])); } } } }
public BatchVerifyVerb(SourcePath batch_file, BatchMode mode, VerificationRequest verificationRequest, DafnyCCVerb.FramePointerMode useFramePointer) { this.mode = mode; this.producers = new HashSet <IObligationsProducer>(); foreach (string line in File.ReadAllLines(IronRootDirectory.PathTo(batch_file))) { if (line.Equals("") || line[0] == '#') { continue; } SourcePath src = new SourcePath(line); switch (mode) { case BatchMode.DAFNY: if (verificationRequest.verifyMode != VerificationRequest.VerifyMode.Verify) { throw new UserError("BatchVerify DAFNY only supports full verification (but maybe we should add selective?)"); } this.producers.Add(new DafnyVerifyTreeVerb(src)); break; case BatchMode.APP: this.producers.Add(new IroncladAppVerb(src, IroncladAppVerb.TARGET.BARE_METAL, useFramePointer, verificationRequest)); break; default: throw new Exception("Unknown batch file type"); } } string parameters = mode.ToString() + "," + verificationRequest.ToString(); this.outputObject = batch_file.makeLabeledOutputObject(parameters, BATCH_EXTN + VerificationObligationList.VOL_EXTN); this.abstractId = new AbstractId(this.GetType().Name, version, batch_file.ToString(), concrete: parameters); }
/// <summary> /// Adds the output objects from a cached verb execution to the /// repository, and ensures they are present in the item cache. /// </summary> /// <param name="verb">The verb whose outputs to add.</param> /// <param name="resultRecord"> /// The result summary record of the verb execution. /// </param> /// <remarks> /// Call only when output objects are known to be cached /// (i.e. because FetchResult returned non-Stale). /// REVIEW: This function probably shouldn't be in this file. /// It does something similar for cached verb results that /// the scheduler's recordResult method does for new verb /// executions. Move this there and/or refactor? /// </remarks> public void AddVerbResults(IVerb verb, ResultSummaryRecord resultRecord) { if (this.alreadyAddedVerbs.Contains(verb)) { // We only need to add a cached verb execution's outputs once. return; } Disposition disposition = resultRecord.Disposition; // REVIEW: In the below, some of these IEnumerables should be // HashSets, and the HashSet should be a simple List. // Create a collection of the potential outputs. IEnumerable <BuildObject> outputs = verb.getOutputs(); IEnumerable <BuildObject> failureOutputs = verb.getFailureOutputs(); outputs = outputs.Concat(failureOutputs); Dictionary <string, BuildObject> potentialOutputs = new Dictionary <string, BuildObject>(); foreach (BuildObject obj in outputs) { potentialOutputs.Add(obj.getRelativePath(), obj); } // Compare the actual outputs with the potential outputs, // and add the actual ones to the repository. HashSet <BuildObject> recorded = new HashSet <BuildObject>(); foreach (BuildObjectValuePointer actualOutput in resultRecord.Outputs) { if (potentialOutputs.ContainsKey(actualOutput.RelativePath)) { BuildObject obj = potentialOutputs[actualOutput.RelativePath]; // TODO: Verify that the object exists in the item cache! this.AddObject(obj, disposition, actualOutput.ObjectHash); recorded.Add(obj); // Store a copy of this verb output as a file in the real nuobj directory. Util.Assert(actualOutput.RelativePath.StartsWith(BuildEngine.theEngine.getObjRoot(), StringComparison.Ordinal)); this.itemCache.FetchItemToFile(ItemCacheContainer.Objects, actualOutput.ObjectHash, IronRootDirectory.PathTo(actualOutput.RelativePath)); } else { // Complain if we find interloping outputs. throw new Exception("Distressing: some actual verb outputs aren't in the verb's list of potential outputs"); } } // Create a collection of missing outputs. IEnumerable <BuildObject> unrecorded = outputs.Except(recorded).Except(failureOutputs); // For non-Failed verb runs, complain if all expected outputs don't // show up in the actual outputs. Util.Assert(unrecorded.Count() == 0 || disposition is Failed); // For cached verb runs with permanent failures (i.e. disposition // is Failed), we want to mark all of the expected outputs as Failed // even if no corresponding actual output was produced during the // failed verb run. foreach (BuildObject obj in unrecorded) { this.AddObject(obj, disposition, null); } // Remember that we've already added this verb's outputs. this.alreadyAddedVerbs.Add(verb); }
/// <summary> /// Record how each output of a task appeared. /// </summary> /// <param name="completion">The task completion notification.</param> /// <returns>Overall result of the verb execution.</returns> private Disposition recordResult(VerbRunner.TaskCompletion completion) { WorkingDirectory workingDirectory = completion.workingDirectory; IVerb verb = completion.verb; Disposition executionDisposition = completion.disposition; List <BuildObjectValuePointer> outputs = new List <BuildObjectValuePointer>(); List <string> missingOutputs = new List <string>(); IEnumerable <BuildObject> expectedOutputs = verb.getOutputs(); if (executionDisposition is Failed) { expectedOutputs = expectedOutputs.Concat(verb.getFailureOutputs()); } bool hasVirtualOutputs = false; foreach (BuildObject outobj in expectedOutputs) { if (!(outobj is VirtualBuildObject)) { // For expected file outputs, check for existence in working directory. // REVIEW: Add method to WorkingDirectory which does this? if (File.Exists(workingDirectory.PathTo(outobj))) { // Try to catch accidental case mismatches that would burn us when we // try to fetch the file back in. ////string fsname = PathNormalizer.dbg_normalizePath_nocache(outobj.deprecatedGetFilesystemPath(), false); ////Util.Assert(Path.GetFileName(fsname).Equals(outobj.getFileName())); // REVIEW: Do we need to worry about case mismatches anymore? See comments above. outputs.Add(this.repository.Store(workingDirectory, outobj, executionDisposition)); // Store a copy of this verb output as a file in the real nuobj directory. Util.Assert(outobj.getRelativePath().StartsWith(BuildEngine.theEngine.getObjRoot(), StringComparison.Ordinal)); string nuobjPath = IronRootDirectory.PathTo(outobj); Directory.CreateDirectory(Path.GetDirectoryName(nuobjPath)); File.Copy(workingDirectory.PathTo(outobj), nuobjPath, true); } else { missingOutputs.Add(string.Format("Missing expected output {0}", outobj.getRelativePath())); } } else { hasVirtualOutputs = true; if (this.repository.GetDisposition(outobj) is Fresh) { // Nothing to cache; virtual objects only survive in the Repository, the in-process store. } else { missingOutputs.Add(string.Format("Missing expected virtual {0}", outobj.getRelativePath())); } } } if (!(executionDisposition is Failed) && missingOutputs.Count() > 0) { executionDisposition = new Failed(missingOutputs); } ResultSummaryRecord summary = new ResultSummaryRecord(verb, executionDisposition, outputs); string inputHash = this.computeInputHash(verb, true); Util.Assert(inputHash != null); if (!hasVirtualOutputs) { this.repository.StoreResult(inputHash, summary); } else { this.Say("Not caching verb persistently: " + verb); } this.verbIsComplete(verb, executionDisposition); return(executionDisposition); }