private ProjectId AddProject(ProjectContext project) { // Create the framework specific project and add it to the workspace var projectInfo = ProjectInfo.Create( ProjectId.CreateNewId(), VersionStamp.Create(), project.ProjectFile.Name + "+" + project.TargetFramework, project.ProjectFile.Name, LanguageNames.CSharp, project.ProjectFile.ProjectFilePath); OnProjectAdded(projectInfo); // TODO: ctor argument? var configuration = "Debug"; var compilationOptions = project.ProjectFile.GetCompilerOptions(project.TargetFramework, configuration); var compilationSettings = ToCompilationSettings(compilationOptions, project.TargetFramework, project.ProjectFile.ProjectDirectory); OnParseOptionsChanged(projectInfo.Id, new CSharpParseOptions(compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines)); OnCompilationOptionsChanged(projectInfo.Id, compilationSettings.CompilationOptions); foreach (var file in project.ProjectFile.Files.SourceFiles) { AddSourceFile(projectInfo, file); } var exporter = project.CreateExporter(configuration); foreach (var dependency in exporter.GetDependencies()) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null) { var projectDependencyContext = ProjectContext.Create(projectDependency.Project.ProjectFilePath, projectDependency.Framework); var id = AddProject(projectDependencyContext); OnProjectReferenceAdded(projectInfo.Id, new ProjectReference(id)); } else { foreach (var asset in dependency.CompilationAssemblies) { OnMetadataReferenceAdded(projectInfo.Id, GetMetadataReference(asset.ResolvedPath)); } } foreach (var file in dependency.SourceReferences) { AddSourceFile(projectInfo, file); } } return projectInfo.Id; }
private static int Publish(ProjectContext context, string outputPath, string configuration) { 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 (!options.EmitEntryPoint.GetValueOrDefault()) { Reporter.Output.WriteLine($"{context.RootProject.Identity} does not have an entry point defined.".Red()); return 1; } // Generate the output path if (string.IsNullOrEmpty(outputPath)) { outputPath = Path.Combine( context.ProjectFile.ProjectDirectory, Constants.BinDirectoryName, configuration, context.TargetFramework.GetTwoDigitShortFolderName(), context.RuntimeIdentifier); } if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } // Compile the project (and transitively, all it's dependencies) var result = Command.Create("dotnet-compile", $"--framework \"{context.TargetFramework.DotNetFrameworkName}\" --output \"{outputPath}\" --configuration \"{configuration}\" \"{context.ProjectFile.ProjectDirectory}\"") .ForwardStdErr() .ForwardStdOut() .Execute(); if (result.ExitCode != 0) { return result.ExitCode; } // Use a library exporter to collect publish assets var exporter = context.CreateExporter(configuration); foreach (var export in exporter.GetAllExports()) { // Skip copying project references if (export.Library is ProjectDescription) { continue; } Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ..."); PublishFiles(export.RuntimeAssemblies, outputPath); PublishFiles(export.NativeLibraries, outputPath); } // Publish the application itself PublishHost(context, outputPath); Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold()); return 0; }
private static bool CompileNative(ProjectContext context, string configuration, string outputOptionValue, bool buildProjectReferences, string intermediateOutputValue, string archValue, string ilcArgsValue, bool isCppMode) { var outputPath = Path.Combine(GetOutputPath(context, configuration, outputOptionValue), "native"); var intermediateOutputPath = GetIntermediateOutputPath(context, configuration, intermediateOutputValue, outputOptionValue); Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); var managedOutput = GetProjectOutput(context.ProjectFile, context.TargetFramework, configuration, outputPath); var nativeArgs = new List<string>(); // Input Assembly nativeArgs.Add($"\"{managedOutput}\""); // ILC Args nativeArgs.Add("--ilcargs"); nativeArgs.Add($"\"{ilcArgsValue}\""); // CodeGen Mode if(isCppMode) { nativeArgs.Add("--mode"); nativeArgs.Add("cpp"); } // Configuration if (configuration != null) { nativeArgs.Add("--configuration"); nativeArgs.Add(configuration); } // Architecture if (archValue != null) { nativeArgs.Add("--arch"); nativeArgs.Add(archValue); } // Intermediate Path nativeArgs.Add("--temp-output"); nativeArgs.Add($"\"{intermediateOutputPath}\""); // Output Path nativeArgs.Add("--output"); nativeArgs.Add($"\"{outputPath}\""); // Dependencies var exporter = context.CreateExporter(configuration); var dependencies = exporter.GetDependencies().ToList(); foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null) { if (projectDependency.Project.Files.SourceFiles.Any()) { var projectOutputPath = GetProjectOutput(projectDependency.Project, projectDependency.Framework, configuration, outputPath); nativeArgs.Add("-r"); nativeArgs.Add($"\"{projectOutputPath}\""); } } else { foreach(var dep in dependency.RuntimeAssemblies) { nativeArgs.Add("-r"); nativeArgs.Add($"\"{dep.ResolvedPath}\""); } } } // Write Response File var rsp = Path.Combine(intermediateOutputPath, $"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.Create($"dotnet-compile-native", $"--rsp \"{rsp}\"") .ForwardStdErr() .ForwardStdOut() .Execute(); return result.ExitCode == 0; }
private static bool Compile(ProjectContext context, string configuration, string outputOptionValue, string intermediateOutputValue, bool buildProjectReferences) { // Set up Output Paths string outputPath = GetOutputPath(context, configuration, outputOptionValue); string intermediateOutputPath = GetIntermediateOutputPath(context, configuration, intermediateOutputValue, outputOptionValue); Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(configuration); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); if (buildProjectReferences) { var projects = new Dictionary<string, ProjectDescription>(); // Build project references foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null && projectDependency.Project.Files.SourceFiles.Any()) { projects[projectDependency.Identity.Name] = projectDependency; } } foreach (var projectDependency in Sort(projects)) { // Skip compiling project dependencies since we've already figured out the build order var compileResult = Command.Create("dotnet-compile", $"--framework {projectDependency.Framework} --configuration {configuration} --output \"{outputPath}\" --temp-output \"{intermediateOutputPath}\" --no-project-dependencies \"{projectDependency.Project.ProjectDirectory}\"") .ForwardStdOut() .ForwardStdErr() .Execute(); if (compileResult.ExitCode != 0) { return false; } } projects.Clear(); } return CompileProject(context, configuration, outputPath, intermediateOutputPath, dependencies); }
private static bool Compile(ProjectContext context, string configuration, string outputOptionValue, string intermediateOutputValue, bool buildProjectReferences) { // Set up Output Paths string outputPath = GetOutputPath(context, configuration, outputOptionValue); string intermediateOutputPath = GetIntermediateOutputPath(context, configuration, intermediateOutputValue, outputOptionValue); Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(configuration); var diagnostics = new List<DiagnosticMessage>(); // Collect dependency diagnostics diagnostics.AddRange(context.LibraryManager.GetAllDiagnostics()); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); if (buildProjectReferences) { var projects = new Dictionary<string, ProjectDescription>(); // Build project references foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null && projectDependency.Project.Files.SourceFiles.Any()) { projects[projectDependency.Identity.Name] = projectDependency; } } foreach (var projectDependency in Sort(projects)) { // Skip compiling project dependencies since we've already figured out the build order var compileResult = Command.Create("dotnet-compile", $"--framework {projectDependency.Framework} --configuration {configuration} --output \"{outputPath}\" --temp-output \"{intermediateOutputPath}\" --no-project-dependencies \"{projectDependency.Project.ProjectDirectory}\"") .ForwardStdOut() .ForwardStdErr() .Execute(); if (compileResult.ExitCode != 0) { return false; } } projects.Clear(); } Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}"); // Dump dependency data // TODO: Turn on only if verbose, we can look at the response // file anyways // ShowDependencyInfo(dependencies); // Get compilation options var outputName = GetProjectOutput(context.ProjectFile, context.TargetFramework, configuration, outputPath); // Assemble args var compilerArgs = new List<string>() { "-nostdlib", "-nologo", $"-out:\"{outputName}\"" }; // Default suppressions, some versions of mono don't support these compilerArgs.Add("-nowarn:CS1701"); compilerArgs.Add("-nowarn:CS1702"); compilerArgs.Add("-nowarn:CS1705"); var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); // Add compilation options to the args ApplyCompilationOptions(compilationOptions, compilerArgs); foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null) { if (projectDependency.Project.Files.SourceFiles.Any()) { var projectOutputPath = GetProjectOutput(projectDependency.Project, projectDependency.Framework, configuration, outputPath); compilerArgs.Add($"-r:\"{projectOutputPath}\""); } } else { compilerArgs.AddRange(dependency.CompilationAssemblies.Select(r => $"-r:\"{r.ResolvedPath}\"")); } compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\"")); } // Add project source files var sourceFiles = context.ProjectFile.Files.SourceFiles; compilerArgs.AddRange(sourceFiles.Select(s => $"\"{s}\"")); if (!AddResources(context.ProjectFile, compilerArgs, intermediateOutputPath)) { return false; } var compilerName = context.ProjectFile.CompilerName; compilerName = compilerName ?? "csc"; // Write RSP file var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.{compilerName}.{context.ProjectFile.Name}.rsp"); File.WriteAllLines(rsp, compilerArgs); var result = Command.Create($"dotnet-compile-{compilerName}", $"\"{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(); foreach (var diag in diagnostics) { PrintDiagnostic(diag); } var success = result.ExitCode == 0; if (success && compilationOptions.EmitEntryPoint.GetValueOrDefault()) { var runtimeContext = ProjectContext.Create(context.ProjectDirectory, context.TargetFramework, new[] { RuntimeIdentifier.Current }); MakeRunnable(runtimeContext, outputPath, runtimeContext.CreateExporter(configuration)); } PrintSummary(success, diagnostics); return success; }
private static bool Compile(ProjectContext context, string configuration, string outputOptionValue, string intermediateOutputValue, bool buildProjectReferences) { // Set up Output Paths string outputPath = GetOutputPath(context, configuration, outputOptionValue); string intermediateOutputPath = GetIntermediateOutputPath(context, configuration, intermediateOutputValue, outputOptionValue); Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(configuration); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); if (buildProjectReferences) { var projects = new Dictionary<string, ProjectDescription>(); // Build project references foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null && projectDependency.Project.Files.SourceFiles.Any()) { projects[projectDependency.Identity.Name] = projectDependency; } } foreach (var projectDependency in Sort(projects)) { // Skip compiling project dependencies since we've already figured out the build order var compileResult = Command.Create("dotnet-compile", $"--framework {projectDependency.Framework} --configuration {configuration} --output \"{outputPath}\" --temp-output \"{intermediateOutputPath}\" --no-project-dependencies \"{projectDependency.Project.ProjectDirectory}\"") .ForwardStdOut() .ForwardStdErr() .Execute(); if (compileResult.ExitCode != 0) { return false; } } projects.Clear(); } 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; } // Dump dependency data // TODO: Turn on only if verbose, we can look at the response // file anyways // ShowDependencyInfo(dependencies); // Get compilation options var outputName = GetProjectOutput(context.ProjectFile, context.TargetFramework, configuration, outputPath); // Assemble args var compilerArgs = new List<string>() { $"--temp-output:{intermediateOutputPath}", $"--out:{outputName}" }; var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); if (!string.IsNullOrEmpty(compilationOptions.KeyFile)) { // Resolve full path to key file compilationOptions.KeyFile = Path.GetFullPath(Path.Combine(context.ProjectFile.ProjectDirectory, compilationOptions.KeyFile)); } // Add compilation options to the args compilerArgs.AddRange(compilationOptions.SerializeToArgs()); foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null) { if (projectDependency.Project.Files.SourceFiles.Any()) { var projectOutputPath = GetProjectOutput(projectDependency.Project, projectDependency.Framework, configuration, outputPath); compilerArgs.Add($"--reference:{projectOutputPath}"); } } else { compilerArgs.AddRange(dependency.CompilationAssemblies.Select(r => $"--reference:{r.ResolvedPath}")); } compilerArgs.AddRange(dependency.SourceReferences); } if (!AddResources(context.ProjectFile, compilerArgs, intermediateOutputPath)) { return false; } // Add project source files var sourceFiles = context.ProjectFile.Files.SourceFiles; compilerArgs.AddRange(sourceFiles); var compilerName = context.ProjectFile.CompilerName; compilerName = compilerName ?? "csc"; // Write RSP file var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.{context.ProjectFile.Name}.rsp"); File.WriteAllLines(rsp, compilerArgs); var result = Command.Create($"dotnet-compile-{compilerName}", $"@\"{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(); var success = result.ExitCode == 0; if (success && compilationOptions.EmitEntryPoint.GetValueOrDefault()) { var runtimeContext = ProjectContext.Create(context.ProjectDirectory, context.TargetFramework, new[] { RuntimeIdentifier.Current }); MakeRunnable(runtimeContext, outputPath, runtimeContext.CreateExporter(configuration)); } return PrintSummary(diagnostics, sw, success); }