private static TestResult BuildAndRunValidationJob(LoadedBSP.LoadedMCU mcu, string mcuDir, bool validateRegisters, LoadedRenamingRule[] renameRules, GeneratedProject prj, ToolFlags flags, Dictionary <string, bool> sourceExtensions, string[] nonValidateReg, string[] UndefinedMacros, BSPEngine.VendorSample vendorSample = null) { BuildJob job = new BuildJob(); string prefix = string.Format("{0}\\{1}\\{2}-", mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, mcu.BSP.Toolchain.Toolchain.GNUTargetID); //esp32 if (flEsp32) { prefix = prefix.Replace('\\', '/'); } job.OtherTasks.Add(new BuildTask { Executable = prefix + "g++", Arguments = $"{flags.StartGroup} {flags.EffectiveLDFLAGS} $^ {flags.EndGroup} -o $@", AllInputs = prj.SourceFiles.Where(f => sourceExtensions.ContainsKey(Path.GetExtension(f).TrimStart('.'))) .Select(f => Path.ChangeExtension(Path.GetFileName(f), ".o")) .Concat(prj.SourceFiles.Where(f => f.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase))) .ToArray(), PrimaryOutput = "test.elf", }); job.OtherTasks.Add(new BuildTask { Executable = prefix + "objcopy", Arguments = "-O binary $< $@", AllInputs = new[] { "test.elf" }, PrimaryOutput = "test.bin", }); foreach (var sf in prj.SourceFiles) { var sfE = sf.Replace('\\', '/'); string ext = Path.GetExtension(sf); if (!sourceExtensions.ContainsKey(ext.TrimStart('.'))) { if (ext != ".txt" && ext != ".a" && ext != ".h") { Console.WriteLine($"#{sf} is not a recognized source file"); } } else { bool isCpp = ext.ToLower() != ".c"; string obj = Path.ChangeExtension(Path.GetFileName(sfE), ".o"); job.CompileTasks.Add(new BuildTask { PrimaryOutput = Path.ChangeExtension(Path.GetFileName(sfE), ".o"), AllInputs = new[] { sfE }, Executable = prefix + (isCpp ? "g++" : "gcc"), Arguments = $"-c $< { (isCpp ? "-std=gnu++11 ":" ")} {flags.GetEffectiveCFLAGS(isCpp, ToolFlags.FlagEscapingMode.ForMakefile)} -o {obj}".Replace('\\', '/').Replace("/\"", "\\\""), }); } } bool errorsFound = false; foreach (var g in job.CompileTasks.GroupBy(t => t.PrimaryOutput.ToLower())) { if (g.Count() > 1) { Console.WriteLine($"ERROR: {g.Key} corresponds to the following files:"); foreach (var f in g) { Console.WriteLine("\t" + f.AllInputs.FirstOrDefault()); } errorsFound = true; } } if (errorsFound) { throw new Exception("Multiple source files with the same name found"); } job.GenerateMakeFile(Path.Combine(mcuDir, "Makefile"), "test.bin"); if (!string.IsNullOrEmpty(mcu.MCUDefinitionFile) && validateRegisters) { string firstSrcFileInPrjDir = prj.SourceFiles.First(fn => Path.GetDirectoryName(fn) == mcuDir); InsertRegisterValidationCode(firstSrcFileInPrjDir, XmlTools.LoadObject <MCUDefinition>(mcu.MCUDefinitionFile), renameRules, nonValidateReg, UndefinedMacros); } Console.Write("Building {0}...", Path.GetFileName(mcuDir)); bool buildSucceeded; if (true) { var proc = Process.Start(new ProcessStartInfo("cmd.exe", "/c " + Path.Combine(mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, "make.exe") + " -j" + Environment.ProcessorCount + " > build.log 2>&1") { UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = mcuDir }); proc.WaitForExit(); buildSucceeded = proc.ExitCode == 0; } else { buildSucceeded = job.BuildFast(mcuDir, Environment.ProcessorCount); } bool success = false; string mapFile = Path.Combine(mcuDir, GeneratedProject.MapFileName); if (buildSucceeded && File.Exists(mapFile)) { success = File.ReadAllLines(Path.Combine(mcuDir, mapFile)).Where(l => RgMainMap.IsMatch(l)).Count() > 0; if (success) { string binFile = Path.Combine(mcuDir, "test.bin"); using (var fs = File.Open(binFile, FileMode.Open)) if (fs.Length < 512) { success = false; } } } if (!success) { return(TestResult.Failed); } if (vendorSample != null) { FillSampleDependenciesFromDepFiles(vendorSample, mcuDir); } Directory.Delete(mcuDir, true); return(TestResult.Succeeded); }
private static TestResult BuildAndRunValidationJob(LoadedBSP.LoadedMCU mcu, string mcuDir, bool validateRegisters, LoadedRenamingRule[] renameRules, GeneratedProject prj, ToolFlags flags, Dictionary<string, bool> sourceExtensions, string[] nonValidateReg, BSPEngine.VendorSample vendorSample = null) { BuildJob job = new BuildJob(); string prefix = string.Format("{0}\\{1}\\{2}-", mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, mcu.BSP.Toolchain.Toolchain.GNUTargetID); job.OtherTasks.Add(new BuildTask { Executable = prefix + "g++", Arguments = $"{flags.EffectiveLDFLAGS} $^ -o $@", AllInputs = prj.SourceFiles.Where(f => sourceExtensions.ContainsKey(Path.GetExtension(f).TrimStart('.'))) .Select(f => Path.ChangeExtension(Path.GetFileName(f), ".o")) .Concat(prj.SourceFiles.Where(f => f.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase))) .ToArray(), PrimaryOutput = "test.elf", }); job.OtherTasks.Add(new BuildTask { Executable = prefix + "objcopy", Arguments = "-O binary $< $@", AllInputs = new[] { "test.elf" }, PrimaryOutput = "test.bin", }); foreach (var sf in prj.SourceFiles) { string ext = Path.GetExtension(sf); if (!sourceExtensions.ContainsKey(ext.TrimStart('.'))) { if (ext != ".txt") Console.WriteLine($"#{sf} is not a recognized source file"); } else { bool isCpp = ext.ToLower() != ".c"; string obj = Path.ChangeExtension(Path.GetFileName(sf), ".o"); job.CompileTasks.Add(new BuildTask { PrimaryOutput = Path.ChangeExtension(Path.GetFileName(sf), ".o"), AllInputs = new[] { sf }, Executable = prefix + (isCpp ? "g++" : "gcc"), Arguments = $"-c $< {flags.GetEffectiveCFLAGS(isCpp)} -o {obj}", }); } } job.GenerateMakeFile(Path.Combine(mcuDir, "Makefile"), "test.bin"); if (!string.IsNullOrEmpty(mcu.MCUDefinitionFile) && validateRegisters) { string firstSrcFileInPrjDir = prj.SourceFiles.First(fn => Path.GetDirectoryName(fn) == mcuDir); InsertRegisterValidationCode(firstSrcFileInPrjDir, XmlTools.LoadObject<MCUDefinition>(mcu.MCUDefinitionFile), renameRules, nonValidateReg); } Console.Write("Building {0}...", Path.GetFileName(mcuDir)); bool buildSucceeded; if (false) { var proc = Process.Start(new ProcessStartInfo("cmd.exe", "/c " + Path.Combine(mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, "make.exe") + " -j" + Environment.ProcessorCount + " > build.log 2>&1") { UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = mcuDir }); proc.WaitForExit(); buildSucceeded = proc.ExitCode == 0; } else { buildSucceeded = job.BuildFast(mcuDir, Environment.ProcessorCount); } bool success = false; string mapFile = Path.Combine(mcuDir, GeneratedProject.MapFileName); if (buildSucceeded && File.Exists(mapFile)) { success = File.ReadAllLines(Path.Combine(mcuDir, mapFile)).Where(l => RgMainMap.IsMatch(l)).Count() > 0; if (success) { string binFile = Path.Combine(mcuDir, "test.bin"); using (var fs = File.Open(binFile, FileMode.Open)) if (fs.Length < 512) success = false; } } if (!success) return TestResult.Failed; if (vendorSample != null) { FillSampleDependenciesFromDepFiles(vendorSample, mcuDir); } Directory.Delete(mcuDir, true); return TestResult.Succeeded; }
private static TestResult BuildAndRunValidationJob(LoadedBSP.LoadedMCU mcu, string mcuDir, GeneratedProject prj, ToolFlags flags, Dictionary <string, bool> sourceExtensions, VendorSample vendorSample = null, RegisterValidationParameters registerValidationParameters = null, BSPValidationFlags validationFlags = BSPValidationFlags.None) { BuildJob job = new BuildJob(); string prefix = string.Format("{0}\\{1}\\{2}", mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, mcu.BSP.Toolchain.Toolchain.Prefix); foreach (var sf in prj.SourceFiles) { var sfE = sf.Replace('\\', '/'); string ext = Path.GetExtension(sf); if (!sourceExtensions.ContainsKey(ext.TrimStart('.'))) { if (ext != ".txt" && ext != ".a" && ext != ".h") { Console.WriteLine($"#{sf} is not a recognized source file"); } } else { bool isCpp = ext.ToLower() != ".c"; string obj = Path.ChangeExtension(Path.GetFileName(sfE), ".o"); job.CompileTasks.Add(new BuildTask { PrimaryOutput = Path.ChangeExtension(Path.GetFileName(sfE), ".o"), AllInputs = new[] { sfE }, Executable = prefix + (isCpp ? "g++" : "gcc"), Arguments = $"-c -o $@ $< { (isCpp ? "-std=gnu++11 " : " ")} {flags.GetEffectiveCFLAGS(isCpp, ToolchainSubtype.GCC, ToolFlags.FlagEscapingMode.ForMakefile)}".Replace('\\', '/').Replace("/\"", "\\\""), }); } } bool errorsFound = false; foreach (var g in job.CompileTasks.GroupBy(t => t.PrimaryOutput.ToLower())) { if (g.Count() > 1) { int i = 0; foreach (var j2 in g) { j2.AttachDisambiguationSuffix($"_{++i}"); } Console.WriteLine($"ERROR: {g.Key} corresponds to the following files:"); foreach (var f in g) { Console.WriteLine("\t" + f.AllInputs.FirstOrDefault()); } errorsFound = true; } } if (errorsFound && (validationFlags & BSPValidationFlags.ResolveNameCollisions) == BSPValidationFlags.None) { throw new Exception("Multiple source files with the same name found"); } job.OtherTasks.Add(new BuildTask { Executable = prefix + "g++", Arguments = $"{flags.StartGroup} {flags.EffectiveLDFLAGS} $^ {flags.EndGroup} -o $@", AllInputs = job.CompileTasks.Select(t => t.PrimaryOutput) .Concat(prj.SourceFiles.Where(f => f.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase))) .ToArray(), PrimaryOutput = "test.elf", }); job.OtherTasks.Add(new BuildTask { Executable = prefix + "objcopy", Arguments = "-O binary $< $@", AllInputs = new[] { "test.elf" }, PrimaryOutput = "test.bin", }); List <string> comments = new List <string>(); comments.Add("Original directory:" + vendorSample?.Path); comments.Add("Tool flags:"); comments.Add("\tInclude directories:"); foreach (var dir in flags.IncludeDirectories ?? new string[0]) { comments.Add("\t\t" + dir); } comments.Add("\tPreprocessor macros:"); foreach (var dir in flags.PreprocessorMacros ?? new string[0]) { comments.Add("\t\t" + dir); } comments.Add("\tLibrary directories:"); foreach (var dir in flags.AdditionalLibraryDirectories ?? new string[0]) { comments.Add("\t\t" + dir); } comments.Add("\tLibrary names:"); foreach (var dir in flags.AdditionalLibraries ?? new string[0]) { comments.Add("\t\t" + dir); } comments.Add("\tExtra linker inputs:"); foreach (var dir in flags.AdditionalLinkerInputs ?? new string[0]) { comments.Add("\t\t" + dir); } comments.Add("\tCFLAGS:" + flags.CFLAGS); comments.Add("\tCXXFLAGS:" + flags.CXXFLAGS); comments.Add("\tLDFLAGS:" + flags.LDFLAGS); comments.Add("\tCOMMONFLAGS:" + flags.COMMONFLAGS); job.GenerateMakeFile(Path.Combine(mcuDir, "Makefile"), "test.bin", comments, (validationFlags & BSPValidationFlags.ContinuePastCompilationErrors) != BSPValidationFlags.None); if (!string.IsNullOrEmpty(mcu.MCUDefinitionFile) && registerValidationParameters != null) { string firstSrcFileInPrjDir = prj.SourceFiles.First(fn => Path.GetDirectoryName(fn) == mcuDir); InsertRegisterValidationCode(firstSrcFileInPrjDir, XmlTools.LoadObject <MCUDefinition>(mcu.MCUDefinitionFile), registerValidationParameters); } bool buildSucceeded; if (true) { var proc = Process.Start(new ProcessStartInfo("cmd.exe", "/c " + Path.Combine(mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, "make.exe") + " -j" + Environment.ProcessorCount + " > build.log 2>&1") { UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = mcuDir }); proc.WaitForExit(); buildSucceeded = proc.ExitCode == 0; } else { buildSucceeded = job.BuildFast(mcuDir, Environment.ProcessorCount); } bool success = false; string mapFile = Path.Combine(mcuDir, GeneratedProject.MapFileName); if (buildSucceeded && File.Exists(mapFile)) { success = File.ReadAllLines(Path.Combine(mcuDir, mapFile)).Where(l => RgMainMap.IsMatch(l)).Count() > 0; if (success) { string binFile = Path.Combine(mcuDir, "test.bin"); using (var fs = File.Open(binFile, FileMode.Open)) if (fs.Length < 512) { success = false; } } } if (!success) { if (vendorSample != null) { vendorSample.AllDependencies = null; } return(new TestResult(TestBuildResult.Failed, Path.Combine(mcuDir, "build.log"))); } if (vendorSample != null) { vendorSample.AllDependencies = Directory.GetFiles(mcuDir, "*.d") .SelectMany(f => SplitDependencyFile(f).Where(t => !t.EndsWith(":"))) .Concat(prj.SourceFiles.SelectMany(sf => FindIncludedResources(vendorSample.Path, sf))) .Distinct() .ToArray(); } if ((validationFlags & BSPValidationFlags.KeepDirectoryAfterSuccessfulTest) == BSPValidationFlags.None) { Directory.Delete(mcuDir, true); } return(new TestResult(TestBuildResult.Succeeded, Path.Combine(mcuDir, "build.log"))); }