Exemplo n.º 1
0
        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));
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        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);
                }
            }
        }