コード例 #1
0
    protected override IEnumerable <string> BuildCommandLineArguments(string assemblyFileName, string outputFileName)
    {
        // The file to compile
        yield return(assemblyFileName);

        // Output
        yield return($"-o:{outputFileName}");

        // Don't forget this one.
        yield return("--readytorun");

        // Todo: Allow control of some of these
        yield return("-g");

        yield return("--runtimeopt:RH_UseServerGC=1");

        yield return("--targetarch=x64");

        yield return("--stacktracedata");

        foreach (var reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(_inputPath))
        {
            yield return($"-r:{reference}");
        }

        foreach (var referenceFolder in _referenceFolders)
        {
            foreach (var reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(referenceFolder))
            {
                yield return($"-r:{reference}");
            }
        }
    }
コード例 #2
0
 private static IEnumerable <string> ResolveReferences(IEnumerable <string> folders)
 {
     foreach (string referenceFolder in folders)
     {
         foreach (string reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(referenceFolder))
         {
             yield return(reference);
         }
     }
 }
コード例 #3
0
        public static BuildFolder FromDirectory(string inputDirectory, IEnumerable <CompilerRunner> compilerRunners, string outputRoot, BuildOptions options)
        {
            List <string> compilationInputFiles = new List <string>();
            List <string> passThroughFiles      = new List <string>();
            List <string> mainExecutables       = new List <string>();
            List <string> executionScripts      = new List <string>();

            string scriptExtension = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".cmd" : ".sh");

            // Copy unmanaged files (runtime, native dependencies, resources, etc)
            foreach (string file in Directory.EnumerateFiles(inputDirectory, options.InputFileSearchString ?? "*"))
            {
                bool isManagedAssembly = ComputeManagedAssemblies.IsManaged(file);
                if (isManagedAssembly)
                {
                    compilationInputFiles.Add(file);
                }
                if ((!isManagedAssembly || options.Composite) &&
                    (Path.GetExtension(file) != ".pdb") && (Path.GetExtension(file) != ".ilk")) // exclude .pdb and .ilk files that are large and not needed in the target folder
                {
                    passThroughFiles.Add(file);
                }
                string ext = Path.GetExtension(file);
                if (ext.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    mainExecutables.Add(file);
                }
                else if (ext.Equals(scriptExtension, StringComparison.OrdinalIgnoreCase))
                {
                    executionScripts.Add(file);
                }
            }

            if (compilationInputFiles.Count == 0)
            {
                return(null);
            }

            foreach (CompilerRunner runner in compilerRunners)
            {
                string runnerOutputPath = runner.GetOutputPath(outputRoot);
                if (!options.Exe)
                {
                    runnerOutputPath.RecreateDirectory();
                    foreach (string file in passThroughFiles)
                    {
                        File.Copy(file, Path.Combine(runnerOutputPath, Path.GetFileName(file)));
                    }
                }
            }

            return(new BuildFolder(compilationInputFiles, mainExecutables, executionScripts, compilerRunners, inputDirectory, outputRoot, options));
        }
コード例 #4
0
ファイル: CpaotRunner.cs プロジェクト: clamp03/runtime
        private List <string> ResolveReferences()
        {
            List <string> references = new List <string>();

            foreach (var referenceFolder in _referenceFolders)
            {
                foreach (var reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(referenceFolder))
                {
                    references.Add($"-r:{reference}");
                }
            }
            return(references);
        }
コード例 #5
0
ファイル: CpaotRunner.cs プロジェクト: stephen1426/runtime
        private List <string> ResolveReferences()
        {
            char          referenceOption = (_options.Composite ? 'u' : 'r');
            List <string> references      = new List <string>();

            foreach (var referenceFolder in _referenceFolders)
            {
                foreach (var reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(referenceFolder))
                {
                    references.Add($"-{referenceOption}:{reference}");
                }
            }
            return(references);
        }
コード例 #6
0
 private IEnumerable <string> ResolveReferences(IEnumerable <string> folders, char referenceOption)
 {
     foreach (string referenceFolder in folders)
     {
         foreach (string reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(referenceFolder))
         {
             string simpleName = Path.GetFileNameWithoutExtension(reference);
             if (!FrameworkExclusion.Exclude(simpleName, Index, out string reason))
             {
                 yield return($"-{referenceOption}:{reference}");
             }
         }
     }
 }
コード例 #7
0
 private static IEnumerable <string> ResolveReferences(IEnumerable <string> folders)
 {
     foreach (string referenceFolder in folders)
     {
         foreach (string reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(referenceFolder))
         {
             if (reference.EndsWith(".ni.dll"))
             {
                 continue;
             }
             yield return(reference);
         }
     }
 }
コード例 #8
0
        public static BuildFolder FromDirectory(string inputDirectory, IEnumerable <CompilerRunner> compilerRunners, string outputRoot, BuildOptions options)
        {
            List <string> compilationInputFiles = new List <string>();
            List <string> passThroughFiles      = new List <string>();
            List <string> mainExecutables       = new List <string>();
            List <string> executionScripts      = new List <string>();

            // Copy unmanaged files (runtime, native dependencies, resources, etc)
            foreach (string file in Directory.EnumerateFiles(inputDirectory))
            {
                bool isManagedAssembly = ComputeManagedAssemblies.IsManaged(file);
                if (isManagedAssembly)
                {
                    compilationInputFiles.Add(file);
                }
                else
                {
                    passThroughFiles.Add(file);
                }
                string ext = Path.GetExtension(file);
                if (ext.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    mainExecutables.Add(file);
                }
                else if (ext.Equals(".cmd", StringComparison.OrdinalIgnoreCase))
                {
                    executionScripts.Add(file);
                }
            }

            if (compilationInputFiles.Count == 0)
            {
                return(null);
            }

            foreach (CompilerRunner runner in compilerRunners)
            {
                string runnerOutputPath = runner.GetOutputPath(outputRoot);
                runnerOutputPath.RecreateDirectory();
                foreach (string file in passThroughFiles)
                {
                    File.Copy(file, Path.Combine(runnerOutputPath, Path.GetFileName(file)));
                }
            }

            return(new BuildFolder(compilationInputFiles, mainExecutables, executionScripts, compilerRunners, outputRoot, options));
        }
コード例 #9
0
ファイル: CpaotRunner.cs プロジェクト: stimms/runtime
        protected override IEnumerable <string> BuildCommandLineArguments(string assemblyFileName, string outputFileName)
        {
            // The file to compile
            yield return(assemblyFileName);

            // Output
            yield return($"-o:{outputFileName}");

            // Todo: Allow control of some of these
            yield return("--targetarch=x64");

            if (_options.GenerateMapFile)
            {
                yield return("--map");
            }

            if (_options.Release)
            {
                yield return("-O");
            }

            if (_options.LargeBubble)
            {
                yield return("--inputbubble");
            }

            if (_options.Crossgen2Parallelism != 0)
            {
                yield return($"--parallelism={_options.Crossgen2Parallelism}");
            }

            foreach (var reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(Path.GetDirectoryName(assemblyFileName)))
            {
                yield return($"-r:{reference}");
            }

            if (_resolvedReferences == null)
            {
                _resolvedReferences = ResolveReferences();
            }

            foreach (string asmRef in _resolvedReferences)
            {
                yield return(asmRef);
            }
        }
コード例 #10
0
ファイル: CpaotRunner.cs プロジェクト: woxihuanjia/corert
        protected override IEnumerable <string> BuildCommandLineArguments(string assemblyFileName, string outputFileName)
        {
            // The file to compile
            yield return(assemblyFileName);

            // Output
            yield return($"-o:{outputFileName}");

            // Don't forget this one.
            yield return("--readytorun");

            // Todo: Allow control of some of these
            yield return("-g");

            yield return("--runtimeopt:RH_UseServerGC=1");

            yield return("--targetarch=x64");

            yield return("--stacktracedata");

            if (_options.Release)
            {
                yield return("-O");
            }

            if (_options.LargeBubble)
            {
                yield return("--inputbubble");
            }

            foreach (var reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(Path.GetDirectoryName(assemblyFileName)))
            {
                yield return($"-r:{reference}");
            }

            if (_resolvedReferences == null)
            {
                _resolvedReferences = ResolveReferences();
            }

            foreach (string asmRef in _resolvedReferences)
            {
                yield return(asmRef);
            }
        }
コード例 #11
0
        public static int CompileDirectory(DirectoryInfo toolDirectory, DirectoryInfo inputDirectory, DirectoryInfo outputDirectory, bool crossgen, bool cpaot, DirectoryInfo[] referencePath)
        {
            if (toolDirectory == null)
            {
                Console.WriteLine("--tool-directory is a required argument.");
                return(1);
            }

            if (inputDirectory == null)
            {
                Console.WriteLine("--input-directory is a required argument.");
                return(1);
            }

            if (outputDirectory == null)
            {
                Console.WriteLine("--output-directory is a required argument.");
                return(1);
            }

            CompilerRunner runner;

            if (cpaot)
            {
                runner = new CpaotRunner(toolDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePath?.Select(x => x.ToString())?.ToList());
            }
            else
            {
                runner = new CrossgenRunner(toolDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePath?.Select(x => x.ToString())?.ToList());
            }

            bool success = true;

            foreach (var assemblyToOptimize in ComputeManagedAssemblies.GetManagedAssembliesInFolder(inputDirectory.ToString()))
            {
                // Compile all assemblies in the input folder
                if (!runner.CompileAssembly(assemblyToOptimize))
                {
                    success = false;
                }
            }

            return(success ? 0 : 1);
        }
コード例 #12
0
        public static int CompileDirectory(
            DirectoryInfo inputDirectory,
            DirectoryInfo outputDirectory,
            DirectoryInfo crossgenDirectory,
            DirectoryInfo cpaotDirectory,
            DirectoryInfo[] referencePath)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            if (inputDirectory == null)
            {
                Console.WriteLine("--input-directory is a required argument.");
                return(1);
            }

            if (outputDirectory == null)
            {
                outputDirectory = inputDirectory;
            }

            if (outputDirectory.IsParentOf(inputDirectory))
            {
                Console.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);
            }

            List <string> referencePaths = referencePath?.Select(x => x.ToString())?.ToList();
            string        coreRunPath    = null;

            foreach (string path in referencePaths)
            {
                string candidatePath = Path.Combine(path, "CoreRun.exe");
                if (File.Exists(candidatePath))
                {
                    coreRunPath = candidatePath;
                    break;
                }
            }

            if (coreRunPath == null)
            {
                Console.Error.WriteLine("CoreRun.exe not found in reference folders, execution won't run");
            }

            List <CompilerRunner> runners = new List <CompilerRunner>();

            if (cpaotDirectory != null)
            {
                runners.Add(new CpaotRunner(cpaotDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePaths));
            }
            if (crossgenDirectory != null)
            {
                runners.Add(new CrossgenRunner(crossgenDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePaths));
            }

            List <string> compilationInputFiles = new List <string>();
            List <string> passThroughFiles      = new List <string>();
            string        mainExecutable        = null;

            // Copy unmanaged files (runtime, native dependencies, resources, etc)
            foreach (string file in Directory.EnumerateFiles(inputDirectory.FullName))
            {
                bool isManagedAssembly = ComputeManagedAssemblies.IsManaged(file);
                if (isManagedAssembly)
                {
                    compilationInputFiles.Add(file);
                }
                else
                {
                    passThroughFiles.Add(file);
                }
                if (Path.GetExtension(file).Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    mainExecutable = file;
                }
            }

            foreach (CompilerRunner runner in runners)
            {
                string runnerOutputPath = runner.GetOutputPath();
                runnerOutputPath.RecreateDirectory();
                foreach (string file in passThroughFiles)
                {
                    File.Copy(file, Path.Combine(runnerOutputPath, Path.GetFileName(file)));
                }
            }

            List <ProcessInfo> compilationsToRun = new List <ProcessInfo>();

            Application application = new Application(compilationInputFiles, mainExecutable, runners, coreRunPath);

            foreach (ProcessInfo[] compilation in application.Compilations)
            {
                foreach (CompilerRunner runner in runners)
                {
                    compilationsToRun.Add(compilation[(int)runner.Index]);
                }
            }

            compilationsToRun.Sort((a, b) => b.CompilationCostHeuristic.CompareTo(a.CompilationCostHeuristic));

            ParallelRunner.Run(compilationsToRun);

            bool success = true;
            List <KeyValuePair <string, string> > failedCompilationsPerBuilder = new List <KeyValuePair <string, string> >();
            int successfulCompileCount = 0;

            foreach (ProcessInfo[] compilation in application.Compilations)
            {
                string file           = null;
                string failedBuilders = null;
                foreach (CompilerRunner runner in runners)
                {
                    ProcessInfo runnerProcess = compilation[(int)runner.Index];
                    if (!runnerProcess.Succeeded)
                    {
                        File.Copy(runnerProcess.InputFileName, runnerProcess.OutputFileName);
                        if (file == null)
                        {
                            file           = runnerProcess.InputFileName;
                            failedBuilders = runner.CompilerName;
                        }
                        else
                        {
                            failedBuilders += "; " + runner.CompilerName;
                        }
                    }
                }
                if (file != null)
                {
                    failedCompilationsPerBuilder.Add(new KeyValuePair <string, string>(file, failedBuilders));
                    success = false;
                }
                else
                {
                    successfulCompileCount++;
                }
            }

            Console.WriteLine($"Compiled {successfulCompileCount} / {successfulCompileCount + failedCompilationsPerBuilder.Count} assemblies in {stopwatch.ElapsedMilliseconds} msecs.");

            if (failedCompilationsPerBuilder.Count > 0)
            {
                Console.WriteLine($"Failed to compile {failedCompilationsPerBuilder.Count} assemblies:");
                foreach (KeyValuePair <string, string> assemblyBuilders in failedCompilationsPerBuilder)
                {
                    string assemblySpec = assemblyBuilders.Key;
                    if (runners.Count > 1)
                    {
                        assemblySpec += " (" + assemblyBuilders.Value + ")";
                    }
                    Console.WriteLine(assemblySpec);
                }
            }

            if (coreRunPath != null)
            {
                List <ProcessInfo> executionsToRun = new List <ProcessInfo>();
                foreach (CompilerRunner runner in runners)
                {
                    bool compilationsSucceeded = application.Compilations.All(comp => comp[(int)runner.Index].Succeeded);
                    if (compilationsSucceeded)
                    {
                        ProcessInfo executionProcess = application.Execution[(int)runner.Index];
                        if (executionProcess != null)
                        {
                            executionsToRun.Add(executionProcess);
                        }
                    }
                }

                ParallelRunner.Run(executionsToRun);
            }

            return(success ? 0 : 1);
        }
コード例 #13
0
ファイル: CpaotRunner.cs プロジェクト: stephen1426/runtime
        protected override IEnumerable <string> BuildCommandLineArguments(IEnumerable <string> assemblyFileNames, string outputFileName)
        {
            // The file to compile
            foreach (string inputAssembly in assemblyFileNames)
            {
                yield return(inputAssembly);
            }

            // Output
            yield return($"-o:{outputFileName}");

            // Todo: Allow control of some of these
            yield return("--targetarch=x64");

            if (_options.Map)
            {
                yield return("--map");
            }

            if (_options.Release)
            {
                yield return("-O");
            }

            if (_options.LargeBubble || _options.Composite)
            {
                yield return("--inputbubble");
            }

            if (_options.Composite)
            {
                yield return("--composite");
            }

            if (_options.Crossgen2Parallelism != 0)
            {
                yield return($"--parallelism={_options.Crossgen2Parallelism}");
            }

            char             referenceOption = (_options.Composite ? 'u' : 'r');
            HashSet <string> uniqueFolders   = new HashSet <string>();

            foreach (string assemblyFileName in assemblyFileNames)
            {
                uniqueFolders.Add(Path.GetDirectoryName(assemblyFileName));
            }
            foreach (string folder in uniqueFolders)
            {
                foreach (var reference in ComputeManagedAssemblies.GetManagedAssembliesInFolder(folder))
                {
                    yield return($"-{referenceOption}:{reference}");
                }
            }

            if (_resolvedReferences == null)
            {
                _resolvedReferences = ResolveReferences();
            }

            foreach (string asmRef in _resolvedReferences)
            {
                yield return(asmRef);
            }
        }
コード例 #14
0
        public bool CompileFramework()
        {
            if (!_options.Framework)
            {
                return(true);
            }

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            string coreRoot = _options.CoreRootDirectory.FullName;

            string[] frameworkFolderFiles = Directory.GetFiles(coreRoot);

            IEnumerable <CompilerRunner> frameworkRunners = _options.CompilerRunners(isFramework: true);

            // Pre-populate the output folders with the input files so that we have backdrops
            // for failing compilations.
            foreach (CompilerRunner runner in frameworkRunners)
            {
                string outputPath = runner.GetOutputPath(coreRoot);
                outputPath.RecreateDirectory();
            }

            List <ProcessInfo> compilationsToRun = new List <ProcessInfo>();
            List <KeyValuePair <string, ProcessInfo[]> > compilationsPerRunner = new List <KeyValuePair <string, ProcessInfo[]> >();

            foreach (string frameworkDll in ComputeManagedAssemblies.GetManagedAssembliesInFolder(_options.CoreRootDirectory.FullName))
            {
                ProcessInfo[] processes = new ProcessInfo[(int)CompilerIndex.Count];
                compilationsPerRunner.Add(new KeyValuePair <string, ProcessInfo[]>(frameworkDll, processes));
                foreach (CompilerRunner runner in frameworkRunners)
                {
                    ProcessInfo compilationProcess = new ProcessInfo(new CompilationProcessConstructor(runner, _options.CoreRootDirectory.FullName, frameworkDll));
                    compilationsToRun.Add(compilationProcess);
                    processes[(int)runner.Index] = compilationProcess;
                }
            }

            ParallelRunner.Run(compilationsToRun, _options.DegreeOfParallelism);

            HashSet <string> skipCopying = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            int[] failedCompilationsPerBuilder = new int[(int)CompilerIndex.Count];
            int   successfulCompileCount       = 0;
            int   failedCompileCount           = 0;

            foreach (KeyValuePair <string, ProcessInfo[]> kvp in compilationsPerRunner)
            {
                bool anyCompilationsFailed = false;
                foreach (CompilerRunner runner in frameworkRunners)
                {
                    ProcessInfo compilationProcess = kvp.Value[(int)runner.Index];
                    if (compilationProcess.Succeeded)
                    {
                        skipCopying.Add(compilationProcess.Parameters.InputFileName);
                    }
                    else
                    {
                        anyCompilationsFailed = true;
                        failedCompilationsPerBuilder[(int)runner.Index]++;
                        _frameworkCompilationFailureBuckets.AddCompilation(compilationProcess);
                    }
                }
                if (anyCompilationsFailed)
                {
                    failedCompileCount++;
                }
                else
                {
                    successfulCompileCount++;
                }
            }

            foreach (CompilerRunner runner in frameworkRunners)
            {
                string outputPath = runner.GetOutputPath(coreRoot);
                foreach (string file in frameworkFolderFiles)
                {
                    if (!skipCopying.Contains(file))
                    {
                        string targetFile = Path.Combine(outputPath, Path.GetFileName(file));
                        File.Copy(file, targetFile, overwrite: true);
                    }
                }
            }

            _frameworkCompilationMilliseconds = stopwatch.ElapsedMilliseconds;

            return(failedCompileCount == 0);
        }
コード例 #15
0
ファイル: BuildFolder.cs プロジェクト: sensen12138/runtime
        public static BuildFolder FromDirectory(string inputDirectory, IEnumerable <CompilerRunner> compilerRunners, string outputRoot, BuildOptions options)
        {
            List <string>    compilationInputFiles = new List <string>();
            HashSet <string> passThroughFiles      = new HashSet <string>();
            List <string>    mainExecutables       = new List <string>();
            List <string>    executionScripts      = new List <string>();

            string scriptExtension = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".cmd" : ".sh");

            // Copy unmanaged files (runtime, native dependencies, resources, etc)
            foreach (string file in Directory.EnumerateFiles(inputDirectory, options.InputFileSearchString ?? "*"))
            {
                bool isManagedAssembly = ComputeManagedAssemblies.IsManaged(file);
                if (isManagedAssembly)
                {
                    compilationInputFiles.Add(file);
                }
                if ((!isManagedAssembly || options.Composite) &&
                    (Path.GetExtension(file) != ".pdb") && (Path.GetExtension(file) != ".ilk")) // exclude .pdb and .ilk files that are large and not needed in the target folder
                {
                    passThroughFiles.Add(file);
                }
                string ext = Path.GetExtension(file);
                if (ext.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    mainExecutables.Add(file);
                }
                else if (ext.Equals(scriptExtension, StringComparison.OrdinalIgnoreCase))
                {
                    executionScripts.Add(file);
                }
            }

            if (compilationInputFiles.Count == 0)
            {
                return(null);
            }

            if (options.Composite && !(options.Framework || options.UseFramework))
            {
                // In composite mode we copy the native runtime to the app folder and pretend that is CORE_ROOT,
                // otherwise CoreRun picks up the original MSIL versions of framework assemblies from CORE_ROOT
                // instead of the rewritten ones next to the app.
                foreach (string exe in s_runtimeExecutables)
                {
                    passThroughFiles.Add(Path.Combine(options.CoreRootDirectory.FullName, exe.AppendOSExeSuffix()));
                }
                string libraryPrefix = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "lib");
                foreach (string lib in s_runtimeLibraries)
                {
                    passThroughFiles.Add(Path.Combine(options.CoreRootDirectory.FullName, (libraryPrefix + lib).AppendOSDllSuffix()));
                }
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    foreach (string lib in s_runtimeWindowsOnlyLibraries)
                    {
                        passThroughFiles.Add(Path.Combine(options.CoreRootDirectory.FullName, lib.AppendOSDllSuffix()));
                    }
                }
                else
                {
                    // Several native lib*.so / dylib are needed by the runtime
                    foreach (string nativeLib in Directory.EnumerateFiles(options.CoreRootDirectory.FullName, "lib*".AppendOSDllSuffix()))
                    {
                        passThroughFiles.Add(nativeLib);
                    }
                }
            }

            foreach (CompilerRunner runner in compilerRunners)
            {
                string runnerOutputPath = runner.GetOutputPath(outputRoot);
                if (!options.Exe)
                {
                    runnerOutputPath.RecreateDirectory();
                    foreach (string file in passThroughFiles)
                    {
                        File.Copy(file, Path.Combine(runnerOutputPath, Path.GetFileName(file)));
                    }
                }
            }

            return(new BuildFolder(compilationInputFiles, mainExecutables, executionScripts, compilerRunners, inputDirectory, outputRoot, options));
        }
コード例 #16
0
        public static int CompileDirectory(DirectoryInfo toolDirectory, DirectoryInfo inputDirectory, DirectoryInfo outputDirectory, bool crossgen, bool cpaot, DirectoryInfo[] referencePath)
        {
            if (toolDirectory == null)
            {
                Console.WriteLine("--tool-directory is a required argument.");
                return(1);
            }

            if (inputDirectory == null)
            {
                Console.WriteLine("--input-directory is a required argument.");
                return(1);
            }

            if (outputDirectory == null)
            {
                Console.WriteLine("--output-directory is a required argument.");
                return(1);
            }

            if (OutputPathIsParentOfInputPath(inputDirectory, outputDirectory))
            {
                Console.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);
            }

            CompilerRunner runner;

            if (cpaot)
            {
                runner = new CpaotRunner(toolDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePath?.Select(x => x.ToString())?.ToList());
            }
            else
            {
                runner = new CrossgenRunner(toolDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePath?.Select(x => x.ToString())?.ToList());
            }

            if (outputDirectory.Exists)
            {
                try
                {
                    outputDirectory.Delete(recursive: true);
                }
                catch (Exception ex) when(
                    ex is UnauthorizedAccessException ||
                    ex is DirectoryNotFoundException ||
                    ex is IOException
                    )
                {
                    Console.WriteLine($"Error: Could not delete output folder {outputDirectory.FullName}. {ex.Message}");
                    return(1);
                }
            }

            outputDirectory.Create();

            bool success = true;

            // Copy unmanaged files (runtime, native dependencies, resources, etc)
            foreach (string file in Directory.EnumerateFiles(inputDirectory.FullName))
            {
                if (ComputeManagedAssemblies.IsManaged(file))
                {
                    // Compile managed code
                    if (!runner.CompileAssembly(file))
                    {
                        success = false;

                        // On compile failure, pass through the input IL assembly so the output is still usable
                        File.Copy(file, Path.Combine(outputDirectory.FullName, Path.GetFileName(file)));
                    }
                }
                else
                {
                    // Copy through all other files
                    File.Copy(file, Path.Combine(outputDirectory.FullName, Path.GetFileName(file)));
                }
            }

            return(success ? 0 : 1);
        }
コード例 #17
0
        public static int CompileDirectory(DirectoryInfo toolDirectory, DirectoryInfo inputDirectory, DirectoryInfo outputDirectory, bool crossgen, bool cpaot, DirectoryInfo[] referencePath)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            if (toolDirectory == null)
            {
                Console.WriteLine("--tool-directory is a required argument.");
                return(1);
            }

            if (inputDirectory == null)
            {
                Console.WriteLine("--input-directory is a required argument.");
                return(1);
            }

            if (outputDirectory == null)
            {
                outputDirectory = inputDirectory;
            }

            if (OutputPathIsParentOfInputPath(inputDirectory, outputDirectory))
            {
                Console.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);
            }

            CompilerRunner runner;

            if (cpaot)
            {
                runner = new CpaotRunner(toolDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePath?.Select(x => x.ToString())?.ToList());
            }
            else
            {
                runner = new CrossgenRunner(toolDirectory.ToString(), inputDirectory.ToString(), outputDirectory.ToString(), referencePath?.Select(x => x.ToString())?.ToList());
            }

            string runnerOutputPath = runner.GetOutputPath();

            if (Directory.Exists(runnerOutputPath))
            {
                try
                {
                    Directory.Delete(runnerOutputPath, recursive: true);
                }
                catch (Exception ex) when(
                    ex is UnauthorizedAccessException ||
                    ex is DirectoryNotFoundException ||
                    ex is IOException
                    )
                {
                    Console.WriteLine($"Error: Could not delete output folder {runnerOutputPath}. {ex.Message}");
                    return(1);
                }
            }

            Directory.CreateDirectory(runnerOutputPath);

            List <ProcessInfo> compilationsToRun = new List <ProcessInfo>();

            // Copy unmanaged files (runtime, native dependencies, resources, etc)
            foreach (string file in Directory.EnumerateFiles(inputDirectory.FullName))
            {
                if (ComputeManagedAssemblies.IsManaged(file))
                {
                    ProcessInfo compilationToRun = runner.CompilationProcess(file);
                    compilationToRun.InputFileName = file;
                    compilationsToRun.Add(compilationToRun);
                }
                else
                {
                    // Copy through all other files
                    File.Copy(file, Path.Combine(runnerOutputPath, Path.GetFileName(file)));
                }
            }

            ParallelRunner.Run(compilationsToRun);

            bool          success = true;
            List <string> failedCompilationAssemblies = new List <string>();
            int           successfulCompileCount      = 0;

            foreach (ProcessInfo processInfo in compilationsToRun)
            {
                if (processInfo.Succeeded)
                {
                    successfulCompileCount++;
                }
                else
                {
                    File.Copy(processInfo.InputFileName, Path.Combine(runnerOutputPath, Path.GetFileName(processInfo.InputFileName)));
                    failedCompilationAssemblies.Add(processInfo.InputFileName);
                }
            }

            Console.WriteLine($"Compiled {successfulCompileCount}/{successfulCompileCount + failedCompilationAssemblies.Count} assemblies in {stopwatch.ElapsedMilliseconds} msecs.");

            if (failedCompilationAssemblies.Count > 0)
            {
                Console.WriteLine($"Failed to compile {failedCompilationAssemblies.Count} assemblies:");
                foreach (var assembly in failedCompilationAssemblies)
                {
                    Console.WriteLine(assembly);
                }
            }

            return(success ? 0 : 1);
        }
コード例 #18
0
        public CompileSerpCommand(BuildOptions options)
        {
            // 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;
            options.Release     = true;
            options.LargeBubble = true;

            _options = options;

            if (_options.InputDirectory == null)
            {
                throw new ArgumentException("Specify --response-file or --input-directory containing multiple response files.");
            }

            if (_options.CoreRootDirectory == null)
            {
                throw new ArgumentException("--core-root-directory (--cr) is a required argument.");
            }

            if (_options.AspNetPath == null || !File.Exists(Path.Combine(_options.AspNetPath.FullName, "Microsoft.AspNetCore.dll")))
            {
                throw new ArgumentException($"Error: Asp.NET Core path must contain Microsoft.AspNetCore.dll");
            }

            SerpDir = _options.InputDirectory.FullName;
            BinDir  = Path.Combine(SerpDir, "bin");

            if (!File.Exists(Path.Combine(SerpDir, "runserp.cmd")))
            {
                throw new ArgumentException($"Error: InputDirectory must point at a SERP build. Could not find {Path.Combine(SerpDir, "runserp.cmd")}");
            }

            string allowListFilePath = Path.Combine(SerpDir, "App_Data", "AllowedDllList.txt");

            if (!File.Exists(allowListFilePath))
            {
                throw new ArgumentException($"File {allowListFilePath} was not found");
            }

            // Add all assemblies from the various SERP packages (filtered by ShouldInclude)
            _packageCompileAssemblies = Directory.GetFiles(Path.Combine(SerpDir, "App_Data\\Answers\\Services\\Packages"), "*.dll", SearchOption.AllDirectories)
                                        .Where((string x) => ShouldInclude(x))
                                        .ToList();
            _packageReferenceAssemblies = new List <string>();
            {
                HashSet <string> packageReferenceAssemblyDirectories = new HashSet <string>();
                foreach (var binFile in _packageCompileAssemblies)
                {
                    var directory = Path.GetDirectoryName(binFile);
                    if (!packageReferenceAssemblyDirectories.Contains(directory))
                    {
                        packageReferenceAssemblyDirectories.Add(directory);
                    }
                }

                foreach (string binFile in ResolveReferences(packageReferenceAssemblyDirectories))
                {
                    _packageReferenceAssemblies.Add(binFile);
                }
            }

            _coreCompileAssemblies   = new List <string>();
            _coreReferenceAssemblies = new List <string>();
            {
                // Add an allow-list of assemblies from bin. This unified list includes binaries from /bin and /App_data so filter just the /bin assemblies
                foreach (string item in new HashSet <string>(File.ReadAllLines(allowListFilePath)))
                {
                    string binAssembly = Path.Combine(BinDir, item);
                    if (File.Exists(binAssembly) &&
                        !FrameworkExclusion.Exclude(Path.GetFileNameWithoutExtension(binAssembly), CompilerIndex.CPAOT, out string reason))
                    {
                        _coreCompileAssemblies.Add(binAssembly);
                    }
                }

                HashSet <string> coreReferenceAssemblyDirectories = new HashSet <string>();
                foreach (var binFile in _coreCompileAssemblies)
                {
                    var directory = Path.GetDirectoryName(binFile);
                    if (!coreReferenceAssemblyDirectories.Contains(directory))
                    {
                        coreReferenceAssemblyDirectories.Add(directory);
                    }
                }

                foreach (string binFile in ResolveReferences(coreReferenceAssemblyDirectories))
                {
                    _coreReferenceAssemblies.Add(binFile);
                }
            }

            _frameworkCompileAssemblies   = new List <string>();
            _frameworkReferenceAssemblies = new List <string>();
            {
                foreach (string frameworkDll in ComputeManagedAssemblies.GetManagedAssembliesInFolder(options.CoreRootDirectory.FullName, "System.*.dll"))
                {
                    string simpleName = Path.GetFileNameWithoutExtension(frameworkDll);
                    if (!FrameworkExclusion.Exclude(simpleName, CompilerIndex.CPAOT, out string reason))
                    {
                        _frameworkCompileAssemblies.Add(frameworkDll);
                    }
                }
                foreach (string frameworkDll in ComputeManagedAssemblies.GetManagedAssembliesInFolder(options.CoreRootDirectory.FullName, "Microsoft.*.dll"))
                {
                    string simpleName = Path.GetFileNameWithoutExtension(frameworkDll);
                    if (!FrameworkExclusion.Exclude(simpleName, CompilerIndex.CPAOT, out string reason))
                    {
                        _frameworkCompileAssemblies.Add(frameworkDll);
                    }
                }
                _frameworkCompileAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "mscorlib.dll"));
                _frameworkCompileAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "netstandard.dll"));
                _frameworkReferenceAssemblies.AddRange(ComputeManagedAssemblies.GetManagedAssembliesInFolder(options.CoreRootDirectory.FullName, "System.*.dll"));
                _frameworkReferenceAssemblies.AddRange(ComputeManagedAssemblies.GetManagedAssembliesInFolder(options.CoreRootDirectory.FullName, "Microsoft.*.dll"));
                _frameworkReferenceAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "mscorlib.dll"));
                _frameworkReferenceAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "netstandard.dll"));
            }

            _aspCompileAssemblies   = new List <string>();
            _aspReferenceAssemblies = new List <string>();
            {
                _aspCompileAssemblies.AddRange(ComputeManagedAssemblies.GetManagedAssembliesInFolder(options.AspNetPath.FullName, "Microsoft.AspNetCore.*.dll"));
                _aspCompileAssemblies.AddRange(ComputeManagedAssemblies.GetManagedAssembliesInFolder(options.AspNetPath.FullName, "Microsoft.Extensions.*.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "Microsoft.JSInterop.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "Microsoft.Net.Http.Headers.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "Microsoft.Win32.SystemEvents.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "System.Diagnostics.EventLog.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "System.Drawing.Common.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "System.IO.Pipelines.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "System.Security.Cryptography.Pkcs.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "System.Security.Cryptography.Xml.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "System.Security.Permissions.dll"));
                _aspCompileAssemblies.Add(Path.Combine(options.AspNetPath.FullName, "System.Windows.Extensions.dll"));

                _aspReferenceAssemblies = new List <string>(_aspCompileAssemblies);
            }
        }
コード例 #19
0
        public static int CompileSerpAssemblies(BuildOptions options)
        {
            if (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);
            }


            // 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;

            string serpDir = options.InputDirectory.FullName;

            if (!File.Exists(Path.Combine(serpDir, "runserp.cmd")))
            {
                Console.Error.WriteLine($"Error: InputDirectory must point at a SERP build. Could not find {Path.Combine(serpDir, "runserp.cmd")}");
                return(1);
            }

            string whiteListFilePath = Path.Combine(serpDir, "WhitelistDlls.txt");

            if (!File.Exists(whiteListFilePath))
            {
                Console.Error.WriteLine($"File {whiteListFilePath} was not found");
                return(1);
            }

            if (!File.Exists(Path.Combine(options.AspNetPath.FullName, "Microsoft.AspNetCore.dll")))
            {
                Console.Error.WriteLine($"Error: Asp.NET Core path must contain Microsoft.AspNetCore.dll");
                return(1);
            }

            string binDir = Path.Combine(serpDir, "bin");

            // Remove existing native images
            foreach (var file in Directory.GetFiles(Path.Combine(serpDir, "App_Data\\Answers\\Services\\Packages"), "*.dll", SearchOption.AllDirectories))
            {
                if (file.EndsWith(".ni.dll") || file.EndsWith(".ni.exe"))
                {
                    File.Delete(file);
                }
            }

            foreach (var file in Directory.GetFiles(binDir, "*.dll", SearchOption.AllDirectories))
            {
                if (file.EndsWith(".ni.dll") || file.EndsWith(".ni.exe"))
                {
                    File.Delete(file);
                }
            }

            // Add all assemblies from the various SERP packages (filtered by ShouldInclude)
            List <string> binFiles = Directory.GetFiles(Path.Combine(serpDir, "App_Data\\Answers\\Services\\Packages"), "*.dll", SearchOption.AllDirectories)
                                     .Where((string x) => ShouldInclude(x))
                                     .ToList();

            // Add a whitelist of assemblies from bin
            foreach (string item in new HashSet <string>(File.ReadAllLines(whiteListFilePath)))
            {
                binFiles.Add(Path.Combine(binDir, item));
            }

            HashSet <string> referenceAssemblyDirectories = new HashSet <string>();

            foreach (var binFile in binFiles)
            {
                var directory = Path.GetDirectoryName(binFile);
                if (!referenceAssemblyDirectories.Contains(directory))
                {
                    referenceAssemblyDirectories.Add(directory);
                }
            }

            // TestILC needs a list of all directories containing assemblies that are referenced from crossgen
            List <string>    referenceAssemblies = new List <string>();
            HashSet <string> simpleNames         = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            // Reference all managed assemblies in /bin and /App_Data/answers/services/packages
            foreach (string binFile in ResolveReferences(referenceAssemblyDirectories))
            {
                simpleNames.Add(Path.GetFileNameWithoutExtension(binFile));
                referenceAssemblies.Add(binFile);
            }

            referenceAssemblies.AddRange(ComputeManagedAssemblies.GetManagedAssembliesInFolderNoSimpleNameDuplicates(simpleNames, options.AspNetPath.FullName, "*.dll"));

            // Add CoreRoot last because it contains various non-framework assemblies that are duplicated in SERP and we want SERP's to be used
            referenceAssemblies.AddRange(ComputeManagedAssemblies.GetManagedAssembliesInFolderNoSimpleNameDuplicates(simpleNames, options.CoreRootDirectory.FullName, "System.*.dll"));
            referenceAssemblies.AddRange(ComputeManagedAssemblies.GetManagedAssembliesInFolderNoSimpleNameDuplicates(simpleNames, options.CoreRootDirectory.FullName, "Microsoft.*.dll"));
            referenceAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "mscorlib.dll"));
            referenceAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "netstandard.dll"));

            //
            // binFiles is now all the assemblies that we want to compile (either individually or as composite)
            // referenceAssemblies is all managed assemblies that are referenceable
            //

            // Remove all bin files except serp.dll so they're just referenced (eventually we'll be able to compile all these in a single composite)
            foreach (string item in new HashSet <string>(File.ReadAllLines(whiteListFilePath)))
            {
                if (item == "Serp.dll")
                {
                    continue;
                }

                binFiles.Remove(Path.Combine(binDir, item));
            }

            List <ProcessInfo> fileCompilations = new List <ProcessInfo>();

            if (options.Composite)
            {
                string serpDll            = Path.Combine(binDir, "Serp.dll");
                var    runner             = new CpaotRunner(options, referenceAssemblies);
                var    compilationProcess = new ProcessInfo(new CompilationProcessConstructor(runner, Path.ChangeExtension(serpDll, ".ni.dll"), binFiles));
                fileCompilations.Add(compilationProcess);
            }
            else
            {
                var runner = new CpaotRunner(options, referenceAssemblies);
                foreach (string assemblyName in binFiles)
                {
                    var compilationProcess = new ProcessInfo(new CompilationProcessConstructor(runner, Path.ChangeExtension(assemblyName, ".ni.dll"), new string[] { assemblyName }));
                    fileCompilations.Add(compilationProcess);
                }
            }

            ParallelRunner.Run(fileCompilations, options.DegreeOfParallelism);

            bool success             = true;
            int  compilationFailures = 0;

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

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

            Console.WriteLine("Serp Compilation Results");
            Console.WriteLine($"Total compilations: {fileCompilations.Count}");
            Console.WriteLine($"Compilation failures: {compilationFailures}");

            return(success ? 0 : 1);
        }