示例#1
0
        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();
            }
        }
示例#3
0
        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));
        }
示例#5
0
        /// <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);
        }
示例#8
0
        /// <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);
        }
示例#9
0
        /// <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);
        }