Stop over building

- Added a flag --no-project-dependencies to dotnet-compile to avoid building project
dependencies.
- Made small tweak to LibraryExporter to check for instances rather than names

#63
This commit is contained in:
David Fowler 2015-10-17 23:43:28 -07:00
parent 68d591124e
commit 6bb95c4857
2 changed files with 57 additions and 13 deletions

View file

@ -25,6 +25,7 @@ namespace Microsoft.DotNet.Tools.Compiler
var output = app.Option("-o|--output <OUTPUT_DIR>", "Directory in which to place outputs", CommandOptionType.SingleValue); var output = app.Option("-o|--output <OUTPUT_DIR>", "Directory in which to place outputs", CommandOptionType.SingleValue);
var framework = app.Option("-f|--framework <FRAMEWORK>", "Compile a specific framework", CommandOptionType.MultipleValue); var framework = app.Option("-f|--framework <FRAMEWORK>", "Compile a specific framework", CommandOptionType.MultipleValue);
var configuration = app.Option("-c|--configuration <CONFIGURATION>", "Configuration under which to build", CommandOptionType.SingleValue); var configuration = app.Option("-c|--configuration <CONFIGURATION>", "Configuration under which to build", CommandOptionType.SingleValue);
var noProjectDependencies = app.Option("--no-project-dependencies", "Skips building project references.", CommandOptionType.NoValue);
var project = app.Argument("<PROJECT>", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); var project = app.Argument("<PROJECT>", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory");
app.OnExecute(() => app.OnExecute(() =>
@ -36,20 +37,22 @@ namespace Microsoft.DotNet.Tools.Compiler
path = Directory.GetCurrentDirectory(); path = Directory.GetCurrentDirectory();
} }
var skipBuildingProjectReferences = noProjectDependencies.HasValue();
// Load project contexts for each framework and compile them // Load project contexts for each framework and compile them
bool success = true; bool success = true;
if (framework.HasValue()) if (framework.HasValue())
{ {
foreach (var context in framework.Values.Select(f => ProjectContext.Create(path, NuGetFramework.Parse(f)))) foreach (var context in framework.Values.Select(f => ProjectContext.Create(path, NuGetFramework.Parse(f))))
{ {
success &= Compile(context, configuration.Value() ?? Constants.DefaultConfiguration, output.Value()); success &= Compile(context, configuration.Value() ?? Constants.DefaultConfiguration, output.Value(), skipBuildingProjectReferences);
} }
} }
else else
{ {
foreach (var context in ProjectContext.CreateContextForEachFramework(path)) foreach (var context in ProjectContext.CreateContextForEachFramework(path))
{ {
success &= Compile(context, configuration.Value() ?? Constants.DefaultConfiguration, output.Value()); success &= Compile(context, configuration.Value() ?? Constants.DefaultConfiguration, output.Value(), skipBuildingProjectReferences);
} }
} }
return success ? 0 : 1; return success ? 0 : 1;
@ -66,7 +69,7 @@ namespace Microsoft.DotNet.Tools.Compiler
} }
} }
private static bool Compile(ProjectContext context, string configuration, string outputPath) private static bool Compile(ProjectContext context, string configuration, string outputPath, bool skipBuildingProjectReferences)
{ {
Reporter.Output.WriteLine($"Building {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}"); Reporter.Output.WriteLine($"Building {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}");
@ -91,17 +94,30 @@ namespace Microsoft.DotNet.Tools.Compiler
// Gather exports for the project // Gather exports for the project
var dependencies = exporter.GetCompilationDependencies().ToList(); var dependencies = exporter.GetCompilationDependencies().ToList();
// Hackily trigger builds of the dependent projects if (!skipBuildingProjectReferences)
foreach (var dependency in dependencies.Where(d => d.CompilationAssemblies.Any()))
{ {
var projectDependency = dependency.Library as ProjectDescription; var projects = new Dictionary<string, ProjectDescription>();
if (projectDependency != null && !string.Equals(projectDependency.Identity.Name, context.RootProject.Identity.Name, StringComparison.Ordinal))
// Build project references
foreach (var dependency in dependencies.Where(d => d.CompilationAssemblies.Any()))
{ {
var compileResult = Command.Create("dotnet-compile", $"--framework {projectDependency.Framework} --configuration {configuration} {projectDependency.Project.ProjectDirectory}") var projectDependency = dependency.Library as ProjectDescription;
.ForwardStdOut()
.ForwardStdErr() if (projectDependency != null)
.RunAsync() {
.Result; 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} --no-project-dependencies {projectDependency.Project.ProjectDirectory}")
.ForwardStdOut()
.ForwardStdErr()
.RunAsync()
.Result;
if (compileResult.ExitCode != 0) if (compileResult.ExitCode != 0)
{ {
Console.Error.WriteLine($"Failed to compile dependency: {projectDependency.Identity.Name}"); Console.Error.WriteLine($"Failed to compile dependency: {projectDependency.Identity.Name}");
@ -124,6 +140,7 @@ namespace Microsoft.DotNet.Tools.Compiler
configuration, configuration,
context.TargetFramework.GetTwoDigitShortFolderName()); context.TargetFramework.GetTwoDigitShortFolderName());
} }
if (!Directory.Exists(outputPath)) if (!Directory.Exists(outputPath))
{ {
Directory.CreateDirectory(outputPath); Directory.CreateDirectory(outputPath);
@ -170,6 +187,33 @@ namespace Microsoft.DotNet.Tools.Compiler
return result.ExitCode == 0; return result.ExitCode == 0;
} }
private static ISet<ProjectDescription> Sort(Dictionary<string, ProjectDescription> projects)
{
var outputs = new HashSet<ProjectDescription>();
foreach (var pair in projects)
{
Sort(pair.Value, projects, outputs);
}
return outputs;
}
private static void Sort(ProjectDescription project, Dictionary<string, ProjectDescription> projects, ISet<ProjectDescription> outputs)
{
// Sorts projects in dependency order so that we only build them once per chain
foreach (var dependency in project.Dependencies)
{
ProjectDescription projectDependency;
if (projects.TryGetValue(dependency.Name, out projectDependency))
{
Sort(projectDependency, projects, outputs);
}
}
outputs.Add(project);
}
private static Command RunCsc(string cscArgs) private static Command RunCsc(string cscArgs)
{ {
// Locate CoreRun // Locate CoreRun

View file

@ -41,7 +41,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
public IEnumerable<LibraryExport> GetCompilationDependencies() public IEnumerable<LibraryExport> GetCompilationDependencies()
{ {
// Export all but the main project // Export all but the main project
return ExportLibraries(l => !string.Equals(l.Identity.Name, _rootProject.Identity.Name, StringComparison.OrdinalIgnoreCase)); return ExportLibraries(library => library != _rootProject);
} }
/// <summary> /// <summary>