private async Task CleanAll(IConsole console, Project superProject, Project project) { foreach (var reference in project.References) { var loadedReference = project.GetReference(reference); if (loadedReference.Type == ProjectType.Executable) { await CleanAll(console, loadedReference, loadedReference); } else { await CleanAll(console, superProject, loadedReference); } } string outputDirectory = project.GetObjectDirectory(superProject); bool hasCleaned = false; if (Directory.Exists(outputDirectory)) { hasCleaned = true; try { Directory.Delete(outputDirectory, true); } catch (Exception) { } } outputDirectory = project.GetOutputDirectory(superProject); if (Directory.Exists(outputDirectory)) { hasCleaned = true; try { Directory.Delete(outputDirectory, true); } catch (Exception) { } } if (hasCleaned) { console.WriteLine(string.Format("[BB] - Cleaning Project - {0}", project.Name)); } }
private async Task CompileProject(IConsole console, Project superProject, Project project, List<CompileResult> results = null) { if (project.Type == ProjectType.Executable && superProject != project) { await Build(console, project); } else { if (!terminateBuild) { if (results == null) { results = new List<CompileResult>(); } foreach (var reference in project.References) { var loadedReference = project.GetReference(reference); await CompileProject(console, superProject, loadedReference, results); } var outputDirectory = project.GetOutputDirectory(superProject); if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); } bool doWork = false; lock (resultLock) { if (!project.IsBuilding) { project.IsBuilding = true; doWork = true; } } if (doWork) { var objDirectory = project.GetObjectDirectory(superProject); if (!Directory.Exists(objDirectory)) { Directory.CreateDirectory(objDirectory); } var compileResults = new CompileResult(); compileResults.Project = project; results.Add(compileResults); var tasks = new List<Task>(); //var parallelResult = Parallel.ForEach(project.SourceFiles, (file) => int numLocalTasks = 0; foreach (var file in project.SourceFiles) { if (terminateBuild) { break; } if (Path.GetExtension(file.Location) == ".c" || Path.GetExtension(file.Location) == ".cpp") { var outputName = Path.GetFileNameWithoutExtension(file.Location) + ".o"; var dependencyFile = Path.Combine(objDirectory, Path.GetFileNameWithoutExtension(file.Location) + ".d"); var objectFile = Path.Combine(objDirectory, outputName); bool dependencyChanged = false; if (File.Exists(dependencyFile)) { List<string> dependencies = new List<string>(); //lock(resultLock) { dependencies.AddRange(ProjectExtensions.GetDependencies(dependencyFile)); foreach (var dependency in dependencies) { if (!File.Exists(dependency) || File.GetLastWriteTime(dependency) > File.GetLastWriteTime(objectFile)) { dependencyChanged = true; break; } } } } if (dependencyChanged || !File.Exists(objectFile)) { while (numTasks >= Jobs) { Thread.Yield(); } lock (resultLock) { numLocalTasks++; numTasks++; console.OverWrite(string.Format("[CC {0}/{1}] [{2}] {3}", ++buildCount, fileCount, project.Name, Path.GetFileName(file.Location))); } new Thread(new ThreadStart(() => { var compileResult = Compile(console, superProject, project, file, objectFile); lock (resultLock) { if (compileResults.ExitCode == 0 && compileResult.ExitCode != 0) { terminateBuild = true; compileResults.ExitCode = compileResult.ExitCode; } else { compileResults.ObjectLocations.Add(objectFile); } numTasks--; numLocalTasks--; } })).Start(); } else { buildCount++; compileResults.ObjectLocations.Add(objectFile); } } } } } } }