コード例 #1
0
            public static CrossgenArguments ParseFromResponseFile(string responseFile)
            {
                var arguments = new CrossgenArguments();

                string[] tokenizedArguments = TokenizeArguments(responseFile);

                for (int i = 0; i < tokenizedArguments.Length; i++)
                {
                    string arg = tokenizedArguments[i];
                    if (MatchParameter("in", arg))
                    {
                        arguments.InputFile = tokenizedArguments[i + 1];
                    }
                    else if (MatchParameter("App_Paths", arg) || MatchParameter("Platform_Assemblies_Paths", arg))
                    {
                        string appPaths = tokenizedArguments[i + 1];
                        arguments.ReferencePaths.AddRange(appPaths.Split(';').TakeWhile(x => !string.IsNullOrWhiteSpace(x)));
                        ++i;
                    }
                    else if (MatchParameter("verbose", arg) ||
                             MatchParameter("readytorun", arg))
                    {
                        // Skip unparameterized switches
                        continue;
                    }
                    else if (MatchParameter("jitpath", arg))
                    {
                        // Skip switches with one parameter
                        ++i;
                        continue;
                    }
                    else if (!IsSwitch(arg))
                    {
                        Debug.Assert(arguments.InputFile == null);
                        arguments.InputFile = arg;
                    }
                }

                return(arguments);
            }
コード例 #2
0
        /// <summary>
        /// Utility mode that allows compilation of a set of assemblies using their existing Crossgen response files.
        /// This is currently useful for workloads like Bing which have a large complicated web of binaries in different folders
        /// with potentially different sets of reference paths used for different assemblies.
        /// </summary>
        public static int CompileFromCrossgenRsp(BuildOptions options)
        {
            if (options.CrossgenResponseFile == null && options.InputDirectory == null)
            {
                Console.Error.WriteLine("Specify --response-file or --input-directory containing multiple response files.");
                return(1);
            }

            if (options.CoreRootDirectory == null)
            {
                Console.Error.WriteLine("--core-root-directory (--cr) is a required argument.");
                return(1);
            }

            if (options.OutputDirectory == null)
            {
                if (options.InputDirectory != null)
                {
                    options.OutputDirectory = options.InputDirectory;
                }
                else
                {
                    options.OutputDirectory = new DirectoryInfo(Path.GetDirectoryName(options.CrossgenResponseFile.FullName));
                }
            }
            else if (options.InputDirectory != null && options.OutputDirectory.IsParentOf(options.InputDirectory))
            {
                Console.Error.WriteLine("Error: Input and output folders must be distinct, and the output directory (which gets deleted) better not be a parent of the input directory.");
                return(1);
            }

            // This command does not work in the context of an app, just a loose set of rsp files so don't execute anything we compile
            options.NoJit = true;
            options.NoEtw = true;

            //
            // Determine whether we're compiling a single .rsp or a folder of them
            //
            var responseFiles = new List <string>();

            if (options.CrossgenResponseFile != null)
            {
                responseFiles.Add(options.CrossgenResponseFile.FullName);
            }
            else
            {
                responseFiles = Directory.EnumerateFiles(options.InputDirectory.FullName, "*.rsp", SearchOption.TopDirectoryOnly).ToList();
            }

            Dictionary <string, string> pathReplacements = new Dictionary <string, string>();

            if ((options.RewriteOldPath == null) != (options.RewriteNewPath == null))
            {
                Console.Error.WriteLine("Error: --rewrite-old-path and --rewrite-new-path must both be specified if either is used.");
                return(1);
            }

            if (options.RewriteOldPath != null && options.RewriteNewPath != null)
            {
                if (options.RewriteOldPath.Length != options.RewriteNewPath.Length)
                {
                    Console.Error.WriteLine("Error: --rewrite-old-path and --rewrite-new-path were specified a different number of times.");
                    return(1);
                }

                for (int i = 0; i < options.RewriteNewPath.Length; i++)
                {
                    pathReplacements.Add(options.RewriteOldPath[i].FullName, options.RewriteNewPath[i].FullName);
                    Console.WriteLine($"Re-writing path {options.RewriteOldPath[i].FullName} as {options.RewriteNewPath[i].FullName}");
                }
            }

            bool success             = true;
            int  compilationFailures = 0;
            int  totalCompilations   = 0;

            // Collect all the compilations first
            foreach (var inputRsp in responseFiles)
            {
                var crossgenArguments = CrossgenArguments.ParseFromResponseFile(inputRsp)
                                        .ReplacePaths(pathReplacements);

                Console.WriteLine($"{inputRsp} -> {crossgenArguments.InputFile}");
                var compilerRunners = options.CompilerRunners(false, crossgenArguments.ReferencePaths);

                string responseFileOuputPath = Path.Combine(options.OutputDirectory.FullName, Path.GetFileNameWithoutExtension(inputRsp));
                responseFileOuputPath.RecreateDirectory();

                List <ProcessInfo> fileCompilations = new List <ProcessInfo>();
                foreach (CompilerRunner runner in compilerRunners)
                {
                    var compilationProcess = new ProcessInfo(new CompilationProcessConstructor(runner, responseFileOuputPath, new string[] { crossgenArguments.InputFile }));
                    fileCompilations.Add(compilationProcess);
                }

                ParallelRunner.Run(fileCompilations, options.DegreeOfParallelism);
                totalCompilations++;

                foreach (var compilationProcess in fileCompilations)
                {
                    if (!compilationProcess.Succeeded)
                    {
                        success = false;
                        compilationFailures++;

                        Console.WriteLine($"Failed compiling {compilationProcess.Parameters.OutputFileName}");
                    }
                }
            }

            Console.WriteLine("Rsp Compilation Results");
            Console.WriteLine($"Total compilations: {totalCompilations}");
            Console.WriteLine($"Compilation failures: {compilationFailures}");

            return(success ? 0 : 1);
        }