public override string GetBaseLibraryArguments(IStandardProject superProject) { var settings = GetSettings(superProject); string result = string.Empty; // TODO linked libraries won't make it in on nano... Please fix -L directory placement in compile string. switch (settings.LinkSettings.Library) { case LibraryType.NanoCLib: result += "-lm -lc_nano -lsupc++_nano -lstdc++_nano "; break; case LibraryType.BaseCLib: result += "-lm -lc -lstdc++ -lsupc++ "; break; case LibraryType.SemiHosting: result += "-lm -lgcc -lc -lrdimon "; break; case LibraryType.Retarget: result += "-lm -lc -lnosys -lgcc -lstdc++ -lsupc++ "; break; } return result; }
private void CompileCS(IConsole console, IStandardProject superProject, IStandardProject project, ISourceFile file, string outputFile) { var startInfo = new ProcessStartInfo(); startInfo.FileName = Path.Combine(BaseDirectory, "Roslyn", "csc.exe"); if (Path.IsPathRooted(startInfo.FileName) && !System.IO.File.Exists(startInfo.FileName)) { console.WriteLine("Unable to find compiler (" + startInfo.FileName + ") Please check project compiler settings."); } else { startInfo.WorkingDirectory = project.Solution.CurrentDirectory; startInfo.Arguments = string.Format("{0} /out:{1} {2}", GetCSCCompilerArguments(superProject, project, file), outputFile, file.Location); // 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(); } } }
private void GenerateLinkerScript(IStandardProject project) { var settings = GetSettings(project).LinkSettings; var template = new ArmGCCLinkTemplate(settings); var linkerScript = GetLinkerScriptLocation(project); if (System.IO.File.Exists(linkerScript)) { System.IO.File.Delete(linkerScript); } var sw = System.IO.File.CreateText(linkerScript); sw.Write(template.TransformText()); sw.Close(); }
public static string GetOutputDirectory(this IStandardProject project, IStandardProject superProject) { var outputDirectory = string.Empty; if (string.IsNullOrEmpty(superProject.BuildDirectory)) { outputDirectory = Path.Combine(superProject.CurrentDirectory, "build"); } if (!string.IsNullOrEmpty(superProject.BuildDirectory)) { outputDirectory = Path.Combine(superProject.CurrentDirectory, superProject.BuildDirectory); } if (project != superProject) { outputDirectory = Path.Combine(outputDirectory, project.Name); } return outputDirectory; }
public override string GetCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile file) { var result = string.Empty; //var settings = GetSettings(project).CompileSettings; var settings = GetSettings(superProject); result += "-Wall -c "; if (settings.CompileSettings.DebugInformation) { result += "-g "; } // TODO remove dependency on file? if (file != null) { if (file.Extension == ".cpp") { if (!settings.CompileSettings.Rtti) { result += "-fno-rtti "; } if (!settings.CompileSettings.Exceptions) { result += "-fno-exceptions "; } result += "-std=c++14 "; } } // TODO make this an option. result += "-ffunction-sections -fdata-sections "; switch (settings.CompileSettings.Optimization) { case OptimizationLevel.None: { result += "-O0 "; } break; case OptimizationLevel.Debug: { result += "-Og "; } break; case OptimizationLevel.Level1: { result += "-O1 "; } break; case OptimizationLevel.Level2: { result += "-O2 "; } break; case OptimizationLevel.Level3: { result += "-O3 "; } break; } switch (settings.CompileSettings.OptimizationPreference) { case OptimizationPreference.Size: { result += "-Os "; } break; case OptimizationPreference.Speed: { result += "-Ofast "; } break; } result += settings.CompileSettings.CustomFlags + " "; // toolchain includes // Referenced includes var referencedIncludes = project.GetReferencedIncludes(); foreach (var include in referencedIncludes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include)); } // global includes var globalIncludes = superProject.GetGlobalIncludes(); foreach (var include in globalIncludes) { result += string.Format("-I\"{0}\" ", include); } // public includes foreach (var include in project.PublicIncludes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include)); } // includes foreach (var include in project.Includes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include.Value)); } var referencedDefines = project.GetReferencedDefines(); foreach (var define in referencedDefines) { result += string.Format("-D{0} ", define); } // global includes var globalDefines = superProject.GetGlobalDefines(); foreach (var define in globalDefines) { result += string.Format("-D{0} ", define); } foreach (var define in project.Defines) { result += string.Format("-D{0} ", define.Value); } if (Platform.PlatformIdentifier == PlatformID.Win32NT) { result += string.Format("-D{0} ", "WIN32NT"); } foreach (var arg in superProject.ToolChainArguments) { result += string.Format(" {0}", arg); } foreach (var arg in superProject.CompilerArguments) { result += string.Format(" {0}", arg); } // TODO factor out this code from here! if (file != null) { switch (file.Extension) { case ".c": { foreach (var arg in superProject.CCompilerArguments) { result += string.Format(" {0}", arg); } } break; case ".cpp": { foreach (var arg in superProject.CppCompilerArguments) { result += string.Format(" {0}", arg); } } break; } } return result; }
private int GetFileCount(IStandardProject project) { var result = 0; foreach (var reference in project.References) { var standardReference = reference as IStandardProject; if (standardReference != null) { result += GetFileCount(standardReference); } } if (!project.IsBuilding) { project.IsBuilding = true; result += project.SourceFiles.Where(sf => SupportsFile(sf)).Count(); } return result; }
public abstract CompileResult Compile(IConsole console, IStandardProject superProject, IStandardProject project, ISourceFile file, string outputFile);
public abstract ProcessResult Size(IConsole console, IStandardProject project, LinkResult linkResult);
public abstract string GetLinkerArguments(IStandardProject superProject, IStandardProject project);
private string GetLinkerScriptLocation(IStandardProject project) { return(Path.Combine(project.CurrentDirectory, "link.ld")); }
public abstract CompileResult Compile(IConsole console, IStandardProject superProject, IStandardProject project, ISourceFile file, string outputFile);
private async Task CompileProject(IConsole console, IStandardProject superProject, IStandardProject project, List <CompileResult> results = null) { if (project.Type == ProjectType.Executable && superProject != project) { if (project.ToolChain == null) { terminateBuild = true; console.WriteLine($"Project: {project.Name} does not have a toolchain set."); } await project.ToolChain?.BuildAsync(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 sourceFiles = project.SourceFiles.ToList(); _statusBar?.SetText($"Building Project: {project.Name}"); foreach (var file in sourceFiles) { if (terminateBuild) { break; } if (SupportsFile(file)) { var outputName = Path.ChangeExtension(file.Name, ".o"); var objectPath = Path.Combine(objDirectory, project.CurrentDirectory.MakeRelativePath(file.CurrentDirectory)); var objectFile = Path.Combine(objectPath, outputName); var dependencyFile = Path.ChangeExtension(objectFile, ".d"); if (!Directory.Exists(objectPath)) { Directory.CreateDirectory(objectPath); } var dependencyChanged = false; if (System.IO.File.Exists(dependencyFile)) { var dependencies = new List <string>(); dependencies.Add(file.Location); 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.Sleep(10); } lock (resultLock) { if (terminateBuild) { break; } numTasks++; } Task.Run(() => { var stringBuilderConsole = new StringBuilderConsole(); var compileResult = Compile(stringBuilderConsole, 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--; } console.OverWrite($"[CC {++buildCount}/{fileCount}] [{project.Name}] {file.Project.Location.MakeRelativePath(file.Location)}"); var output = stringBuilderConsole.GetOutput(); if (!string.IsNullOrEmpty(output)) { console.WriteLine(output); } }).GetAwaiter(); } else { buildCount++; compileResults.ObjectLocations.Add(objectFile); } } } _statusBar?.ClearText(); } } } }
public override CompileResult Compile(IConsole console, IStandardProject superProject, IStandardProject project, ISourceFile file, string outputFile) { var result = new CompileResult(); if (Path.GetExtension(file.FilePath) == ".cs") { CompileCS(console, superProject, project, file, outputFile); TransformMSIL(console, superProject, project, file, outputFile); CompileLLVMIR(console, superProject, project, file, outputFile + ".bc", outputFile); } else if (Path.GetExtension(file.FilePath) == ".cpp" || Path.GetExtension(file.FilePath) == ".c") { var startInfo = new ProcessStartInfo(); if (file.Extension == ".cpp") { startInfo.FileName = Path.Combine(BaseDirectory, "GCC\\bin", "arm-none-eabi-g++.exe"); } else { startInfo.FileName = Path.Combine(BaseDirectory, "GCC\\bin", "arm-none-eabi-gcc.exe"); } startInfo.WorkingDirectory = project.Solution.CurrentDirectory; if (Path.IsPathRooted(startInfo.FileName) && !System.IO.File.Exists(startInfo.FileName)) { result.ExitCode = -1; console.WriteLine("Unable to find compiler (" + startInfo.FileName + ") Please check project compiler settings."); } else { var fileArguments = string.Empty; if (file.Extension == ".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), 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 abstract string GetLinkerArguments(IStandardProject superProject, IStandardProject project);
private LinkResult Link(IConsole console, IStandardProject superProject, CompileResult compileResult, CompileResult linkResults, string label = "") { var binDirectory = compileResult.Project.GetBinDirectory(superProject); if (!Directory.Exists(binDirectory)) { Directory.CreateDirectory(binDirectory); } var outputLocation = binDirectory; var executable = Path.Combine(outputLocation, compileResult.Project.Name); if (!string.IsNullOrEmpty(label)) { executable += string.Format("-{0}", label); } if (compileResult.Project.Type == ProjectType.StaticLibrary) { executable = Path.Combine(outputLocation, "lib" + compileResult.Project.Name); executable += StaticLibraryExtension; } else { executable += ExecutableExtension; } if (!Directory.Exists(outputLocation)) { Directory.CreateDirectory(outputLocation); } var link = false; foreach (var objectFile in compileResult.ObjectLocations) { if (!System.IO.File.Exists(executable) || (System.IO.File.GetLastWriteTime(objectFile) > System.IO.File.GetLastWriteTime(executable))) { link = true; break; } } if (!link) { foreach (var library in compileResult.LibraryLocations) { if (!System.IO.File.Exists(executable) || (System.IO.File.GetLastWriteTime(library) > System.IO.File.GetLastWriteTime(executable))) { link = true; break; } } } var linkResult = new LinkResult { Executable = executable }; if (link) { _statusBar?.SetText($"Linking: {compileResult.Project.Name}"); console.OverWrite(string.Format("[LL] [{0}]", compileResult.Project.Name)); linkResult = Link(console, superProject, compileResult.Project, compileResult, executable); _statusBar?.ClearText(); } if (linkResult.ExitCode == 0) { if (compileResult.Project.Type == ProjectType.StaticLibrary) { if (compileResult.ObjectLocations.Count > 0) { // This is where we have a libray with just headers. linkResults.LibraryLocations.Add(executable); } } else { superProject.Executable = superProject.Location.MakeRelativePath(linkResult.Executable).ToAvalonPath(); superProject.Save(); console.WriteLine(); Size(console, compileResult.Project, linkResult); linkResults.ExecutableLocations.Add(executable); } } else if (linkResults.ExitCode == 0) { linkResults.ExitCode = linkResult.ExitCode; } return(linkResult); }
public abstract string GetCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile sourceFile);
public abstract ProcessResult Size(IConsole console, IStandardProject project, LinkResult linkResult);
public abstract LinkResult Link(IConsole console, IStandardProject superProject, IStandardProject project, CompileResult assemblies, string outputPath);
private string GetLinkerScriptLocation(IStandardProject project) { return Path.Combine(project.CurrentDirectory, "link.ld"); }
public string GetCSCCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile sourceFile) { return "/unsafe"; }
public override string GetBaseLibraryArguments(IStandardProject superProject) { return(string.Empty); }
public string GetZeligCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile sourceFile) { var result = string.Empty; result += string.Format("-HostAssemblyDir {0} ", Path.Combine(BaseDirectory, "Llilum\\ZeligBuild\\Host\\bin\\Debug")); result += string.Format("-DeviceAssemblyDir {0} ", Path.Combine(BaseDirectory, "Llilum\\ZeligBuild\\Target\\bin\\Debug")); result += string.Format("-CompilationSetupPath {0} ", Path.Combine(BaseDirectory, "Llilum\\ZeligBuild\\Host\\bin\\Debug\\Microsoft.Llilum.BoardConfigurations.STM32F411.dll")); result += "-CompilationSetup Microsoft.Llilum.BoardConfigurations.STM32F411MBEDHostedCompilationSetup "; result += "-Reference Microsoft.CortexM4OnMBED "; result += "-Reference Microsoft.CortexM4OnCMSISCore "; result += "-Reference DeviceModels.ModelForCortexM4 "; result += "-Reference STM32F411 "; result += "-Reference Microsoft.Zelig.LlilumCMSIS-RTOS "; result += "-Reference Microsoft.Zelig.Runtime "; result += "-CompilationPhaseDisabled InitializeReferenceCountingGarbageCollection "; result += "-CompilationPhaseDisabled EnableStrictReferenceCountingGarbageCollection "; result += "-CompilationPhaseDisabled ResourceManagerOptimizations "; result += "-CompilationPhaseDisabled PrepareExternalMethods "; result += "-CompilationPhaseDisabled MidLevelToLowLevelConversion "; result += "-CompilationPhaseDisabled ConvertUnsupportedOperatorsToMethodCalls "; result += "-CompilationPhaseDisabled ExpandAggregateTypes "; result += "-CompilationPhaseDisabled SplitComplexOperators "; result += "-CompilationPhaseDisabled FuseOperators "; result += "-CompilationPhaseDisabled ConvertToSSA "; result += "-CompilationPhaseDisabled PrepareForRegisterAllocation "; result += "-CompilationPhaseDisabled CollectRegisterAllocationConstraints "; result += "-CompilationPhaseDisabled AllocateRegisters "; result += "-DumpIR "; result += "-DumpLLVMIR "; result += "-MaxProcs 8 "; result += "-NoSDK "; result += string.Format("-LlvmBinPath {0} ", Path.Combine(BaseDirectory, "LLVM")); return result; }
public override string GetCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile file) { var result = string.Empty; var settings = superProject.GetToolchainSettings <GccToolchainSettings>(); result += "-Wall -c "; if (settings.CompileSettings.DebugInformation) { result += "-ggdb3 "; } if (file == null || file.Extension == ".cpp") { switch (settings.CompileSettings.CppLanguageStandard) { case CppLanguageStandard.Cpp98: result += "-std=c++98 "; break; case CppLanguageStandard.Cpp03: result += "-std=c++03 "; break; case CppLanguageStandard.Cpp11: result += "-std=c++11 "; break; case CppLanguageStandard.Cpp14: result += "-std=c++14 "; break; case CppLanguageStandard.Cpp17: result += "-std=c++17 "; break; case CppLanguageStandard.Gnu11: result += "-std=gnu++11 "; break; case CppLanguageStandard.Gnu14: result += "-std=gnu++14 "; break; default: break; } if (!settings.CompileSettings.Rtti) { result += "-fno-rtti "; } if (!settings.CompileSettings.Exceptions) { result += "-fno-exceptions "; } } if (file == null || file.Extension == ".c") { switch (settings.CompileSettings.CLanguageStandard) { case CLanguageStandard.C89: result += "-std=c89 "; break; case CLanguageStandard.C99: result += "-std=c99 "; break; case CLanguageStandard.C11: result += "-std=c11 "; break; } } switch (settings.CompileSettings.Fpu) { case FPUSupport.Soft: result += "-mfpu=fpv4-sp-d16 -mfloat-abi=softfp "; break; case FPUSupport.Hard: result += "-mfpu=fpv4-sp-d16 -mfloat-abi=hard "; break; } switch (settings.CompileSettings.Fpu) { case FPUSupport.Soft: { result += "-mfpu=fpv4-sp-d16 -mfloat-abi=softfp "; } break; case FPUSupport.Hard: { result += "-mfpu=fpv4-sp-d16 -mfloat-abi=hard "; } break; } // TODO make this an option. result += "-ffunction-sections -fdata-sections "; switch (settings.CompileSettings.Optimization) { case OptimizationLevel.None: { result += "-O0 "; } break; case OptimizationLevel.Debug: { result += "-O0 "; } break; case OptimizationLevel.Level1: { result += "-O1 "; } break; case OptimizationLevel.Level2: { result += "-O2 "; } break; case OptimizationLevel.Level3: { result += "-O3 "; } break; case OptimizationLevel.Size: { result += "-Os "; } break; case OptimizationLevel.Speed: { result += "-Ofast "; } break; } result += settings.CompileSettings.CustomFlags + " "; // Referenced includes var referencedIncludes = project.GetReferencedIncludes(); referencedIncludes.Select(s => result += $"-I\"{ Path.Combine(project.CurrentDirectory, s)}\" ").ToList(); // global includes var globalIncludes = superProject.GetGlobalIncludes(); globalIncludes.Select(s => result += $"-I\"{s}\" ").ToList(); // includes project.Includes.Select(s => result += $"-I\"{ Path.Combine(project.CurrentDirectory, s.Value)}\" ").ToList(); var referencedDefines = project.GetReferencedDefines(); referencedDefines.Select(s => result += $"-D{s} ").ToList(); var toolchainIncludes = GetToolchainIncludes(file); toolchainIncludes.Select(s => result += $"-isystem\"{s}\" ").ToList(); // global includes var globalDefines = superProject.GetGlobalDefines(); globalDefines.Select(s => result += $"-D{s} ").ToList(); project.Defines.Select(s => result += $"-D{s.Value} ").ToList(); superProject.ToolChainArguments.Select(s => result += $" {s}").ToList(); superProject.CompilerArguments.Select(s => result += $" {s}").ToList(); // TODO factor out this code from here! if (file != null) { switch (file.Extension) { case ".c": { superProject.CCompilerArguments.Select(s => result += $" {s}"); } break; case ".cpp": { superProject.CppCompilerArguments.Select(s => result += $" {s}"); } break; } } return(result); }
public override LinkResult Link(IConsole console, IStandardProject superProject, IStandardProject project, CompileResult assemblies, string outputDirectory) { var result = new LinkResult(); var startInfo = new ProcessStartInfo(); startInfo.FileName = Path.Combine(BaseDirectory, "GCC\\bin", "arm-none-eabi-gcc.exe"); if (project.Type == ProjectType.StaticLibrary) { startInfo.FileName = Path.Combine(BaseDirectory, "GCC\\bin", "arm-none-eabi-ar.exe"); } startInfo.WorkingDirectory = project.Solution.CurrentDirectory; if (Path.IsPathRooted(startInfo.FileName) && !System.IO.File.Exists(startInfo.FileName)) { result.ExitCode = -1; console.WriteLine("Unable to find linker executable (" + startInfo.FileName + ") Check project compiler settings."); return result; } // GenerateLinkerScript(project); var objectArguments = string.Empty; foreach (var obj in assemblies.ObjectLocations) { objectArguments += obj + " "; } var libs = string.Empty; foreach (var lib in assemblies.LibraryLocations) { libs += lib + " "; } if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); } var outputName = Path.GetFileNameWithoutExtension(project.Location) + ".elf"; if (project.Type == ProjectType.StaticLibrary) { outputName = "lib" + Path.GetFileNameWithoutExtension(project.Name) + ".a"; } var executable = Path.Combine(outputDirectory, outputName); var linkedLibraries = string.Empty; foreach (var libraryPath in project.StaticLibraries) { var relativePath = project.CurrentDirectory; var 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(superProject, 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 abstract LinkResult Link(IConsole console, IStandardProject superProject, IStandardProject project, CompileResult assemblies, string outputPath);
private LinkResult Link(IConsole console, IStandardProject superProject, CompileResult compileResult, CompileResult linkResults, string label = "") { var binDirectory = compileResult.Project.GetBinDirectory(superProject); if (!Directory.Exists(binDirectory)) { Directory.CreateDirectory(binDirectory); } var outputLocation = binDirectory; var executable = Path.Combine(outputLocation, compileResult.Project.Name); if (!string.IsNullOrEmpty(label)) { executable += string.Format("-{0}", label); } if (compileResult.Project.Type == ProjectType.StaticLibrary) { executable = Path.Combine(outputLocation, "lib" + compileResult.Project.Name); executable += StaticLibraryExtension; } else { executable += ExecutableExtension; } if (!Directory.Exists(outputLocation)) { Directory.CreateDirectory(outputLocation); } var link = false; foreach (var objectFile in compileResult.ObjectLocations) { if (System.IO.File.GetLastWriteTime(objectFile) > System.IO.File.GetLastWriteTime(executable)) { link = true; break; } } if (!link) { foreach (var library in compileResult.LibraryLocations) { if (System.IO.File.GetLastWriteTime(library) > System.IO.File.GetLastWriteTime(executable)) { link = true; break; } } } var linkResult = new LinkResult {Executable = executable}; if (link) { console.OverWrite(string.Format("[LL] [{0}]", compileResult.Project.Name)); linkResult = Link(console, superProject, compileResult.Project, compileResult, executable); } if (linkResult.ExitCode == 0) { if (compileResult.Project.Type == ProjectType.StaticLibrary) { if (compileResult.ObjectLocations.Count > 0) // This is where we have a libray with just headers. { linkResults.LibraryLocations.Add(executable); } } else { superProject.Executable = superProject.Location.MakeRelativePath(linkResult.Executable).ToAvalonPath(); superProject.Save(); console.WriteLine(); Size(console, compileResult.Project, linkResult); linkResults.ExecutableLocations.Add(executable); } } else if (linkResults.ExitCode == 0) { linkResults.ExitCode = linkResult.ExitCode; } return linkResult; }
public abstract string GetCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile sourceFile);
private async Task CleanAll(IConsole console, IStandardProject superProject, IStandardProject project) { foreach (var reference in project.References) { var loadedReference = reference as IStandardProject; if (loadedReference != null) { if (loadedReference.Type == ProjectType.Executable) { await CleanAll(console, loadedReference, loadedReference); } else { await CleanAll(console, superProject, loadedReference); } } } var outputDirectory = project.GetObjectDirectory(superProject); var 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 void ClearBuildFlags(IStandardProject project) { foreach (var reference in project.References) { var standardReference = reference as IStandardProject; if (standardReference != null) { ClearBuildFlags(standardReference); } } project.IsBuilding = false; }
public override string GetLinkerArguments(IStandardProject superProject, IStandardProject project) { var settings = GetSettings(project); if(superProject != null && project.Type != ProjectType.StaticLibrary) { GenerateLinkerScript(superProject); } var result = string.Empty; result += string.Format("{0} ", settings.LinkSettings.MiscLinkerArguments); switch (settings.CompileSettings.Fpu) { case FPUSupport.Soft: result += " -mfpu=fpv4-sp-d16 -mfloat-abi=softfp "; break; case FPUSupport.Hard: result += " -mfpu=fpv4-sp-d16 -mfloat-abi=hard "; break; } if (settings.LinkSettings.NotUseStandardStartupFiles) { result += "-nostartfiles "; } if (settings.LinkSettings.DiscardUnusedSections) { result += "-Wl,--gc-sections "; } switch (settings.CompileSettings.Optimization) { case OptimizationLevel.None: result += " -O0"; break; case OptimizationLevel.Level1: result += " -O1"; break; case OptimizationLevel.Level2: result += " -O2"; break; case OptimizationLevel.Level3: result += " -O3"; break; } result += string.Format(" -L{0} -Wl,-T\"{1}\"", project.CurrentDirectory, GetLinkerScriptLocation(project)); return result; }
private void SetFileCount(IStandardProject project) { ClearBuildFlags(project); fileCount = GetFileCount(project); ClearBuildFlags(project); }
public override string GetLinkerArguments(IStandardProject superProject, IStandardProject project) { var settings = project.GetToolchainSettings <GccToolchainSettings>(); var result = string.Empty; if (_gccConfig != null && _gccConfig.SystemLibraryPaths != null) { foreach (var libraryPath in _gccConfig.SystemLibraryPaths) { result += $"-Wl,-L\"{libraryPath}\" "; } } if (superProject != null && settings.LinkSettings.UseMemoryLayout && project.Type != ProjectType.StaticLibrary) { // GenerateLinkerScript(superProject); } result += string.Format("{0} ", settings.LinkSettings.MiscLinkerArguments); switch (settings.CompileSettings.Fpu) { case FPUSupport.Soft: result += " -mfpu=fpv4-sp-d16 -mfloat-abi=softfp "; break; case FPUSupport.Hard: result += " -mfpu=fpv4-sp-d16 -mfloat-abi=hard "; break; } if (settings.LinkSettings.NotUseStandardStartupFiles) { result += "-nostartfiles "; } if (settings.LinkSettings.DiscardUnusedSections) { result += "-Wl,--gc-sections "; } switch (settings.CompileSettings.Optimization) { case OptimizationLevel.None: result += " -O0"; break; case OptimizationLevel.Level1: result += " -O1"; break; case OptimizationLevel.Level2: result += " -O2"; break; case OptimizationLevel.Level3: result += " -O3"; break; } if (settings.LinkSettings.UseMemoryLayout) { result += string.Format(" -L{0} -Wl,-T\"{1}\"", project.CurrentDirectory, GetLinkerScriptLocation(project)); } return(result); }
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); } } } } } } }
public override ProcessResult Size(IConsole console, IStandardProject project, LinkResult linkResult) { var result = new ProcessResult(); var startInfo = new ProcessStartInfo(); startInfo.FileName = Path.Combine(BaseDirectory, "GCC\\bin", "arm-none-eabi-size.exe"); if (Path.IsPathRooted(startInfo.FileName) && !System.IO.File.Exists(startInfo.FileName)) { console.WriteLine("Unable to find tool (" + startInfo.FileName + ") check project compiler settings."); result.ExitCode = -1; return result; } startInfo.Arguments = string.Format("{0}", linkResult.Executable); // Hide console window startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.RedirectStandardInput = true; startInfo.CreateNoWindow = true; using (var process = Process.Start(startInfo)) { process.OutputDataReceived += (sender, e) => { console.WriteLine(e.Data); }; process.ErrorDataReceived += (sender, e) => { console.WriteLine(e.Data); }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); result.ExitCode = process.ExitCode; } return result; }
public string GetBuildDirectory(IStandardProject superProject) { return Path.Combine(GetOutputDirectory(superProject), "bin"); }
public override string GetLinkerArguments(IStandardProject superProject, IStandardProject project) { var result = string.Empty; foreach (var arg in project.ToolChainArguments) { result += string.Format(" {0}", arg); } foreach (var arg in project.LinkerArguments) { result += string.Format(" {0}", arg); } result += string.Format(" -L{0} -Wl,-T\"{1}\"", project.CurrentDirectory, "link.ld"); return result; }
public override string GetCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile file) { var result = string.Empty; //var settings = GetSettings(project).CompileSettings; var settings = GetSettings(superProject); result += "-Wall -c -fshort-enums "; if (settings.CompileSettings.DebugInformation) { result += "-ggdb3 "; } if (file == null || file.Extension == ".cpp") { switch (settings.CompileSettings.CppLanguageStandard) { case CppLanguageStandard.Cpp98: result += "-std=c++98 "; break; case CppLanguageStandard.Cpp03: result += "-std=c++03 "; break; case CppLanguageStandard.Cpp11: result += "-std=c++11 "; break; case CppLanguageStandard.Cpp14: result += "-std=c++14 "; break; case CppLanguageStandard.Cpp17: result += "-std=c++17 "; break; default: break; } } if (file == null || file.Extension == ".c") { switch (settings.CompileSettings.CLanguageStandard) { case CLanguageStandard.C89: result += "-std=c89 "; break; case CLanguageStandard.C99: result += "-std=c99 "; break; case CLanguageStandard.C11: result += "-std=c11 "; break; } } switch (settings.CompileSettings.Fpu) { case FPUSupport.Soft: result += "-mfpu=fpv4-sp-d16 -mfloat-abi=softfp "; break; case FPUSupport.Hard: result += "-mfpu=fpv4-sp-d16 -mfloat-abi=hard "; break; } // TODO remove dependency on file? if (file != null) { if (file.Extension == ".cpp") { if (!settings.CompileSettings.Rtti) { result += "-fno-rtti "; } if (!settings.CompileSettings.Exceptions) { result += "-fno-exceptions "; } } } switch (settings.CompileSettings.Fpu) { case FPUSupport.Soft: { result += "-mfpu=fpv4-sp-d16 -mfloat-abi=softfp "; } break; case FPUSupport.Hard: { result += "-mfpu=fpv4-sp-d16 -mfloat-abi=hard "; } break; } // TODO make this an option. result += "-ffunction-sections -fdata-sections "; switch (settings.CompileSettings.Optimization) { case OptimizationLevel.None: { result += "-O0 "; } break; case OptimizationLevel.Debug: { result += "-O2 "; } break; case OptimizationLevel.Level1: { result += "-O1 "; } break; case OptimizationLevel.Level2: { result += "-O2 "; } break; case OptimizationLevel.Level3: { result += "-O3 "; } break; } switch (settings.CompileSettings.OptimizationPreference) { case OptimizationPreference.Size: { result += "-Os "; } break; case OptimizationPreference.Speed: { result += "-Ofast "; } break; } result += settings.CompileSettings.CustomFlags + " "; // Referenced includes var referencedIncludes = project.GetReferencedIncludes(); foreach (var include in referencedIncludes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include)); } // global includes var globalIncludes = superProject.GetGlobalIncludes(); foreach (var include in globalIncludes) { result += string.Format("-I\"{0}\" ", include); } // public includes foreach (var include in project.PublicIncludes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include)); } // includes foreach (var include in project.Includes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include.Value)); } var referencedDefines = project.GetReferencedDefines(); foreach (var define in referencedDefines) { result += string.Format("-D{0} ", define); } var toolchainIncludes = GetToolchainIncludes(file); foreach (var include in toolchainIncludes) { result += string.Format("-isystem\"{0}\" ", include); } // global includes var globalDefines = superProject.GetGlobalDefines(); foreach (var define in globalDefines) { result += string.Format("-D{0} ", define); } foreach (var define in project.Defines) { result += string.Format("-D{0} ", define.Value); } foreach (var arg in superProject.ToolChainArguments) { result += string.Format(" {0}", arg); } foreach (var arg in superProject.CompilerArguments) { result += string.Format(" {0}", arg); } // TODO factor out this code from here! if (file != null) { switch (file.Extension) { case ".c": { foreach (var arg in superProject.CCompilerArguments) { result += string.Format(" {0}", arg); } } break; case ".cpp": { foreach (var arg in superProject.CppCompilerArguments) { result += string.Format(" {0}", arg); } } break; } } return result; }
private void TransformMSIL(IConsole console, IStandardProject superProject, IStandardProject project, ISourceFile file, string outputFile) { var startInfo = new ProcessStartInfo(); startInfo.FileName = Path.Combine(BaseDirectory, "Llilum\\ZeligBuild\\Host\\bin\\Debug", "Microsoft.Zelig.Compiler.exe"); if (Path.IsPathRooted(startInfo.FileName) && !System.IO.File.Exists(startInfo.FileName)) { console.WriteLine("Unable to find compiler (" + startInfo.FileName + ") Please check project compiler settings."); } else { //startInfo.WorkingDirectory = Path.Combine(BaseDirectory, "Llilum\\ZeligBuild\\Host\\bin\\Debug"); startInfo.Arguments = string.Format("{0} -OutputName {1} {2}", GetZeligCompilerArguments(superProject, project, file), outputFile, 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(); } } }
public override string GetBaseLibraryArguments(IStandardProject superProject) { return string.Empty; }
public static string GetBinDirectory(this IStandardProject project, IStandardProject superProject) { return Path.Combine(project.GetOutputDirectory(superProject), "bin"); }
public override string GetLinkerArguments(IStandardProject superProject, IStandardProject project) { var settings = GetSettings(project); var result = string.Empty; result += string.Format("-flto -static-libgcc -static-libstdc++ -Wl,-Map={0}.map ", Path.GetFileNameWithoutExtension(project.Name)); result += string.Format("{0} ", settings.LinkSettings.MiscLinkerArguments); if (settings.LinkSettings.DiscardUnusedSections) { result += "-Wl,--gc-sections "; } switch (settings.CompileSettings.Optimization) { case OptimizationLevel.None: result += " -O0"; break; case OptimizationLevel.Level1: result += " -O1"; break; case OptimizationLevel.Level2: result += " -O2"; break; case OptimizationLevel.Level3: result += " -O3"; break; } return result; }
public override string GetCompilerArguments(IStandardProject superProject, IStandardProject project, ISourceFile file) { var result = string.Empty; var settings = superProject.GetToolchainSettings <GccToolchainSettings>(); result += "-Wall -c "; if (settings.CompileSettings.DebugInformation) { result += "-g "; } // TODO make this an option. result += "-ffunction-sections -fdata-sections "; if (file == null || file.Extension == ".cpp") { switch (settings.CompileSettings.CppLanguageStandard) { case CppLanguageStandard.Cpp98: result += "-std=c++98 "; break; case CppLanguageStandard.Cpp03: result += "-std=c++03 "; break; case CppLanguageStandard.Cpp11: result += "-std=c++11 "; break; case CppLanguageStandard.Cpp14: result += "-std=c++14 "; break; case CppLanguageStandard.Cpp17: result += "-std=c++17 "; break; case CppLanguageStandard.Gnu11: result += "-std=gnu++11 "; break; case CppLanguageStandard.Gnu14: result += "-std=gnu++14 "; break; default: break; } if (!settings.CompileSettings.Rtti) { result += "-fno-rtti "; } if (!settings.CompileSettings.Exceptions) { result += "-fno-exceptions "; } } if (file == null || file.Extension == ".c") { switch (settings.CompileSettings.CLanguageStandard) { case CLanguageStandard.C89: result += "-std=c89 "; break; case CLanguageStandard.C99: result += "-std=c99 "; break; case CLanguageStandard.C11: result += "-std=c11 "; break; } } switch (settings.CompileSettings.Optimization) { case OptimizationLevel.None: { result += "-O0 "; } break; case OptimizationLevel.Debug: { result += "-Og "; } break; case OptimizationLevel.Level1: { result += "-O1 "; } break; case OptimizationLevel.Level2: { result += "-O2 "; } break; case OptimizationLevel.Level3: { result += "-O3 "; } break; case OptimizationLevel.Size: { result += "-Os "; } break; case OptimizationLevel.Speed: { result += "Ofast "; } break; } result += settings.CompileSettings.CustomFlags + " "; // toolchain includes // Referenced includes var referencedIncludes = project.GetReferencedIncludes(); foreach (var include in referencedIncludes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include)); } // global includes var globalIncludes = superProject.GetGlobalIncludes(); foreach (var include in globalIncludes) { result += string.Format("-I\"{0}\" ", include); } // includes foreach (var include in project.Includes) { result += string.Format("-I\"{0}\" ", Path.Combine(project.CurrentDirectory, include.Value)); } var referencedDefines = project.GetReferencedDefines(); foreach (var define in referencedDefines) { result += string.Format("-D{0} ", define); } // global includes var globalDefines = superProject.GetGlobalDefines(); foreach (var define in globalDefines) { result += string.Format("-D{0} ", define); } foreach (var define in project.Defines) { result += string.Format("-D{0} ", define.Value); } if (Platform.OSDescription == "Windows") { result += string.Format("-D{0} ", "WIN32NT"); } foreach (var arg in superProject.ToolChainArguments) { result += string.Format(" {0}", arg); } foreach (var arg in superProject.CompilerArguments) { result += string.Format(" {0}", arg); } // TODO factor out this code from here! if (file != null) { switch (file.Extension) { case ".c": { foreach (var arg in superProject.CCompilerArguments) { result += string.Format(" {0}", arg); } } break; case ".cpp": { foreach (var arg in superProject.CppCompilerArguments) { result += string.Format(" {0}", arg); } } break; } } return(result); }