public override LinkResult Link(IConsole console, Project superProject, Project project, CompileResult assemblies, string outputDirectory) { LinkResult result = new LinkResult(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-gcc.exe"); if (project.Type == ProjectType.StaticLibrary) { startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-ar.exe"); } startInfo.WorkingDirectory = project.Solution.CurrentDirectory; if (!File.Exists(startInfo.FileName)) { result.ExitCode = -1; console.WriteLine("Unable to find linker executable (" + startInfo.FileName + ") Check project compiler settings."); return result; } // GenerateLinkerScript(project); string objectArguments = string.Empty; foreach (string obj in assemblies.ObjectLocations) { objectArguments += obj + " "; } string libs = string.Empty; foreach (string lib in assemblies.LibraryLocations) { libs += lib + " "; } if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); } string outputName = Path.GetFileNameWithoutExtension(project.Location) + ".elf"; if (project.Type == ProjectType.StaticLibrary) { outputName = "lib" + Path.GetFileNameWithoutExtension(project.Name) + ".a"; } var executable = Path.Combine(outputDirectory, outputName); string linkedLibraries = string.Empty; //foreach (var libraryPath in project.SelectedConfiguration.LinkedLibraries) //{ // string relativePath = Path.GetDirectoryName(libraryPath); // string libName = Path.GetFileNameWithoutExtension(libraryPath).Substring(3); // linkedLibraries += string.Format(" -L\"{0}\" -l{1}", relativePath, libName); //} foreach (var lib in project.BuiltinLibraries) { linkedLibraries += string.Format("-l{0} ", lib); } // Hide console window startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.RedirectStandardInput = true; startInfo.CreateNoWindow = true; startInfo.Arguments = string.Format("{0} -o{1} {2} -Wl,--start-group {3} {4} -Wl,--end-group", GetLinkerArguments(project), executable, objectArguments, linkedLibraries, libs); if (project.Type == ProjectType.StaticLibrary) { startInfo.Arguments = string.Format("rvs {0} {1}", executable, objectArguments); } //console.WriteLine(Path.GetFileNameWithoutExtension(startInfo.FileName) + " " + startInfo.Arguments); //console.WriteLine ("[LL] - " + startInfo.Arguments); using (var process = Process.Start(startInfo)) { process.OutputDataReceived += (sender, e) => { //console.WriteLine(e.Data); }; process.ErrorDataReceived += (sender, e) => { if (e.Data != null && !e.Data.Contains("creating")) { console.WriteLine(e.Data); } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); result.ExitCode = process.ExitCode; if (result.ExitCode == 0) { result.Executable = executable; } } return result; }
public override CompileResult Compile(IConsole console, Project superProject, Project project, SourceFile file, string outputFile) { CompileResult result = new CompileResult(); var startInfo = new ProcessStartInfo(); if (file.Language == Language.Cpp) { startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-g++.exe"); } else { startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-gcc.exe"); } startInfo.WorkingDirectory = project.Solution.CurrentDirectory; if (!File.Exists(startInfo.FileName)) { result.ExitCode = -1; console.WriteLine("Unable to find compiler (" + startInfo.FileName + ") Please check project compiler settings."); } else { string fileArguments = string.Empty; if (file.Language == Language.Cpp) { fileArguments = "-x c++ -std=c++14 -fno-use-cxa-atexit"; } startInfo.Arguments = string.Format("{0} {1} {2} -o{3} -MMD -MP", GetCompilerArguments(superProject, project, file.Language), fileArguments, file.Location, outputFile); // Hide console window startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.CreateNoWindow = true; // console.WriteLine (Path.GetFileNameWithoutExtension(startInfo.FileName) + " " + startInfo.Arguments); using (var process = Process.Start(startInfo)) { process.OutputDataReceived += (sender, e) => { console.WriteLine(e.Data); }; process.ErrorDataReceived += (sender, e) => { if (e.Data != null) { console.WriteLine(); console.WriteLine(e.Data); } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); result.ExitCode = process.ExitCode; } } return result; }
public override async Task<bool> Build(IConsole console, Project project) { console.WriteLine("Starting Build..."); bool result = true; terminateBuild = false; SetFileCount(project); buildCount = 0; var compiledProjects = new List<CompileResult>(); if (!terminateBuild) { await CompileProject(console, project, project, compiledProjects); if (!terminateBuild) { await WaitForCompileJobs(); foreach (var compiledReference in compiledProjects) { result = compiledReference.ExitCode == 0; if(!result) { break; } } if (result) { var linkedReferences = new CompileResult(); linkedReferences.Project = project; foreach (var compiledProject in compiledProjects) { if (compiledProject.Project != project) { Link(console, project, compiledProject, linkedReferences); } else { if (linkedReferences.Count > 0) { linkedReferences.ObjectLocations = compiledProject.ObjectLocations; Link(console, project, linkedReferences, linkedReferences); } } if(linkedReferences.ExitCode != 0) { result = false; break; } } } ClearBuildFlags(project); } } console.WriteLine(); if(result && !terminateBuild) { console.WriteLine("Build Successful"); } else { console.WriteLine("Build Failed"); } return result; }
public abstract LinkResult Link(IConsole console, Project superProject, Project project, CompileResult assemblies, string outputDirectory);
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); } } } } } } }
private void Link(IConsole console, Project superProject, CompileResult compileResult, CompileResult linkResults) { var binDirectory = compileResult.Project.GetBinDirectory(superProject); if (!Directory.Exists(binDirectory)) { Directory.CreateDirectory(binDirectory); } string outputLocation = binDirectory; string executable = Path.Combine(outputLocation, compileResult.Project.Name); if (compileResult.Project.Type == ProjectType.StaticLibrary) { executable = Path.Combine(outputLocation, "lib" + compileResult.Project.Name); executable += ".a"; } else { executable += ".elf"; } if (!Directory.Exists(outputLocation)) { Directory.CreateDirectory(outputLocation); } console.OverWrite(string.Format("[LL] [{0}]", compileResult.Project.Name)); var linkResult = Link(console, superProject, compileResult.Project, compileResult, outputLocation); if (linkResult.ExitCode == 0) { if (compileResult.Project.Type == ProjectType.StaticLibrary) { linkResults.LibraryLocations.Add(executable); } else { console.WriteLine(); Size(console, compileResult.Project, linkResult); linkResults.ExecutableLocations.Add(executable); } } else if(linkResults.ExitCode == 0) { linkResults.ExitCode = linkResult.ExitCode; } }