Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
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));
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }