void ConvertFrameworkIncludesFromAutoConditionedSubfoldersToConditionalFlags(List <EmbeddedFramework> frameworks, List <ConditionalToolFlags> condFlags) { foreach (var fw in frameworks) { if (!_FrameworkConditions.TryGetValue(fw.ID, out var frameworkConditions)) { continue; } Dictionary <string, List <string> > conditionalIncludes = new Dictionary <string, List <string> >(); var includeDirs = fw.AdditionalIncludeDirs.ToList(); for (int i = 0; i < includeDirs.Count; i++) { if (!includeDirs[i].StartsWith(frameworkConditions.TargetPath + "/")) { continue; } string firstComponent = includeDirs[i].Substring(frameworkConditions.TargetPath.Length).TrimStart('/'); int idx = firstComponent.IndexOf('/'); if (idx != -1) { firstComponent = firstComponent.Substring(0, idx); } if (frameworkConditions.ConditionalSubdirectories.Contains(firstComponent)) { if (!conditionalIncludes.TryGetValue(firstComponent, out var list)) { conditionalIncludes[firstComponent] = list = new List <string>(); } list.Add(includeDirs[i]); includeDirs.RemoveAt(i--); } } fw.AdditionalIncludeDirs = includeDirs.ToArray(); foreach (var kv in conditionalIncludes) { string prefix = frameworkConditions.TargetPath + "/" + kv.Key; var fileCondition = _Builder.MatchedFileConditions.FirstOrDefault(kv2 => kv2.Key.StartsWith(prefix + "/")).Value; if (fileCondition == null) { throw new Exception($"No file conditions start with '{prefix}'. Could not derive variable name for '{kv.Key}'."); } Condition.Equals conditionToInclude = fileCondition.ConditionToInclude as Condition.Equals; if (conditionToInclude == null) { //This is a generated condition for a library file (.a). conditionToInclude = (fileCondition.ConditionToInclude as Condition.And)?.Arguments?.LastOrDefault() as Condition.Equals; if (conditionToInclude == null) { throw new Exception("Failed to determine a condition to include " + prefix); } } condFlags.Add(new ConditionalToolFlags { FlagCondition = new Condition.And { Arguments = new Condition[] { new Condition.ReferencesFramework { FrameworkID = fw.ClassID ?? fw.ID }, conditionToInclude, } }, Flags = new ToolFlags { IncludeDirectories = kv.Value.ToArray() } }); var reverseConditions = _Builder.ReverseFileConditions?.GetHandleForFramework(fw); if (reverseConditions != null) { foreach (var dir in kv.Value) { reverseConditions.AttachIncludeDirectoryCondition(dir, reverseConditions.CreateSimpleCondition(conditionToInclude.Expression.Trim('$'), conditionToInclude.ExpectedValue)); } } } } }
private void GenerateConditionsForPrebuiltLibraries(FamilyDefinition family, Framework fw, CopyJob job) { var srcDir = Path.GetFullPath(_Builder.ExpandVariables(job.SourceFolder)); var allLibraries = Directory.GetFiles(srcDir, "*.a", SearchOption.AllDirectories) .Select(l => l.Substring(srcDir.Length).TrimStart('\\')).ToArray(); var conditions = new[] { new PrebuiltLibraryCondition("hard-float", "com.sysprogs.bspoptions.arm.floatmode", "-mfloat-abi=hard", "soft-float"), new PrebuiltLibraryCondition("no-interrupts", "com.sysprogs.bspoptions.nrf5x.interrupts", "no"), new PrebuiltLibraryCondition("short-wchar", "com.sysprogs.bspoptions.nrf5x.wchar", "-fshort-wchar"), }; Dictionary <string, PrebuiltLibraryCondition> conditionsByFolder = new Dictionary <string, PrebuiltLibraryCondition>(); foreach (var cond in conditions) { conditionsByFolder[cond.Folder] = cond; if (cond.InverseFolder != null) { conditionsByFolder[cond.InverseFolder] = cond; } } foreach (var grp in allLibraries.GroupBy(l => l.Substring(0, l.IndexOf('\\')), StringComparer.InvariantCultureIgnoreCase)) { HashSet <PrebuiltLibraryCondition> allConditionsInGroup = new HashSet <PrebuiltLibraryCondition>(); List <ConstructedLibraryCondition> libs = new List <ConstructedLibraryCondition>(); foreach (var lib in grp) { List <string> components = lib.Split('\\').ToList(); int libComponent = components.IndexOf("lib"); if (libComponent < 0) { throw new Exception($"Cannot build a list of conditional folders. {lib} does not contain 'lib' in the path."); } components.RemoveRange(0, libComponent + 1); string cortexPrefix = "cortex-"; if (!components[0].StartsWith(cortexPrefix)) { throw new Exception($"Relative path to {lib} does not start with 'cortex-'"); } string cortexCore = components[0].Substring(cortexPrefix.Length); components.RemoveAt(0); components.RemoveAt(components.Count - 1); foreach (var cmp in components) { if (!conditionsByFolder.TryGetValue(cmp, out var cond)) { throw new Exception($"Don't know how to map '{cmp}' to a prebuilt library condition"); } allConditionsInGroup.Add(cond); } libs.Add(new ConstructedLibraryCondition { Library = $"$$SYS:BSP_ROOT$$/{family.FamilySubdirectory}/{job.TargetFolder}/" + lib.Replace('\\', '/'), PathComponents = components.ToArray(), Core = cortexCore }); } foreach (var lib in libs) { List <Condition> finalConditions = new List <Condition>(); finalConditions.Add(new Condition.Equals { Expression = "$$com.sysprogs.bspoptions.nrf5x.cortex$$", ExpectedValue = lib.Core }); foreach (var usedCond in allConditionsInGroup) { var eqCond = new Condition.Equals { Expression = $"$${usedCond.Variable}$$", ExpectedValue = usedCond.Value }; if (lib.PathComponents.Contains(usedCond.Folder)) { finalConditions.Add(eqCond); } else { finalConditions.Add(new Condition.Not { Argument = eqCond }); } } FileCondition cond = new FileCondition { FilePath = lib.Library, ConditionToInclude = new Condition.And { Arguments = finalConditions.ToArray() } }; _Builder.AddFileCondition(cond); } } }