Example #1
0
            public Writer(RelationSchemaLoaderResult rslr, String Title, String CopyrightText)
            {
                this.Schema        = rslr.Schema;
                this.Title         = Title;
                this.CopyrightText = CopyrightText;

                TypeInfoDict = new Dictionary <String, TypeInfo>(StringComparer.OrdinalIgnoreCase);

                String Root = "";

                if (rslr.Positions.Count > 0)
                {
                    Func <String, String, String> GetCommonHead = (a, b) =>
                    {
                        var lc = new List <Char>();
                        var k  = 0;
                        while (true)
                        {
                            if (k >= a.Length || k >= b.Length)
                            {
                                break;
                            }
                            if (a[k] != b[k])
                            {
                                break;
                            }
                            lc.Add(a[k]);
                            k += 1;
                        }
                        return(new String(lc.ToArray()));
                    };
                    Root = rslr.Positions.Select(p => FileNameHandling.GetDirectoryPathWithTailingSeparator(FileNameHandling.GetFileDirectory(p.Value.Text.Path))).Aggregate((a, b) => GetCommonHead(a, b));
                    if (Root != FileNameHandling.GetDirectoryPathWithTailingSeparator(Root))
                    {
                        Root = FileNameHandling.GetFileDirectory(Root);
                    }
                }

                var Map = Schema.GetMap().ToDictionary(p => p.Key, p => p.Value);

                foreach (var t in Schema.Types)
                {
                    if (t.OnQueryList)
                    {
                        continue;
                    }
                    var Name = t.Name();
                    var Path = "Default.tree";
                    if (rslr.Positions.ContainsKey(t))
                    {
                        Path = FileNameHandling.GetRelativePath(rslr.Positions[t].Text.Path, Root);
                    }
                    var PathWithoutExt = FileNameHandling.GetPath(FileNameHandling.GetFileDirectory(Path), FileNameHandling.GetMainFileName(Path));
                    var DocFilePath    = PathWithoutExt.Replace(@"\", @"_").Replace(@"/", @"_").Replace(@".", "_").Replace(@":", @"_").Replace(@"#", @"_") + @".html";
                    var tli            = new TypeInfo {
                        Def = Map[Name], FriendlyPath = PathWithoutExt.Replace(@"\", @"/"), DocFilePath = DocFilePath, DocPath = String.Format("{0}#{1}", DocFilePath, Name)
                    };
                    TypeInfoDict.Add(Name, tli);
                }
            }
Example #2
0
        public static void GenerateCSharp(String InputDirectory, String OutputDirectory)
        {
            var Files = new Dictionary <String, FileParserResult>();

            foreach (var FilePath in Directory.EnumerateFiles(InputDirectory, "*.tree", SearchOption.AllDirectories))
            {
                var AbsolutePath = FileNameHandling.GetAbsolutePath(FilePath, System.Environment.CurrentDirectory);
                var FileContent  = Txt.ReadFile(FilePath);
                var Text         = TokenParser.BuildText(FileContent, AbsolutePath);
                var Result       = FileParser.ParseFile(Text);
                Files.Add(AbsolutePath, Result);
            }

            foreach (var p in Files)
            {
                var RelativePath = FileNameHandling.GetRelativePath(p.Key, FileNameHandling.GetAbsolutePath(InputDirectory, System.Environment.CurrentDirectory));
                var FileName     = FileNameHandling.GetFileName(p.Key);
                var ecsg         = new EmbeddedCSharpGenerator();
                var Content      = String.Join("\r\n", ecsg.Generate(p.Value.File).Select(Line => Line.TrimEnd(' ')));
                var OutputPath   = FileNameHandling.GetPath(FileNameHandling.GetPath(OutputDirectory, FileNameHandling.GetFileDirectory(RelativePath)), FileNameHandling.GetMainFileName(FileName) + ".cs");
                var OutputDir    = FileNameHandling.GetFileDirectory(OutputPath);
                if (!Directory.Exists(OutputDir))
                {
                    Directory.CreateDirectory(OutputDir);
                }
                WriteToFileIfChanged(OutputPath, Content);
            }
        }
Example #3
0
        public static void DumpSyntaxResult(String InputDirectory, String OutputDirectory)
        {
            var Files = new Dictionary <String, FileParserResult>();

            foreach (var FilePath in Directory.EnumerateFiles(InputDirectory, "*.tree", SearchOption.AllDirectories))
            {
                var AbsolutePath = FileNameHandling.GetAbsolutePath(FilePath, System.Environment.CurrentDirectory);
                var FileContent  = Txt.ReadFile(FilePath);
                var Text         = TokenParser.BuildText(FileContent, AbsolutePath);
                var Result       = FileParser.ParseFile(Text);
                Files.Add(AbsolutePath, Result);
            }

            //var arr = AmbiguousRemover.Reduce(Files, new List<String> { }, new TypeProvider());
            //if (arr.UnresolvableAmbiguousOrErrors.Count > 0)
            //{
            //    var l = new List<String> { };
            //    foreach (var p in arr.UnresolvableAmbiguousOrErrors)
            //    {
            //        var ErrorMessage = p.Key;
            //        var ErrorRange = p.Value;
            //        l.Add(p.Key + ": " + ErrorRange.Text.Path + (ErrorRange.Range.OnSome ? ": " + ErrorRange.Range.Value.ToString() : ""));
            //    }
            //    var OutputPath = FileNameHandling.GetPath(OutputDirectory, "Error.txt");
            //    var OutputDir = FileNameHandling.GetFileDirectory(OutputPath);
            //    if (!Directory.Exists(OutputDir)) { Directory.CreateDirectory(OutputDir); }
            //    Txt.WriteFile(OutputPath, String.Join("\r\n", l) + "\r\n");
            //    return;
            //}
            //Files = arr.Files;

            foreach (var p in Files)
            {
                var RelativePath = FileNameHandling.GetRelativePath(p.Key, FileNameHandling.GetAbsolutePath(InputDirectory, System.Environment.CurrentDirectory));
                var FileName     = FileNameHandling.GetFileName(p.Key);
                var fd           = new FileDumper();
                var Comment
                    = "==========================================================================" + "\r\n"
                      + "\r\n"
                      + "  SourceFile:  " + FileName + "\r\n"
                      + "\r\n"
                      + "==========================================================================";
                var f          = fd.Dump(p.Value, Comment);
                var OutputPath = FileNameHandling.GetPath(FileNameHandling.GetPath(OutputDirectory, FileNameHandling.GetFileDirectory(RelativePath)), FileNameHandling.GetMainFileName(FileName) + ".syn.tree");
                var OutputDir  = FileNameHandling.GetFileDirectory(OutputPath);
                if (!Directory.Exists(OutputDir))
                {
                    Directory.CreateDirectory(OutputDir);
                }
                TreeFile.WriteRaw(OutputPath, f);
            }
        }
Example #4
0
        private void GenerateVcxproj(bool EnableRebuild)
        {
            var VcxprojPath = Path.Combine(OutputDirectory, Project.Name + ".vcxproj");
            var BaseDirPath = Path.GetDirectoryName(Path.GetFullPath(VcxprojPath));

            var xVcxproj = XmlFile.FromString(VcxprojTemplateText);

            Trim(xVcxproj);

            var xn = xVcxproj.Name.Namespace;

            foreach (var ig in xVcxproj.Elements(xn + "ItemGroup").ToArray())
            {
                if (ig.Attribute("Label") != null)
                {
                    continue;
                }

                var None             = ig.Elements().Where(e => e.Name == xn + "None").ToArray();
                var ClInclude        = ig.Elements().Where(e => e.Name == xn + "ClInclude").ToArray();
                var ClCompile        = ig.Elements().Where(e => e.Name == xn + "ClCompile").ToArray();
                var ProjectReference = ig.Elements().Where(e => e.Name == xn + "ProjectReference").ToArray();
                foreach (var e in None)
                {
                    e.Remove();
                }
                foreach (var e in ClInclude)
                {
                    e.Remove();
                }
                foreach (var e in ClCompile)
                {
                    e.Remove();
                }
                foreach (var e in ProjectReference)
                {
                    e.Remove();
                }
                if (!ig.HasElements && !ig.HasAttributes)
                {
                    ig.Remove();
                }
            }

            var GlobalsPropertyGroup = xVcxproj.Elements(xn + "PropertyGroup").Where(e => e.Attribute("Label") != null && e.Attribute("Label").Value == "Globals").FirstOrDefault();

            if (GlobalsPropertyGroup == null)
            {
                GlobalsPropertyGroup = new XElement(xn + "PropertyGroup", new XAttribute("Label", "Globals"));
                xVcxproj.Add(GlobalsPropertyGroup);
            }
            var g = "{" + ProjectId.ToUpper() + "}";

            GlobalsPropertyGroup.SetElementValue(xn + "ProjectGuid", g);
            GlobalsPropertyGroup.SetElementValue(xn + "RootNamespace", Project.Name);

            var ExistingConfigurationTypeAndArchitectures = new Dictionary <KeyValuePair <ConfigurationType, ArchitectureType>, String>();
            var ProjectConfigurations = xVcxproj.Elements(xn + "ItemGroup").Where(e => (e.Attribute("Label") != null) && (e.Attribute("Label").Value == "ProjectConfigurations")).SelectMany(e => e.Elements(xn + "ProjectConfiguration")).Select(e => e.Element(xn + "Configuration").Value + "|" + e.Element(xn + "Platform").Value).ToDictionary(s => s);

            foreach (var Architecture in Enum.GetValues(typeof(ArchitectureType)).Cast <ArchitectureType>())
            {
                foreach (var ConfigurationType in Enum.GetValues(typeof(ConfigurationType)).Cast <ConfigurationType>())
                {
                    var Name = ConfigurationType.ToString() + "|" + GetArchitectureString(Architecture);
                    if (ProjectConfigurations.ContainsKey(Name))
                    {
                        ExistingConfigurationTypeAndArchitectures.Add(new KeyValuePair <ConfigurationType, ArchitectureType>(ConfigurationType, Architecture), Name);
                    }
                }
            }

            foreach (var Pair in ExistingConfigurationTypeAndArchitectures)
            {
                var ConfigurationType = Pair.Key.Key;
                var Architecture      = Pair.Key.Value;
                var Name = Pair.Value;

                var conf = ConfigurationUtils.GetMergedConfiguration(ToolchainType.Windows_VisualC, CompilerType.VisualC, BuildingOperatingSystem, TargetOperatingSystem, ConfigurationType, Architecture, Project.Configurations);

                var PropertyGroup = xVcxproj.Elements(xn + "PropertyGroup").Where(e => (e.Attribute("Condition") != null) && (e.Attribute("Condition").Value == "'$(Configuration)|$(Platform)'=='" + Name + "'")).LastOrDefault();
                if (PropertyGroup == null)
                {
                    PropertyGroup = new XElement(xn + "PropertyGroup", new XAttribute("Condition", "'$(Configuration)|$(Platform)'=='" + Name + "'"));
                }

                if (conf.TargetType == TargetType.Executable)
                {
                    PropertyGroup.SetElementValue(xn + "ConfigurationType", "Application");
                }
                else if (conf.TargetType == TargetType.StaticLibrary)
                {
                    PropertyGroup.SetElementValue(xn + "ConfigurationType", "StaticLibrary");
                }
                else if (conf.TargetType == TargetType.DynamicLibrary)
                {
                    PropertyGroup.SetElementValue(xn + "ConfigurationType", "DynamicLibrary");
                }
                else
                {
                    throw new NotSupportedException("NotSupportedTargetType: " + conf.TargetType.ToString());
                }

                var ItemDefinitionGroup = xVcxproj.Elements(xn + "ItemDefinitionGroup").Where(e => (e.Attribute("Condition") != null) && (e.Attribute("Condition").Value == "'$(Configuration)|$(Platform)'=='" + Name + "'")).LastOrDefault();
                if (ItemDefinitionGroup == null)
                {
                    ItemDefinitionGroup = new XElement(xn + "ItemDefinitionGroup", new XAttribute("Condition", "'$(Configuration)|$(Platform)'=='" + Name + "'"));
                    xVcxproj.Add(ItemDefinitionGroup);
                }
                var ClCompile = ItemDefinitionGroup.Element(xn + "ClCompile");
                if (ClCompile == null)
                {
                    ClCompile = new XElement(xn + "ClCompile");
                    ItemDefinitionGroup.Add(ClCompile);
                }
                var IncludeDirectories = conf.IncludeDirectories.Select(d => FileNameHandling.GetRelativePath(d, BaseDirPath)).ToList();
                if (IncludeDirectories.Count != 0)
                {
                    ClCompile.SetElementValue(xn + "AdditionalIncludeDirectories", String.Join(";", IncludeDirectories) + ";%(AdditionalIncludeDirectories)");
                }
                var Defines = conf.Defines;
                if (Defines.Count != 0)
                {
                    ClCompile.SetElementValue(xn + "PreprocessorDefinitions", String.Join(";", Defines.Select(d => d.Key + (d.Value == null ? "" : "=" + (Regex.IsMatch(d.Value, @"^[0-9]+$") ? d.Value : "\"" + d.Value.Replace("\"", "\"\"") + "\"")))) + ";%(PreprocessorDefinitions)");
                }
                var CompilerFlags = conf.CFlags.Concat(conf.CppFlags).ToList();
                if (CompilerFlags.Count != 0)
                {
                    ClCompile.SetElementValue(xn + "AdditionalOptions", "%(AdditionalOptions) " + String.Join(" ", CompilerFlags.Select(f => (f == null ? "" : Regex.IsMatch(f, @"^[0-9]+$") ? f : "\"" + f.Replace("\"", "\"\"") + "\""))));
                }

                if ((conf.TargetType == TargetType.Executable) || (conf.TargetType == TargetType.DynamicLibrary))
                {
                    var Link = ItemDefinitionGroup.Element(xn + "Link");
                    if (Link == null)
                    {
                        Link = new XElement(xn + "Link");
                        ItemDefinitionGroup.Add(ClCompile);
                    }
                    var LibDirectories = conf.LibDirectories.Select(d => FileNameHandling.GetRelativePath(d, BaseDirPath)).ToList();
                    if (LibDirectories.Count != 0)
                    {
                        Link.SetElementValue(xn + "AdditionalLibraryDirectories", String.Join(";", LibDirectories) + ";%(AdditionalLibraryDirectories)");
                    }
                    var Libs = conf.Libs.Concat(ProjectReferences.Select(p => p.Name + ".lib")).ToList();
                    if (Libs.Count != 0)
                    {
                        Link.SetElementValue(xn + "AdditionalDependencies", String.Join(";", Libs) + ";%(AdditionalDependencies)");
                    }
                    var LinkerFlags = conf.LinkerFlags.ToList();
                    if (LinkerFlags.Count != 0)
                    {
                        ClCompile.SetElementValue(xn + "AdditionalOptions", "%(AdditionalOptions) " + String.Join(" ", LinkerFlags.Select(f => (f == null ? "" : Regex.IsMatch(f, @"^[0-9]+$") ? f : "\"" + f.Replace("\"", "\"\"") + "\""))));
                    }
                }
            }

            var Import = xVcxproj.Elements(xn + "Import").LastOrDefault();

            foreach (var conf in Project.Configurations)
            {
                var FileItemGroup = new XElement(xn + "ItemGroup");
                if (Import != null)
                {
                    Import.AddBeforeSelf(FileItemGroup);
                }
                else
                {
                    xVcxproj.Add(FileItemGroup);
                }
                if ((conf.ConfigurationType != null) || (conf.Architecture != null))
                {
                    var Keys   = new List <String> {
                    };
                    var Values = new List <String> {
                    };
                    if (conf.ConfigurationType != null)
                    {
                        Keys.Add("$(Configuration)");
                        Values.Add(conf.ConfigurationType.ToString());
                    }
                    if (conf.Architecture != null)
                    {
                        Keys.Add("$(Platform)");
                        Values.Add(GetArchitectureString(conf.Architecture.Value));
                    }
                    var Condition = "'" + String.Join("|", Keys) + "' == '" + String.Join("|", Values) + "'";
                    FileItemGroup.Add(new XAttribute("Condition", Condition));
                }
                foreach (var f in conf.Files)
                {
                    var      RelativePath = FileNameHandling.GetRelativePath(f.Path, BaseDirPath);
                    XElement x;
                    if (f.Type == FileType.Header)
                    {
                        x = new XElement(xn + "ClInclude", new XAttribute("Include", RelativePath));
                    }
                    else if (f.Type == FileType.CSource)
                    {
                        x = new XElement(xn + "ClCompile", new XAttribute("Include", RelativePath));
                    }
                    else if (f.Type == FileType.CppSource)
                    {
                        x = new XElement(xn + "ClCompile", new XAttribute("Include", RelativePath));
                        x.Add(new XElement(xn + "ObjectFileName", "$(IntDir)" + RelativePath.Replace("..", "__") + ".obj"));
                    }
                    else
                    {
                        x = new XElement(xn + "None", new XAttribute("Include", RelativePath));
                    }
                    FileItemGroup.Add(x);
                }
                if (!FileItemGroup.HasElements)
                {
                    FileItemGroup.Remove();
                }
            }

            var ProjectItemGroup = new XElement(xn + "ItemGroup");

            if (Import != null)
            {
                Import.AddBeforeSelf(ProjectItemGroup);
            }
            else
            {
                xVcxproj.Add(ProjectItemGroup);
            }
            foreach (var p in ProjectReferences)
            {
                var RelativePath = FileNameHandling.GetRelativePath(p.FilePath, BaseDirPath);
                var x            = new XElement(xn + "ProjectReference", new XAttribute("Include", RelativePath));
                x.Add(new XElement(xn + "Project", "{" + p.Id.ToUpper() + "}"));
                x.Add(new XElement(xn + "Name", "{" + p.Name + "}"));
                ProjectItemGroup.Add(x);
            }
            if (!ProjectItemGroup.HasElements)
            {
                ProjectItemGroup.Remove();
            }

            var sVcxproj = XmlFile.ToString(xVcxproj);

            TextFile.WriteToFile(VcxprojPath, sVcxproj, Encoding.UTF8, !EnableRebuild);
        }
Example #5
0
        private void GenerateVcxprojFilters(bool EnableRebuild)
        {
            var FilterPath  = Path.Combine(OutputDirectory, Project.Name + ".vcxproj") + ".filters";
            var BaseDirPath = Path.GetDirectoryName(Path.GetFullPath(FilterPath));

            var xFilter = XmlFile.FromString(VcxprojFilterTemplateText);

            Trim(xFilter);

            var xn = xFilter.Name.Namespace;

            foreach (var ig in xFilter.Elements(xn + "ItemGroup").ToArray())
            {
                if (ig.Attribute("Label") != null)
                {
                    continue;
                }

                var None      = ig.Elements().Where(e => e.Name == xn + "None").ToArray();
                var ClInclude = ig.Elements().Where(e => e.Name == xn + "ClInclude").ToArray();
                var ClCompile = ig.Elements().Where(e => e.Name == xn + "ClCompile").ToArray();
                var Filter    = ig.Elements().Where(e => e.Name == xn + "Filter").ToArray();
                foreach (var e in None)
                {
                    e.Remove();
                }
                foreach (var e in ClInclude)
                {
                    e.Remove();
                }
                foreach (var e in ClCompile)
                {
                    e.Remove();
                }
                foreach (var e in Filter)
                {
                    e.Remove();
                }
                if (!ig.HasElements && !ig.HasAttributes)
                {
                    ig.Remove();
                }
            }

            var FilterItemGroup = new XElement(xn + "ItemGroup");
            var FileItemGroup   = new XElement(xn + "ItemGroup");

            xFilter.Add(FilterItemGroup);
            xFilter.Add(FileItemGroup);

            var Files   = new HashSet <String>(StringComparer.OrdinalIgnoreCase);
            var Filters = new HashSet <String>(StringComparer.OrdinalIgnoreCase);

            foreach (var conf in Project.Configurations)
            {
                foreach (var f in conf.Files)
                {
                    if (Files.Contains(f.Path))
                    {
                        continue;
                    }
                    Files.Add(f.Path);

                    var RelativePath = FileNameHandling.GetRelativePath(f.Path, BaseDirPath);
                    var Dir          = Path.GetDirectoryName(FileNameHandling.GetRelativePath(f.Path, InputDirectory)).Replace('/', '\\');
                    while (Dir.StartsWith(@"..\"))
                    {
                        Dir = Dir.Substring(3);
                    }
                    if (!Filters.Contains(Dir))
                    {
                        var CurrentDir = Dir;
                        while (CurrentDir != "" && !Filters.Contains(CurrentDir))
                        {
                            Filters.Add(CurrentDir);
                            CurrentDir = Path.GetDirectoryName(CurrentDir);
                        }
                    }

                    XElement x;
                    if (f.Type == FileType.Header)
                    {
                        x = new XElement(xn + "ClInclude", new XAttribute("Include", RelativePath));
                    }
                    else if (f.Type == FileType.CSource)
                    {
                        x = new XElement(xn + "ClCompile", new XAttribute("Include", RelativePath));
                    }
                    else if (f.Type == FileType.CppSource)
                    {
                        x = new XElement(xn + "ClCompile", new XAttribute("Include", RelativePath));
                    }
                    else
                    {
                        x = new XElement(xn + "None", new XAttribute("Include", RelativePath));
                    }
                    x.Add(new XElement(xn + "Filter", Dir));
                    FileItemGroup.Add(x);
                }
            }

            foreach (var f in Filters.OrderBy(ff => ff, StringComparer.OrdinalIgnoreCase))
            {
                if (f == "")
                {
                    continue;
                }

                var g = "{" + Guid.NewGuid().ToString().ToUpper() + "}";
                FilterItemGroup.Add(new XElement(xn + "Filter", new XAttribute("Include", f), new XElement(xn + "UniqueIdentifier", g)));
            }

            if (!FilterItemGroup.HasElements)
            {
                FilterItemGroup.Remove();
            }
            if (!FileItemGroup.HasElements)
            {
                FileItemGroup.Remove();
            }

            var sFilter = XmlFile.ToString(xFilter);

            TextFile.WriteToFile(FilterPath, sFilter, Encoding.UTF8, !EnableRebuild);
        }
Example #6
0
        private IEnumerable <String> GenerateLines(String CMakeListsPath, String BaseDirPath)
        {
            var conf = ConfigurationUtils.GetMergedConfiguration(Toolchain, Compiler, BuildingOperatingSystem, TargetOperatingSystem, null, null, Project.Configurations);

            yield return(@"cmake_minimum_required(VERSION 3.0.2)");

            yield return($@"project({Project.Name})");

            if ((conf.TargetType == TargetType.Executable) || (conf.TargetType == TargetType.DynamicLibrary))
            {
                var LibDirectories = conf.LibDirectories.Select(d => FileNameHandling.GetRelativePath(d, BaseDirPath).Replace('\\', '/')).ToList();
                if (LibDirectories.Count != 0)
                {
                    yield return(@"link_directories(");

                    foreach (var d in LibDirectories)
                    {
                        yield return("  " + (d.Contains(" ") ? "\"" + d + "\"" : d));
                    }
                    yield return(@")");
                }
            }

            if (conf.TargetType == TargetType.Executable)
            {
                yield return(@"add_executable(${PROJECT_NAME} """")");
            }
            else if (conf.TargetType == TargetType.StaticLibrary)
            {
                yield return(@"add_library(${PROJECT_NAME} STATIC """")");
            }
            else if (conf.TargetType == TargetType.DynamicLibrary)
            {
                yield return(@"add_library(${PROJECT_NAME} SHARED """")");
            }
            else
            {
                throw new NotSupportedException("NotSupportedTargetType: " + conf.TargetType.ToString());
            }

            yield return(@"target_sources(${PROJECT_NAME} PRIVATE");

            foreach (var f in conf.Files)
            {
                if ((f.Type == FileType.CSource) || (f.Type == FileType.CppSource) || (f.Type == FileType.ObjectiveCSource) || (f.Type == FileType.ObjectiveCppSource))
                {
                    yield return("  " + FileNameHandling.GetRelativePath(f.Path, BaseDirPath).Replace('\\', '/'));
                }
            }
            yield return(@")");

            foreach (var g in conf.Files.GroupBy(f => Path.GetDirectoryName(f.Path)))
            {
                var Name = FileNameHandling.GetRelativePath(g.Key, InputDirectory);
                yield return($@"source_group({Name.Replace('\\', '/').Replace("/", @"\\")} FILES");

                foreach (var f in g)
                {
                    yield return("  " + FileNameHandling.GetRelativePath(f.Path, BaseDirPath).Replace('\\', '/'));
                }
                yield return(@")");
            }

            var IncludeDirectories = conf.IncludeDirectories.Select(d => FileNameHandling.GetRelativePath(d, BaseDirPath).Replace('\\', '/')).ToList();

            if (IncludeDirectories.Count != 0)
            {
                yield return(@"target_include_directories(${PROJECT_NAME} PRIVATE");

                foreach (var d in IncludeDirectories)
                {
                    yield return("  " + (d.Contains(" ") ? "\"" + d + "\"" : d));
                }
                yield return(@")");
            }
            var Defines = conf.Defines;

            if (Defines.Count != 0)
            {
                yield return(@"target_compile_definitions(${PROJECT_NAME} PRIVATE");

                foreach (var d in Defines)
                {
                    yield return(@"  -D" + d.Key + (d.Value == null ? "" : "=" + (Regex.IsMatch(d.Value, @"["" ^|]") ? "\"" + d.Value.Replace("\"", "\"\"") + "\"" : d.Value)));
                }
                yield return(@")");
            }
            var CFlags     = conf.CFlags;
            var CppFlags   = conf.CppFlags;
            var CFlagStr   = String.Join("", CFlags.Select(f => (f == null ? "" : Regex.IsMatch(f, @"[ ""^|]") ? "\"" + f.Replace("\"", "\"\"") + "\"" : f)));
            var CppFlagStr = String.Join("", CppFlags.Select(f => (f == null ? "" : Regex.IsMatch(f, @"[ ""^|]") ? "\"" + f.Replace("\"", "\"\"") + "\"" : f)));

            if (CFlags.Count + CppFlags.Count != 0)
            {
                yield return(@"target_compile_options(${PROJECT_NAME} PRIVATE " + CFlagStr + (CppFlags.Count > 0 ? "$<$<COMPILE_LANGUAGE:CXX>:" + CppFlagStr + ">" : "") + ")");
            }

            if ((conf.TargetType == TargetType.Executable) || (conf.TargetType == TargetType.DynamicLibrary))
            {
                var LinkerFlags = conf.LinkerFlags;
                if (LinkerFlags.Count != 0)
                {
                    var LinkerFlagStr = String.Join("", CFlags.Select(f => (f == null ? "" : Regex.IsMatch(f, @"[ ""^|]") ? "\"" + f.Replace("\"", "\"\"") + "\"" : f)));
                    yield return(@"set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS " + LinkerFlagStr + ")");
                }

                if (ProjectReferences.Count + conf.Libs.Count > 0)
                {
                    yield return(@"target_link_libraries(${PROJECT_NAME} PRIVATE");

                    foreach (var p in ProjectReferences)
                    {
                        yield return("  " + p.Name);
                    }
                    foreach (var lib in conf.Libs)
                    {
                        yield return("  " + lib);
                    }
                    yield return(@")");
                }
            }

            yield return("");
        }
Example #7
0
        public void Generate(bool EnableRebuild)
        {
            var PbxprojPath = Path.Combine(OutputDirectory, Path.Combine(Project.Name + ".xcodeproj", "project.pbxproj"));
            var BaseDirPath = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetFullPath(PbxprojPath)));

            var p = Plist.FromString(PbxprojTemplateText);

            var Objects       = p.Dict["objects"].Dict;
            var RootObjectKey = p.Dict["rootObject"].String;
            var RootObject    = Objects[RootObjectKey].Dict;

            ObjectReferenceValidityTest(Objects, RootObjectKey);

            RemoveFiles(Objects, RootObject["mainGroup"].String);

            var Targets = RootObject["targets"].Array;

            foreach (var TargetKey in Targets)
            {
                foreach (var PhaseKey in Objects[TargetKey.String].Dict["buildPhases"].Array)
                {
                    var Phase = Objects[PhaseKey.String].Dict;
                    var Type  = Phase["isa"].String;
                    if (Type == "PBXSourcesBuildPhase")
                    {
                        var Files       = Phase["files"];
                        var ToBeRemoved = new HashSet <String>();
                        foreach (var FileKey in Files.Array)
                        {
                            var File     = Objects[FileKey.String].Dict;
                            var FileType = File["isa"].String;
                            if (FileType == "PBXBuildFile")
                            {
                                var FileRef = File["fileRef"].String;
                                if (!Objects.ContainsKey(FileRef))
                                {
                                    ToBeRemoved.Add(FileKey.String);
                                    Objects.Remove(FileKey.String);
                                }
                            }
                        }
                        if (ToBeRemoved.Count > 0)
                        {
                            Files.Array = Files.Array.Where(FileKey => !ToBeRemoved.Contains(FileKey.String)).ToList();
                        }
                    }
                }
            }

            ObjectReferenceValidityTest(Objects, RootObjectKey);

            var RelativePathToObjects = new Dictionary <String, String>();

            foreach (var conf in Project.Configurations)
            {
                foreach (var f in conf.Files)
                {
                    var PathParts = GetPathParts(FileNameHandling.GetRelativePath(f.Path, InputDirectory).Replace('\\', '/'));
                    PathParts[0] = Path.Combine(FileNameHandling.GetRelativePath(InputDirectory, OutputDirectory), PathParts[0]).Replace('\\', '/');
                    var RelativePath = String.Join("/", PathParts);
                    if (RelativePathToObjects.ContainsKey(RelativePath))
                    {
                        continue;
                    }
                    var Added = AddFile(Objects, RootObject["mainGroup"].String, new LinkedList <String>(), new LinkedList <String>(PathParts), f, BaseDirPath, RelativePathToObjects);
                    if (!Added)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            foreach (var Project in ProjectReferences)
            {
                var RelativePath = "Frameworks/" + Project.Name;
                AddProjectReference(Objects, RootObject["mainGroup"].String, new LinkedList <String>(), new LinkedList <String>(GetPathParts(RelativePath)), Project, BaseDirPath, RelativePathToObjects);
            }

            foreach (var TargetKey in Targets)
            {
                var conf = ConfigurationUtils.GetMergedConfiguration(ToolchainType.Mac_XCode, CompilerType.clang, BuildingOperatingSystem, TargetOperatingSystem, null, null, Project.Configurations);

                var Target     = Objects[TargetKey.String].Dict;
                var TargetName = Target["name"].String;
                foreach (var PhaseKey in Target["buildPhases"].Array)
                {
                    var Phase = Objects[PhaseKey.String].Dict;
                    var Type  = Phase["isa"].String;
                    if (Type == "PBXSourcesBuildPhase")
                    {
                        var Files = Phase["files"];
                        foreach (var f in conf.Files)
                        {
                            if ((f.Type == FileType.CSource) || (f.Type == FileType.CppSource) || (f.Type == FileType.ObjectiveCSource) || (f.Type == FileType.ObjectiveCppSource))
                            {
                                var PathParts = GetPathParts(FileNameHandling.GetRelativePath(f.Path, InputDirectory).Replace('\\', '/'));
                                PathParts[0] = Path.Combine(FileNameHandling.GetRelativePath(InputDirectory, OutputDirectory), PathParts[0]).Replace('\\', '/');
                                var RelativePath = String.Join("/", PathParts);
                                var File         = new Dictionary <String, Value>();
                                File.Add("fileRef", Value.CreateString(RelativePathToObjects[RelativePath]));
                                File.Add("isa", Value.CreateString("PBXBuildFile"));
                                var Hash = GetHashOfPath(TargetName + ":" + RelativePath);
                                Objects.Add(Hash, Value.CreateDict(File));
                                Files.Array.Add(Value.CreateString(Hash));
                            }
                        }
                    }
                    else if (Type == "PBXFrameworksBuildPhase")
                    {
                        var Files = Phase["files"];
                        foreach (var Project in ProjectReferences)
                        {
                            var RelativePath = "Frameworks/" + Project.Name;
                            var File         = new Dictionary <String, Value>();
                            File.Add("fileRef", Value.CreateString(RelativePathToObjects[RelativePath]));
                            File.Add("isa", Value.CreateString("PBXBuildFile"));
                            var Hash = GetHashOfPath(TargetName + ":" + RelativePath);
                            Objects.Add(Hash, Value.CreateDict(File));
                            Files.Array.Add(Value.CreateString(Hash));
                        }
                    }
                }
                Target["name"]        = Value.CreateString(Project.Name);
                Target["productName"] = Value.CreateString(Project.Name);
                var TargetFile = Objects[Target["productReference"].String];

                if (conf.TargetType == TargetType.Executable)
                {
                    if (TargetOperatingSystem == OperatingSystemType.Mac)
                    {
                        Target["productType"] = Value.CreateString("com.apple.product-type.tool");
                    }
                    else if (TargetOperatingSystem == OperatingSystemType.iOS)
                    {
                        Target["productType"] = Value.CreateString("com.apple.product-type.application");
                    }
                    else
                    {
                        throw new NotSupportedException("NotSupportedTargetOperatingSystem: " + TargetOperatingSystem.ToString());
                    }
                    TargetFile.Dict["explicitFileType"] = Value.CreateString("compiled.mach-o.executable");
                    TargetFile.Dict["path"]             = Value.CreateString(Project.Name);
                }
                else if (conf.TargetType == TargetType.StaticLibrary)
                {
                    Target["productType"] = Value.CreateString("com.apple.product-type.library.static");
                    TargetFile.Dict["explicitFileType"] = Value.CreateString("archive.ar");
                    TargetFile.Dict["path"]             = Value.CreateString("lib" + Project.Name + ".a");
                }
                else if (conf.TargetType == TargetType.DynamicLibrary)
                {
                    Target["productType"] = Value.CreateString("com.apple.product-type.library.dynamic");
                    TargetFile.Dict["explicitFileType"] = Value.CreateString("compiled.mach-o.dylib");
                    TargetFile.Dict["path"]             = Value.CreateString("lib" + Project.Name + ".dylib");
                }
                else
                {
                    throw new NotSupportedException("NotSupportedTargetType: " + conf.TargetType.ToString());
                }
            }

            foreach (var BuildConfigurationKey in Objects[RootObject["buildConfigurationList"].String].Dict["buildConfigurations"].Array)
            {
                var BuildConfiguration = Objects[BuildConfigurationKey.String].Dict;
                var ConfigurationType  = (ConfigurationType)(Enum.Parse(typeof(ConfigurationType), BuildConfiguration["name"].String));
                var BuildSettings      = BuildConfiguration["buildSettings"].Dict;

                var conf = ConfigurationUtils.GetMergedConfiguration(ToolchainType.Mac_XCode, CompilerType.clang, BuildingOperatingSystem, TargetOperatingSystem, ConfigurationType, null, Project.Configurations);

                var IncludeDirectories = conf.IncludeDirectories.Select(d => FileNameHandling.GetRelativePath(d, BaseDirPath).Replace('\\', '/')).ToList();
                if (IncludeDirectories.Count != 0)
                {
                    BuildSettings.SetItem("HEADER_SEARCH_PATHS", Value.CreateArray(IncludeDirectories.Concat(new List <String> {
                        "$(inherited)"
                    }).Select(d => Value.CreateString(d)).ToList()));
                }
                var Defines = conf.Defines;
                if (Defines.Count != 0)
                {
                    BuildSettings.SetItem("GCC_PREPROCESSOR_DEFINITIONS", Value.CreateArray(Defines.Select(d => d.Key + (d.Value == null ? "" : "=" + d.Value)).Concat(new List <String> {
                        "$(inherited)"
                    }).Select(d => Value.CreateString(d)).ToList()));
                }
                var CFlags = conf.CFlags;
                if (CFlags.Count != 0)
                {
                    BuildSettings.SetItem("OTHER_CFLAGS", Value.CreateArray(CFlags.Concat(new List <String> {
                        "$(inherited)"
                    }).Select(d => Value.CreateString(d)).ToList()));
                }
                var CppFlags = conf.CFlags.Concat(conf.CppFlags).ToList();
                if (CppFlags.Count != 0)
                {
                    BuildSettings.SetItem("OTHER_CPLUSPLUSFLAGS", Value.CreateArray(CppFlags.Concat(new List <String> {
                        "$(inherited)"
                    }).Select(d => Value.CreateString(d)).ToList()));
                }

                if ((conf.TargetType == TargetType.Executable) || (conf.TargetType == TargetType.DynamicLibrary))
                {
                    var LibDirectories = conf.LibDirectories.Select(d => FileNameHandling.GetRelativePath(d, BaseDirPath).Replace('\\', '/')).ToList();
                    if (LibDirectories.Count != 0)
                    {
                        BuildSettings.SetItem("LIBRARY_SEARCH_PATHS", Value.CreateArray(LibDirectories.Concat(new List <String> {
                            "$(inherited)"
                        }).Select(d => Value.CreateString(d)).ToList()));
                    }
                    var LinkerFlags = conf.Libs.Concat(conf.LinkerFlags).ToList();
                    if (LinkerFlags.Count != 0)
                    {
                        BuildSettings.SetItem("OTHER_LDFLAGS", Value.CreateArray(CppFlags.Concat(new List <String> {
                            "$(inherited)"
                        }).Select(d => Value.CreateString(d)).ToList()));
                    }
                }

                if (TargetOperatingSystem == OperatingSystemType.Mac)
                {
                    BuildSettings.SetItem("SDKROOT", Value.CreateString("macosx"));
                }
                else if (TargetOperatingSystem == OperatingSystemType.iOS)
                {
                    BuildSettings.SetItem("SDKROOT", Value.CreateString("iphoneos"));
                    if (conf.TargetType == TargetType.Executable)
                    {
                        BuildSettings.SetItem("INFOPLIST_FILE", Value.CreateString(FileNameHandling.GetRelativePath(Path.Combine(InputDirectory, "Info.plist"), BaseDirPath).Replace('\\', '/')));
                        BuildSettings.SetItem("PRODUCT_BUNDLE_IDENTIFIER", Value.CreateString(conf.BundleIdentifier));
                    }
                }
                else
                {
                    throw new NotSupportedException("NotSupportedTargetOperatingSystem: " + TargetOperatingSystem.ToString());
                }
            }

            ObjectReferenceValidityTest(Objects, RootObjectKey);
            TextFile.WriteToFile(PbxprojPath, Plist.ToString(p), new UTF8Encoding(false), !EnableRebuild);
        }