StandaloneBSPValidator.Program.TestStatistics TestVendorSamplesAndUpdateReportAndDependencies(VendorSample[] samples, string sampleDirPath, VendorSamplePass pass, Predicate <VendorSample> keepDirectoryAfterSuccessfulBuild = null, double testProbability = 1, BSPValidationFlags validationFlags = BSPValidationFlags.None) { Console.WriteLine($"Building {samples.Length} samples..."); if (pass != VendorSamplePass.RelocatedBuild && pass != VendorSamplePass.InPlaceBuild) { throw new Exception("Invalid build pass: "******"test.log"))) { foreach (var vs in samples) { LoadedBSP.LoadedMCU mcu; try { var rgFilterID = new Regex(vs.DeviceID.Replace('x', '.').Replace("_DEBUG", "").Replace("_MBR", "").Replace("_S132", "").Replace("_S140", ""), RegexOptions.IgnoreCase); //We need to find the shortest MCU name that matches the mask (e.g. for CC3220S and CC3220SF we should pick CC3220S). mcu = BSP.MCUs.OrderBy(m => m.ExpandedMCU.ID.Length).Where(f => rgFilterID.IsMatch(f.ExpandedMCU.ID)).ToArray()?.First(); vs.DeviceID = mcu.ExpandedMCU.ID; } catch { logger.HandleError($"Could not find {vs.DeviceID} MCU , Project: {vs.UserFriendlyName} "); continue; } if (testProbability < 1 && rng.NextDouble() > testProbability) { samplesProcessed++; continue; } VendorSampleTestReport.Record record = _Report.ProvideEntryForSample(new VendorSampleID(vs)); string mcuDir = Path.Combine(outputDir, record.ID.ToString()); DateTime start = DateTime.Now; var thisSampleFlags = validationFlags; if (keepDirectoryAfterSuccessfulBuild?.Invoke(vs) == true) { thisSampleFlags |= BSPValidationFlags.KeepDirectoryAfterSuccessfulTest; } var result = StandaloneBSPValidator.Program.TestVendorSampleAndUpdateDependencies(mcu, vs, mcuDir, sampleDirPath, CodeRequiresDebugInfoFlag, thisSampleFlags); record.BuildDuration = (int)(DateTime.Now - start).TotalMilliseconds; record.TimeOfLastBuild = DateTime.Now; if (result.Result != StandaloneBSPValidator.Program.TestBuildResult.Succeeded) { StoreError(record, result.LogFile, pass); samplesFailed++; } else { record.BuildFailedExplicitly = false; record.LastSucceededPass = pass; } logger.LogSampleResult(record); samplesProcessed++; var timePerSample = (DateTime.Now - passStartTime).TotalMilliseconds / samplesProcessed; string displayedSampleName = record.ID.ToString(); int maxNameLength = 50; if (displayedSampleName.Length > maxNameLength) { displayedSampleName = displayedSampleName.Substring(0, maxNameLength - 3) + "..."; } List <KeyValuePair <string, string> > fields = new List <KeyValuePair <string, string> >(); fields.Add(new KeyValuePair <string, string>("Pass:"******"Current sample:", displayedSampleName)); fields.Add(new KeyValuePair <string, string>("Samples processed:", $"{samplesProcessed}/{sampleCount}")); fields.Add(new KeyValuePair <string, string>("Average time per sample:", $"{timePerSample:f0} msec")); fields.Add(new KeyValuePair <string, string>("Failed samples:", $"{samplesFailed}")); var remainingTime = TimeSpan.FromMilliseconds(timePerSample * (sampleCount - samplesProcessed)); fields.Add(new KeyValuePair <string, string>("ETA:", $"{remainingTime.Hours:d}:{remainingTime.Minutes:d2}:{remainingTime.Seconds:d2}")); Console.SetCursorPosition(0, line); OutputKeyValueList(fields); int maxWidth = Console.WindowWidth - 2; int progressWidth = (int)((double)maxWidth * samplesProcessed) / sampleCount; Console.WriteLine("[" + new string('#', progressWidth).PadRight(maxWidth) + "]"); } } return(new StandaloneBSPValidator.Program.TestStatistics { Passed = sampleCount - samplesFailed, Failed = samplesFailed }); }
public static TestResult TestSingleSample(LoadedBSP.LoadedSample sampleObj, LoadedBSP.LoadedMCU mcu, string testDirectory, TestedSample sample, DeviceParameterSet extraParameters, RegisterValidationParameters registerValidationParameters, BSPValidationFlags validationFlags = BSPValidationFlags.None) { CreateEmptyDirectoryForTestingMCU(testDirectory); var configuredMCU = new LoadedBSP.ConfiguredMCU(mcu, GetDefaultPropertyValues(mcu.ExpandedMCU.ConfigurableProperties)); if (configuredMCU.ExpandedMCU.FLASHSize == 0) { configuredMCU.Configuration["com.sysprogs.bspoptions.primary_memory"] = "sram"; } var configuredSample = new ConfiguredSample { Sample = sampleObj, Parameters = GetDefaultPropertyValues(sampleObj.Sample.ConfigurableProperties), Frameworks = (sampleObj.Sample.RequiredFrameworks == null) ? null : sampleObj.Sample.RequiredFrameworks.Select(fwId => { return(configuredMCU.BSP.BSP.Frameworks.First(fwO => fwO.ID == fwId || fwO.ClassID == fwId && fwO.IsCompatibleWithMCU(configuredMCU.ExpandedMCU.ID))); }).ToList(), FrameworkParameters = new Dictionary <string, string>(), }; ApplyConfiguration(configuredMCU.Configuration, extraParameters?.MCUConfiguration, sample.MCUConfiguration); var bspDict = configuredMCU.BuildSystemDictionary(default(SystemDirectories)); bspDict["PROJECTNAME"] = "test"; if (configuredSample.Frameworks != null) { foreach (var fw in configuredSample.Frameworks) { if (fw.AdditionalSystemVars != null) { foreach (var kv in fw.AdditionalSystemVars) { bspDict[kv.Key] = kv.Value; } } if (fw.ConfigurableProperties != null) { var defaultFwConfig = GetDefaultPropertyValues(fw.ConfigurableProperties); if (defaultFwConfig != null) { foreach (var kv in defaultFwConfig) { configuredSample.FrameworkParameters[kv.Key] = kv.Value; } } } } } if (sampleObj.Sample?.DefaultConfiguration?.Entries != null) { foreach (var kv in sampleObj.Sample.DefaultConfiguration.Entries) { configuredSample.FrameworkParameters[kv.Key] = kv.Value; } } ApplyConfiguration(configuredSample.FrameworkParameters, extraParameters?.FrameworkConfiguration, sample.FrameworkConfiguration); ApplyConfiguration(configuredSample.Parameters, extraParameters?.SampleConfiguration, sample.SampleConfiguration); Dictionary <string, bool> frameworkIDs = new Dictionary <string, bool>(); foreach (var fw in sampleObj.Sample.RequiredFrameworks ?? new string[0]) { frameworkIDs[fw] = true; } foreach (var fw in sample.AdditionalFrameworks ?? new string[0]) { frameworkIDs[fw] = true; } var prj = new GeneratedProject(testDirectory, configuredMCU, frameworkIDs.Keys.ToArray()) { DataSections = sample.DataSections }; prj.DoGenerateProjectFromEmbeddedSample(configuredSample, false, bspDict); prj.AddBSPFilesToProject(bspDict, configuredSample.FrameworkParameters, frameworkIDs); var flags = prj.GetToolFlags(bspDict, configuredSample.FrameworkParameters, frameworkIDs); // if(sampleObj.Sample.LinkerScript!=null) // flags.LinkerScript = sampleObj.Sample.LinkerScript; if (!string.IsNullOrEmpty(configuredSample.Sample.Sample.LinkerScript)) { flags.LinkerScript = VariableHelper.ExpandVariables(configuredSample.Sample.Sample.LinkerScript, bspDict, configuredSample.FrameworkParameters); } if (!string.IsNullOrEmpty(configuredSample.Sample.Sample.CLanguageStandard)) { flags.CFLAGS += $" -std={configuredSample.Sample.Sample.CLanguageStandard}"; } if (!string.IsNullOrEmpty(configuredSample.Sample.Sample.CPPLanguageStandard)) { flags.CXXFLAGS += $" -std={configuredSample.Sample.Sample.CPPLanguageStandard}"; } flags.COMMONFLAGS += " -save-temps "; Dictionary <string, bool> sourceExtensions = new Dictionary <string, bool>(StringComparer.InvariantCultureIgnoreCase); foreach (var ext in sample.SourceFileExtensions.Split(';')) { sourceExtensions[ext] = true; } Console.WriteLine("Building {0}...", Path.GetFileName(testDirectory)); return(BuildAndRunValidationJob(mcu, testDirectory, prj, flags, sourceExtensions, null, sample.ValidateRegisters ? registerValidationParameters : null, validationFlags)); }
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"))); }
public static TestResult TestVendorSampleAndUpdateDependencies(LoadedBSP.LoadedMCU mcu, VendorSample vs, string mcuDir, string sampleDirPath, bool codeRequiresDebugInfoFlag, BSPValidationFlags validationFlags) { if (Directory.Exists(mcuDir)) { Directory.Delete(mcuDir, true); } Directory.CreateDirectory(mcuDir); var configuredMCU = new LoadedBSP.ConfiguredMCU(mcu, GetDefaultPropertyValues(mcu.ExpandedMCU.ConfigurableProperties)); if (configuredMCU.ExpandedMCU.FLASHSize == 0) { configuredMCU.Configuration["com.sysprogs.bspoptions.primary_memory"] = "sram"; } var entries = vs.Configuration.MCUConfiguration?.Entries; if (entries != null) { foreach (var e in entries) { configuredMCU.Configuration[e.Key] = e.Value; } } var bspDict = configuredMCU.BuildSystemDictionary(default(SystemDirectories)); bspDict["PROJECTNAME"] = "test"; if (sampleDirPath != null) { bspDict["SYS:VSAMPLE_DIR"] = sampleDirPath; } var prj = new GeneratedProject(configuredMCU, vs, mcuDir, bspDict, vs.Configuration.Frameworks ?? new string[0]); var projectCfg = PropertyDictionary2.ReadPropertyDictionary(vs.Configuration.MCUConfiguration); var frameworkCfg = PropertyDictionary2.ReadPropertyDictionary(vs.Configuration.Configuration); foreach (var k in projectCfg.Keys) { bspDict[k] = projectCfg[k]; } var frameworkIDs = vs.Configuration.Frameworks?.ToDictionary(fw => fw, fw => true); prj.AddBSPFilesToProject(bspDict, frameworkCfg, frameworkIDs); var flags = prj.GetToolFlags(bspDict, frameworkCfg, frameworkIDs); if (flags.LinkerScript != null && !Path.IsPathRooted(flags.LinkerScript)) { flags.LinkerScript = Path.Combine(VariableHelper.ExpandVariables(vs.Path, bspDict, frameworkCfg), flags.LinkerScript).Replace('\\', '/'); } //ToolFlags flags = new ToolFlags { CXXFLAGS = " ", COMMONFLAGS = "-mcpu=cortex-m3 -mthumb", LDFLAGS = "-Wl,-gc-sections -Wl,-Map," + "test.map", CFLAGS = "-ffunction-sections -Os -MD" }; int idx = flags.CFLAGS.IndexOf("-std="); if (!string.IsNullOrEmpty(vs.CLanguageStandard)) { if (idx >= 0) { flags.CFLAGS += ' '; flags.CFLAGS = flags.CFLAGS.Remove(idx, flags.CFLAGS.IndexOf(' ', idx) - idx); } flags.CFLAGS += $" -std={vs.CLanguageStandard}"; } if (!string.IsNullOrEmpty(vs.CPPLanguageStandard)) { if (idx >= 0) { flags.CFLAGS += ' '; flags.CFLAGS = flags.CFLAGS.Remove(idx, flags.CFLAGS.IndexOf(' ', idx) - idx); } flags.CXXFLAGS += $" -std={vs.CPPLanguageStandard}"; } flags.CFLAGS += " -MD"; flags.CXXFLAGS += " -MD"; if (codeRequiresDebugInfoFlag) { flags.CFLAGS += " -ggdb"; flags.CXXFLAGS += " -ggdb"; } flags.IncludeDirectories = LoadedBSP.Combine(flags.IncludeDirectories, vs.IncludeDirectories).Distinct().ToArray(); flags.PreprocessorMacros = LoadedBSP.Combine(flags.PreprocessorMacros, vs.PreprocessorMacros); flags.LDFLAGS = flags.LDFLAGS + " " + vs.LDFLAGS; flags = LoadedBSP.ConfiguredMCU.ExpandToolFlags(flags, bspDict, null); Dictionary <string, bool> sourceExtensions = new Dictionary <string, bool>(StringComparer.InvariantCultureIgnoreCase); sourceExtensions.Add("c", true); sourceExtensions.Add("cpp", true); sourceExtensions.Add("s", true); return(BuildAndRunValidationJob(mcu, mcuDir, prj, flags, sourceExtensions, vs, null, validationFlags)); }