private async Task CompileProject(IConsole console, IStandardProject superProject, IStandardProject 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 standardReference = reference as IStandardProject;
if (standardReference != null)
{
await CompileProject(console, superProject, standardReference, results);
}
}
var outputDirectory = project.GetOutputDirectory(superProject);
if (!Directory.Exists(outputDirectory))
{
Directory.CreateDirectory(outputDirectory);
}
var 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 numLocalTasks = 0;
var sourceFiles = project.SourceFiles.ToList();
foreach (var file in sourceFiles)
{
if (terminateBuild)
{
break;
}
if (SupportsFile(file))
{
var outputName = Path.GetFileNameWithoutExtension(file.Location) + ".o";
var dependencyFile = Path.Combine(objDirectory, Path.GetFileNameWithoutExtension(file.Location) + ".d");
var objectFile = Path.Combine(objDirectory, outputName);
var dependencyChanged = false;
if (System.IO.File.Exists(dependencyFile))
{
var dependencies = new List<string>();
dependencies.AddRange(ProjectExtensions.GetDependencies(dependencyFile));
foreach (var dependency in dependencies)
{
if (!System.IO.File.Exists(dependency) || System.IO.File.GetLastWriteTime(dependency) > System.IO.File.GetLastWriteTime(objectFile))
{
dependencyChanged = true;
break;
}
}
}
if (dependencyChanged || !System.IO.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(() =>
{
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);
compileResults.NumberOfObjectsCompiled++;
}
numTasks--;
numLocalTasks--;
}
}).Start();
}
else
{
buildCount++;
compileResults.ObjectLocations.Add(objectFile);
}
}
}
}
}
}
}