Exemplo n.º 1
0
        private static void HandleTestExecutionStartMessage(string testRunner, Message message, ReportingChannel channel, ProjectContext projectContext)
        {
            TestHostTracing.Source.TraceInformation("Starting Execution");

            var commandArgs = new List <string> {
                projectContext.GetOutputPathCalculator().GetAssemblyPath(Constants.DefaultConfiguration)
            };

            commandArgs.AddRange(new[]
            {
                "--designtime"
            });

            var tests = message.Payload?.ToObject <RunTestsMessage>().Tests;

            if (tests != null)
            {
                foreach (var test in tests)
                {
                    commandArgs.Add("--test");
                    commandArgs.Add(test);
                }
            }

            ExecuteRunnerCommand(testRunner, channel, commandArgs);

            channel.Send(new Message()
            {
                MessageType = "TestExecution.Response",
            });

            TestHostTracing.Source.TraceInformation("Completed Execution");
        }
Exemplo n.º 2
0
        public static AssemblyLoadContext CreateLoadContext(this ProjectContext context, string configuration = "Debug")
        {
            var exporter   = context.CreateExporter(configuration);
            var assemblies = new Dictionary <AssemblyName, string>(AssemblyNameComparer.OrdinalIgnoreCase);
            var dllImports = new Dictionary <string, string>();

            foreach (var export in exporter.GetAllExports())
            {
                // TODO: Handle resource assemblies
                foreach (var asset in export.RuntimeAssemblies)
                {
                    // REVIEW: Should we use the following?
                    // AssemblyLoadContext.GetAssemblyName(asset.ResolvedPath);
                    var assemblyName = new AssemblyName(asset.Name);
                    assemblies[assemblyName] = asset.ResolvedPath;
                }

                foreach (var asset in export.NativeLibraries)
                {
                    dllImports[asset.Name] = asset.ResolvedPath;
                }
            }

            return(new ProjectLoadContext(
                       assemblies,
                       dllImports,

                       // Add the project's output directory path to ensure project-to-project references get located
                       new[] { context.GetOutputPathCalculator().GetOutputDirectoryPath(configuration) }));
        }
Exemplo n.º 3
0
        private void MakeRunnableIfNecessary()
        {
            var compilationOptions = CompilerUtil.ResolveCompilationOptions(_rootProject, _args.ConfigValue);

            // TODO: Make this opt in via another mechanism
            var makeRunnable = compilationOptions.EmitEntryPoint.GetValueOrDefault() ||
                               _rootProject.IsTestProject();

            if (makeRunnable)
            {
                var outputPathCalculator = _rootProject.GetOutputPathCalculator(_args.OutputValue);
                var rids = new List <string>();
                if (string.IsNullOrEmpty(_args.RuntimeValue))
                {
                    rids.AddRange(PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers());
                }
                else
                {
                    rids.Add(_args.RuntimeValue);
                }

                var runtimeContext = ProjectContext.Create(_rootProject.ProjectDirectory, _rootProject.TargetFramework, rids);
                var executable     = new Executable(runtimeContext, outputPathCalculator);
                executable.MakeCompilationOutputRunnable(_args.ConfigValue);
            }
        }
Exemplo n.º 4
0
        private static int RunConsole(ProjectContext projectContext, CommandLineApplication app, string testRunner)
        {
            var commandArgs = new List <string> {
                projectContext.GetOutputPathCalculator().GetAssemblyPath(Constants.DefaultConfiguration)
            };

            commandArgs.AddRange(app.RemainingArguments);

            return(Command.CreateDotNet($"{GetCommandName(testRunner)}", commandArgs, projectContext.TargetFramework)
                   .ForwardStdErr()
                   .ForwardStdOut()
                   .Execute()
                   .ExitCode);
        }
Exemplo n.º 5
0
        // computes all the inputs and outputs that would be used in the compilation of a project
        // ensures that all paths are files
        // ensures no missing inputs
        public static CompilerIO GetCompileIO(
            ProjectContext project,
            string buildConfiguration,
            string outputPath,
            string intermediaryOutputPath,
            ProjectDependenciesFacade dependencies)
        {
            var compilerIO         = new CompilerIO(new List <string>(), new List <string>());
            var calculator         = project.GetOutputPathCalculator(outputPath);
            var binariesOutputPath = calculator.GetOutputDirectoryPath(buildConfiguration);

            intermediaryOutputPath = calculator.GetIntermediateOutputDirectoryPath(buildConfiguration, intermediaryOutputPath);


            // input: project.json
            compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath);

            // input: lock file; find when dependencies change
            AddLockFile(project, compilerIO);

            // input: source files
            compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project));

            // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile
            // input: dependencies
            AddDependencies(dependencies, compilerIO);

            // output: compiler outputs
            foreach (var path in calculator.GetBuildOutputs(buildConfiguration))
            {
                compilerIO.Outputs.Add(path);
            }

            // input compilation options files
            AddCompilationOptions(project, buildConfiguration, compilerIO);

            // input / output: resources without culture
            AddCultureResources(project, intermediaryOutputPath, compilerIO);

            // input / output: resources with culture
            AddNonCultureResources(project, binariesOutputPath, compilerIO);

            return(compilerIO);
        }
Exemplo n.º 6
0
        public CompileContext(ProjectContext rootProject, BuilderCommandApp args)
        {
            _rootProject = rootProject;

            // Cleaner to clone the args and mutate the clone than have separate CompileContext fields for mutated args
            // and then reasoning which ones to get from args and which ones from fields.
            _args = (BuilderCommandApp)args.ShallowCopy();

            // Set up Output Paths. They are unique per each CompileContext
            var outputPathCalculator = _rootProject.GetOutputPathCalculator(_args.OutputValue);

            _args.OutputValue       = outputPathCalculator.BaseCompilationOutputPath;
            _args.IntermediateValue =
                outputPathCalculator.GetIntermediateOutputDirectoryPath(_args.ConfigValue, _args.IntermediateValue);

            // Set up dependencies
            _dependencies = new ProjectDependenciesFacade(_rootProject, _args.ConfigValue);

            // gather preconditions
            _preconditions = GatherIncrementalPreconditions();
        }
Exemplo n.º 7
0
        private static void HandleTestDiscoveryStartMessage(string testRunner, ReportingChannel channel, ProjectContext projectContext)
        {
            TestHostTracing.Source.TraceInformation("Starting Discovery");

            var commandArgs = new List <string> {
                projectContext.GetOutputPathCalculator().GetAssemblyPath(Constants.DefaultConfiguration)
            };

            commandArgs.AddRange(new[]
            {
                "--list",
                "--designtime"
            });

            ExecuteRunnerCommand(testRunner, channel, commandArgs);

            channel.Send(new Message()
            {
                MessageType = "TestDiscovery.Response",
            });

            TestHostTracing.Source.TraceInformation("Completed Discovery");
        }
Exemplo n.º 8
0
        private static bool CompileNative(
            ProjectContext context,
            CompilerCommandApp args)
        {
            var outputPathCalculator   = context.GetOutputPathCalculator(args.OutputValue);
            var outputPath             = outputPathCalculator.GetOutputDirectoryPath(args.ConfigValue);
            var nativeOutputPath       = Path.Combine(outputPath, "native");
            var intermediateOutputPath =
                outputPathCalculator.GetIntermediateOutputDirectoryPath(args.ConfigValue, args.IntermediateValue);
            var nativeIntermediateOutputPath = Path.Combine(intermediateOutputPath, "native");

            Directory.CreateDirectory(nativeOutputPath);
            Directory.CreateDirectory(nativeIntermediateOutputPath);

            var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, args.ConfigValue);
            var managedOutput      = outputPathCalculator.GetAssemblyPath(args.ConfigValue);

            var nativeArgs = new List <string>();

            // Input Assembly
            nativeArgs.Add($"{managedOutput}");

            // ILC Args
            if (!string.IsNullOrWhiteSpace(args.IlcArgsValue))
            {
                nativeArgs.Add("--ilcargs");
                nativeArgs.Add($"{args.IlcArgsValue}");
            }

            // ILC Path
            if (!string.IsNullOrWhiteSpace(args.IlcPathValue))
            {
                nativeArgs.Add("--ilcpath");
                nativeArgs.Add(args.IlcPathValue);
            }

            // ILC SDK Path
            if (!string.IsNullOrWhiteSpace(args.IlcSdkPathValue))
            {
                nativeArgs.Add("--ilcsdkpath");
                nativeArgs.Add(args.IlcSdkPathValue);
            }

            // AppDep SDK Path
            if (!string.IsNullOrWhiteSpace(args.AppDepSdkPathValue))
            {
                nativeArgs.Add("--appdepsdk");
                nativeArgs.Add(args.AppDepSdkPathValue);
            }

            // CodeGen Mode
            if (args.IsCppModeValue)
            {
                nativeArgs.Add("--mode");
                nativeArgs.Add("cpp");
            }

            if (!string.IsNullOrWhiteSpace(args.CppCompilerFlagsValue))
            {
                nativeArgs.Add("--cppcompilerflags");
                nativeArgs.Add(args.CppCompilerFlagsValue);
            }

            // Configuration
            if (args.ConfigValue != null)
            {
                nativeArgs.Add("--configuration");
                nativeArgs.Add(args.ConfigValue);
            }

            // Architecture
            if (args.ArchValue != null)
            {
                nativeArgs.Add("--arch");
                nativeArgs.Add(args.ArchValue);
            }

            // Intermediate Path
            nativeArgs.Add("--temp-output");
            nativeArgs.Add($"{nativeIntermediateOutputPath}");

            // Output Path
            nativeArgs.Add("--output");
            nativeArgs.Add($"{nativeOutputPath}");

            // Write Response File
            var rsp = Path.Combine(nativeIntermediateOutputPath, $"dotnet-compile-native.{context.ProjectFile.Name}.rsp");

            File.WriteAllLines(rsp, nativeArgs);

            // TODO Add -r assembly.dll for all Nuget References
            //     Need CoreRT Framework published to nuget

            // Do Native Compilation
            var result = Command.CreateDotNet("compile-native", new string[] { "--rsp", $"{rsp}" })
                         .ForwardStdErr()
                         .ForwardStdOut()
                         .Execute();

            return(result.ExitCode == 0);
        }
Exemplo n.º 9
0
        private static bool CompileProject(ProjectContext context, CompilerCommandApp args)
        {
            // Set up Output Paths
            var outputPathCalculator   = context.GetOutputPathCalculator(args.OutputValue);
            var outputPath             = outputPathCalculator.GetOutputDirectoryPath(args.ConfigValue);
            var intermediateOutputPath =
                outputPathCalculator.GetIntermediateOutputDirectoryPath(args.ConfigValue, args.IntermediateValue);

            Directory.CreateDirectory(outputPath);
            Directory.CreateDirectory(intermediateOutputPath);

            // Create the library exporter
            var exporter = context.CreateExporter(args.ConfigValue);

            // Gather exports for the project
            var dependencies = exporter.GetDependencies().ToList();

            Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}");
            var sw = Stopwatch.StartNew();

            var diagnostics = new List <DiagnosticMessage>();
            var missingFrameworkDiagnostics = new List <DiagnosticMessage>();

            // Collect dependency diagnostics
            foreach (var diag in context.LibraryManager.GetAllDiagnostics())
            {
                if (diag.ErrorCode == ErrorCodes.DOTNET1011 ||
                    diag.ErrorCode == ErrorCodes.DOTNET1012)
                {
                    missingFrameworkDiagnostics.Add(diag);
                }

                diagnostics.Add(diag);
            }

            if (missingFrameworkDiagnostics.Count > 0)
            {
                // The framework isn't installed so we should short circuit the rest of the compilation
                // so we don't get flooded with errors
                PrintSummary(missingFrameworkDiagnostics, sw);
                return(false);
            }

            // Get compilation options
            var outputName = outputPathCalculator.GetAssemblyPath(args.ConfigValue);

            // Assemble args
            var compilerArgs = new List <string>()
            {
                $"--temp-output:\"{intermediateOutputPath}\"",
                $"--out:\"{outputName}\""
            };

            var compilationOptions = CompilerUtil.ResolveCompilationOptions(context, args.ConfigValue);
            var languageId         = CompilerUtil.ResolveLanguageId(context);

            var references = new List <string>();

            // Add compilation options to the args
            compilerArgs.AddRange(compilationOptions.SerializeToArgs());

            // Add metadata options
            compilerArgs.AddRange(AssemblyInfoOptions.SerializeToArgs(AssemblyInfoOptions.CreateForProject(context)));

            foreach (var dependency in dependencies)
            {
                references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath));
                compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\""));

                // Add analyzer references
                compilerArgs.AddRange(dependency.AnalyzerReferences
                                      .Where(a => a.AnalyzerLanguage == languageId)
                                      .Select(a => $"--analyzer:\"{a.AssemblyPath}\""));
            }

            compilerArgs.AddRange(references.Select(r => $"--reference:\"{r}\""));

            if (compilationOptions.PreserveCompilationContext == true)
            {
                var dependencyContext = DependencyContextBuilder.Build(compilationOptions,
                                                                       exporter,
                                                                       args.ConfigValue,
                                                                       context.TargetFramework,
                                                                       context.RuntimeIdentifier);

                var writer       = new DependencyContextWriter();
                var depsJsonFile = Path.Combine(intermediateOutputPath, context.ProjectFile.Name + "dotnet-compile.deps.json");
                using (var fileStream = File.Create(depsJsonFile))
                {
                    writer.Write(dependencyContext, fileStream);
                }

                compilerArgs.Add($"--resource:\"{depsJsonFile},{context.ProjectFile.Name}.deps.json\"");
            }

            if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath))
            {
                return(false);
            }
            // Add project source files
            var sourceFiles = CompilerUtil.GetCompilationSources(context);

            compilerArgs.AddRange(sourceFiles);

            var compilerName = CompilerUtil.ResolveCompilerName(context);

            // Write RSP file
            var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp");

            File.WriteAllLines(rsp, compilerArgs);

            // Run pre-compile event
            var contextVariables = new Dictionary <string, string>()
            {
                { "compile:TargetFramework", context.TargetFramework.DotNetFrameworkName },
                { "compile:Configuration", args.ConfigValue },
                { "compile:OutputFile", outputName },
                { "compile:OutputDir", outputPath },
                { "compile:ResponseFile", rsp }
            };

            RunScripts(context, ScriptNames.PreCompile, contextVariables);

            var result = Command.CreateDotNet($"compile-{compilerName}", new[] { "@" + $"{rsp}" })
                         .OnErrorLine(line =>
            {
                var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
                if (diagnostic != null)
                {
                    diagnostics.Add(diagnostic);
                }
                else
                {
                    Reporter.Error.WriteLine(line);
                }
            })
                         .OnOutputLine(line =>
            {
                var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
                if (diagnostic != null)
                {
                    diagnostics.Add(diagnostic);
                }
                else
                {
                    Reporter.Output.WriteLine(line);
                }
            }).Execute();

            // Run post-compile event
            contextVariables["compile:CompilerExitCode"] = result.ExitCode.ToString();
            RunScripts(context, ScriptNames.PostCompile, contextVariables);

            var success = result.ExitCode == 0;

            if (!success)
            {
                Reporter.Error.WriteLine($"{result.StartInfo.FileName} {result.StartInfo.Arguments} returned Exit Code {result.ExitCode}");
            }

            if (success)
            {
                success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, intermediateOutputPath, outputPath);
            }

            return(PrintSummary(diagnostics, sw, success));
        }
Exemplo n.º 10
0
        private int RunExecutable()
        {
            CalculateDefaultsForNonAssigned();

            // Create a temporary directory under the project root
            // REVIEW: MAX_PATH?
            var tempDir = Path.Combine(_context.ProjectDirectory, "bin", ".dotnetrun", Guid.NewGuid().ToString("N"));

            // Compile to that directory
            var result = Command.CreateDotNet($"build", new []
            {
                $"--output",
                $"{tempDir}",
                $"--temp-output",
                $"{tempDir}",
                $"--framework",
                $"{_context.TargetFramework}",
                $"--configuration",
                $"{Configuration}",
                $"{_context.ProjectFile.ProjectDirectory}"
            })
                         .ForwardStdOut(onlyIfVerbose: true)
                         .ForwardStdErr()
                         .Execute();

            if (result.ExitCode != 0)
            {
                return(result.ExitCode);
            }

            // Now launch the output and give it the results
            var outputName = _context.GetOutputPathCalculator(tempDir).GetExecutablePath(Configuration);

            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                if (_context.TargetFramework.IsDesktop())
                {
                    // Run mono if we're running a desktop target on non windows
                    _args.Insert(0, outputName);

                    if (string.Equals(Configuration, "Debug", StringComparison.OrdinalIgnoreCase))
                    {
                        // If we're compiling for the debug configuration then add the --debug flag
                        // other options may be passed using the MONO_OPTIONS env var
                        _args.Insert(0, "--debug");
                    }

                    outputName = "mono";
                }
            }

            // Locate the runtime
            string runtime = Environment.GetEnvironmentVariable("DOTNET_HOME");

            if (string.IsNullOrEmpty(runtime))
            {
                // Use the runtime deployed with the tools, if present
                var candidate = Path.Combine(AppContext.BaseDirectory, "..", "runtime");
                if (File.Exists(Path.Combine(candidate, Constants.LibCoreClrName)))
                {
                    runtime = Path.GetFullPath(candidate);
                }
            }

            result = Command.Create(outputName, _args)
                     .ForwardStdOut()
                     .ForwardStdErr()
                     .EnvironmentVariable("DOTNET_HOME", runtime)
                     .Execute();

            // Clean up
            if (!PreserveTemporary)
            {
                Directory.Delete(tempDir, recursive: true);
            }

            return(result.ExitCode);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Publish the project for given 'framework (ex - dnxcore50)' and 'runtimeID (ex - win7-x64)'
        /// </summary>
        /// <param name="context">project that is to be published</param>
        /// <param name="baseOutputPath">Location of published files</param>
        /// <param name="configuration">Debug or Release</param>
        /// <param name="nativeSubdirectories"></param>
        /// <returns>Return 0 if successful else return non-zero</returns>
        private static bool PublishProjectContext(ProjectContext context, string outputPath, string configuration, bool nativeSubdirectories)
        {
            Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}/{context.RuntimeIdentifier.Yellow()}");

            var options = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);

            if (string.IsNullOrEmpty(outputPath))
            {
                outputPath = context.GetOutputPathCalculator().GetOutputDirectoryPath(configuration);
            }

            var contextVariables = new Dictionary <string, string>
            {
                { "publish:ProjectPath", context.ProjectDirectory },
                { "publish:Configuration", configuration },
                { "publish:OutputPath", outputPath },
                { "publish:Framework", context.TargetFramework.Framework },
                { "publish:Runtime", context.RuntimeIdentifier },
            };

            RunScripts(context, ScriptNames.PrePublish, contextVariables);

            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            // Compile the project (and transitively, all it's dependencies)
            var result = Command.CreateDotNet("build",
                                              new string[] {
                "--framework",
                $"{context.TargetFramework.DotNetFrameworkName}",
                "--runtime",
                context.RuntimeIdentifier,
                "--configuration",
                configuration,
                context.ProjectFile.ProjectDirectory
            })
                         .ForwardStdErr()
                         .ForwardStdOut()
                         .Execute();

            if (result.ExitCode != 0)
            {
                return(false);
            }

            // Use a library exporter to collect publish assets
            var exporter = context.CreateExporter(configuration);

            foreach (var export in exporter.GetAllExports())
            {
                Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ...");

                PublishFiles(export.RuntimeAssemblies, outputPath, nativeSubdirectories: false);
                PublishFiles(export.NativeLibraries, outputPath, nativeSubdirectories);
                PublishFiles(export.RuntimeAssets, outputPath);

                if (options.PreserveCompilationContext.GetValueOrDefault())
                {
                    PublishRefs(export, outputPath);
                }
            }

            CopyContents(context, outputPath);

            // Publish a host if this is an application
            if (options.EmitEntryPoint.GetValueOrDefault())
            {
                Reporter.Verbose.WriteLine($"Making {context.ProjectFile.Name.Cyan()} runnable ...");
                PublishHost(context, outputPath);
            }

            RunScripts(context, ScriptNames.PostPublish, contextVariables);

            Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold());

            return(true);
        }