Пример #1
0
 AppendTargetNames(
     Bam.Core.StringArray variableNames)
 {
     foreach (var target in this.Targets)
     {
         var name = target.VariableName;
         if (null != name)
         {
             variableNames.AddUnique("$(" + name + ")");
         }
         else
         {
             variableNames.AddUnique(target.Path.Parse());
         }
     }
 }
Пример #2
0
        Serialize()
        {
            var document = new System.Xml.XmlDocument();

            var projectEl = this.CreateRootProject(document);

            projectEl.SetAttribute("ToolsVersion", "4.0"); // TODO: get this number from VisualC

            var filtersEl = document.CreateVSItemGroup(parentEl: projectEl);

            foreach (var filter in this.Filters)
            {
                var filterEl = document.CreateVSElement("Filter", parentEl: filtersEl);
                filterEl.SetAttribute("Include", filter.Key);
                document.CreateVSElement("UniqueIdentifier", new DeterministicGuid("VSFilter" + filter.Key).Guid.ToString("B").ToUpper(), parentEl: filterEl);

                var filesEl    = document.CreateVSItemGroup(parentEl: projectEl);
                var extensions = new Bam.Core.StringArray();
                foreach (var setting in filter.Value)
                {
                    var path      = setting.Include;
                    var extension = System.IO.Path.GetExtension(path.Parse()).TrimStart(new[] { '.' });
                    extensions.AddUnique(extension);
                    setting.Serialize(document, filesEl);
                }
                if (extensions.Count > 0)
                {
                    document.CreateVSElement("Extensions", extensions.ToString(';'), parentEl: filterEl);
                }
            }
            return(document);
        }
Пример #3
0
 AppendAllPrerequisiteTargetNames(
     Bam.Core.StringArray variableNames)
 {
     lock (this.Targets)
     {
         foreach (var target in this.Targets)
         {
             if (!target.IsPrerequisiteofAll)
             {
                 continue;
             }
             var name = target.VariableName;
             if (null != name)
             {
                 variableNames.AddUnique("$(" + name + ")");
             }
             else
             {
                 variableNames.AddUnique(target.Path.ToString());
             }
         }
     }
 }
Пример #4
0
        Serialize()
        {
            var ProjectTypeGuid    = System.Guid.Parse("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942");
            var SolutionFolderGuid = System.Guid.Parse("2150E333-8FDC-42A3-9474-1A3956D46DE8");

            var content = new System.Text.StringBuilder();

            // TODO: obviously dependent on version
            content.AppendLine(@"Microsoft Visual Studio Solution File, Format Version 12.00");

            var configs = new Bam.Core.StringArray();

            foreach (var project in this.Projects)
            {
                content.AppendFormat("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"",
                                     ProjectTypeGuid.ToString("B").ToUpper(),
                                     System.IO.Path.GetFileNameWithoutExtension(project.ProjectPath),
                                     project.ProjectPath, // TODO: relative to the solution file
                                     project.Guid.ToString("B").ToUpper());
                content.AppendLine();
                content.AppendLine("EndProject");

                foreach (var config in project.Configurations)
                {
                    configs.AddUnique(config.Value.FullName);
                }
            }
            foreach (var folder in this.SolutionFolders)
            {
                content.AppendFormat("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"",
                                     SolutionFolderGuid.ToString("B").ToUpper(),
                                     folder.Key,
                                     folder.Key,
                                     folder.Value.Guid);
                content.AppendLine();
                content.AppendLine("EndProject");
            }
            content.AppendLine("Global");
            content.AppendLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
            foreach (var config in configs)
            {
                // TODO: I'm sure these are not meant to be identical, but I don't know what else to put here
                content.AppendFormat("\t\t{0} = {0}", config);
                content.AppendLine();
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
            foreach (var project in this.Projects)
            {
                foreach (var config in project.Configurations)
                {
                    var guid = project.Guid.ToString("B").ToUpper();
                    content.AppendFormat("\t\t{0}.{1}.ActiveCfg = {1}", guid, config.Value.FullName);
                    content.AppendLine();
                    content.AppendFormat("\t\t{0}.{1}.Build.0 = {1}", guid, config.Value.FullName);
                    content.AppendLine();
                }
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(SolutionProperties) = preSolution");
            content.AppendLine("\t\tHideSolutionNode = FALSE");
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(NestedProjects) = preSolution");
            foreach (var folder in this.SolutionFolders)
            {
                foreach (var project in folder.Value.Projects)
                {
                    content.AppendFormat("\t\t{0} = {1}", project.Guid.ToString("B").ToUpper(), folder.Value.Guid);
                    content.AppendLine();
                }
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("EndGlobal");

            return(content);
        }
Пример #5
0
        public override void Evaluate()
        {
            this.ReasonToExecute = null;
            var graph = Bam.Core.Graph.Instance;
            var factory = graph.MetaData as System.Threading.Tasks.TaskFactory;
            this.EvaluationTask = factory.StartNew(() =>
            {
                // does the object file exist?
                var objectFilePath = this.GeneratedPaths[Key].Parse();
                if (!System.IO.File.Exists(objectFilePath))
                {
                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.FileDoesNotExist(this.GeneratedPaths[Key]);
                    return;
                }
                var objectFileWriteTime = System.IO.File.GetLastWriteTime(objectFilePath);

                // has the source file been evaluated to be rebuilt?
                if ((this as IRequiresSourceModule).Source.ReasonToExecute != null)
                {
                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(this.GeneratedPaths[Key], this.InputPath);
                    return;
                }

                // is the source file newer than the object file?
                var sourcePath = this.InputPath.Parse();
                var sourceWriteTime = System.IO.File.GetLastWriteTime(sourcePath);
                if (sourceWriteTime > objectFileWriteTime)
                {
                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(this.GeneratedPaths[Key], this.InputPath);
                    return;
                }

                if (this is WinResource)
                {
                    return;
                }

                // are there any headers as explicit dependencies (procedurally generated most likely), which are newer?
                var explicitHeadersUpdated = new Bam.Core.StringArray();
                foreach (var dep in this.Dependents)
                {
                    if (!(dep is HeaderFile))
                    {
                        continue;
                    }
                    if (null == dep.ReasonToExecute)
                    {
                        continue;
                    }
                    explicitHeadersUpdated.AddUnique((dep as HeaderFile).InputPath.Parse());
                }

                var includeSearchPaths = (this.Settings as C.ICommonCompilerSettings).IncludePaths;

                var filesToSearch = new System.Collections.Generic.Queue<string>();
                filesToSearch.Enqueue(sourcePath);

                var headerPathsFound = new Bam.Core.StringArray();
                while (filesToSearch.Count > 0)
                {
                    var fileToSearch = filesToSearch.Dequeue();

                    string fileContents = null;
                    using (System.IO.TextReader reader = new System.IO.StreamReader(fileToSearch))
                    {
                        fileContents = reader.ReadToEnd();
                    }

                    // never know if developers are consistent with #include "header.h" or #include <header.h> so look for both
                    var matches = System.Text.RegularExpressions.Regex.Matches(
                        fileContents,
                        "^\\s*#include [\"<]([^\\s]*)[\">]",
                        System.Text.RegularExpressions.RegexOptions.Multiline);
                    if (0 == matches.Count)
                    {
                        // no #includes
                        return;
                    }

                    foreach (System.Text.RegularExpressions.Match match in matches)
                    {
                        var headerFile = match.Groups[1].Value;
                        bool exists = false;
                        // search for the file on the include paths the compiler uses
                        foreach (var includePath in includeSearchPaths)
                        {
                            try
                            {
                                var potentialPath = System.IO.Path.Combine(includePath.Parse(), headerFile);
                                if (!System.IO.File.Exists(potentialPath))
                                {
                                    continue;
                                }
                                potentialPath = System.IO.Path.GetFullPath(potentialPath);
                                var headerWriteTime = System.IO.File.GetLastWriteTime(potentialPath);

                                // early out - header is newer than generated object file
                                if (headerWriteTime > objectFileWriteTime)
                                {
                                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(
                                        this.GeneratedPaths[Key],
                                        Bam.Core.TokenizedString.CreateVerbatim(potentialPath));
                                    return;
                                }

                                if (explicitHeadersUpdated.Contains(potentialPath))
                                {
                                    // found #included header in list of explicitly dependent headers that have been updated
                                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(
                                        this.GeneratedPaths[Key],
                                        Bam.Core.TokenizedString.CreateVerbatim(potentialPath));
                                    return;
                                }

                                if (!headerPathsFound.Contains(potentialPath))
                                {
                                    headerPathsFound.Add(potentialPath);
                                    filesToSearch.Enqueue(potentialPath);
                                }

                                exists = true;
                                break;
                            }
                            catch (System.Exception ex)
                            {
                                Bam.Core.Log.MessageAll("IncludeDependency Exception: Cannot locate '{0}' on '{1}' due to {2}", headerFile, includePath, ex.Message);
                            }
                        }

                        if (!exists)
                        {
            #if false
                                Bam.Core.Log.DebugMessage("***** Could not locate '{0}' on any include search path, included from {1}:\n{2}",
                                                          match.Groups[1],
                                                          fileToSearch,
                                                          entry.includePaths.ToString('\n'));
            #endif
                        }
                    }
                }

                return;
            });
        }
Пример #6
0
        Serialize(
            string solutionPath)
        {
            var ProjectTypeGuid    = System.Guid.Parse("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942");
            var SolutionFolderGuid = System.Guid.Parse("2150E333-8FDC-42A3-9474-1A3956D46DE8");

            var content = new System.Text.StringBuilder();

            var visualCMeta = Bam.Core.Graph.Instance.PackageMetaData <VisualC.MetaData>("VisualC");

            content.AppendFormat(@"Microsoft Visual Studio Solution File, Format Version {0}", visualCMeta.SolutionFormatVersion);
            content.AppendLine();

            var configs = new Bam.Core.StringArray();

            foreach (var project in this.Projects)
            {
                var relativeProjectPath = Bam.Core.RelativePathUtilities.GetPath(project.ProjectPath, solutionPath);
                content.AppendFormat("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"",
                                     ProjectTypeGuid.ToString("B").ToUpper(),
                                     System.IO.Path.GetFileNameWithoutExtension(project.ProjectPath),
                                     relativeProjectPath,
                                     project.GuidString);
                content.AppendLine();
                content.AppendLine("EndProject");

                foreach (var config in project.Configurations)
                {
                    configs.AddUnique(config.Value.FullName);
                }
            }
            foreach (var folder in this.SolutionFolders)
            {
                var folderPath = folder.Value.Path;
                var folderGuid = folder.Value.GuidString;
                content.AppendFormat("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"",
                                     SolutionFolderGuid.ToString("B").ToUpper(),
                                     folderPath,
                                     folderPath,
                                     folderGuid);
                content.AppendLine();
                content.AppendLine("EndProject");
            }
            content.AppendLine("Global");
            content.AppendLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
            foreach (var config in configs)
            {
                // TODO: I'm sure these are not meant to be identical, but I don't know what else to put here
                content.AppendFormat("\t\t{0} = {0}", config);
                content.AppendLine();
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
            foreach (var project in this.Projects)
            {
                var guid = project.GuidString;
                var thisProjectConfigs = new Bam.Core.StringArray();

                // write the configurations for which build steps have been defined
                foreach (var config in project.Configurations)
                {
                    var configName = config.Value.FullName;
                    content.AppendFormat("\t\t{0}.{1}.ActiveCfg = {1}", guid, configName);
                    content.AppendLine();
                    content.AppendFormat("\t\t{0}.{1}.Build.0 = {1}", guid, configName);
                    content.AppendLine();
                    thisProjectConfigs.AddUnique(configName);
                }

                // now cater for any configurations that the project does not support
                var unsupportedConfigs = configs.Complement(thisProjectConfigs) as Bam.Core.StringArray;
                foreach (var uConfig in unsupportedConfigs)
                {
                    // a missing "XX.YY.Build.0" line means not configured to build
                    // also, the remapping between config names seems a little arbitrary, but seems to work
                    // might be related to the project not having an ProjectConfiguration for the unsupported config
                    content.AppendFormat("\t\t{0}.{1}.ActiveCfg = {2}", guid, uConfig, thisProjectConfigs[0]);
                    content.AppendLine();
                }
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(SolutionProperties) = preSolution");
            content.AppendLine("\t\tHideSolutionNode = FALSE");
            content.AppendLine("\tEndGlobalSection");
            if (this.SolutionFolders.Count() > 0)
            {
                content.AppendLine("\tGlobalSection(NestedProjects) = preSolution");
                foreach (var folder in this.SolutionFolders)
                {
                    folder.Value.Serialize(content, 2);
                }
                content.AppendLine("\tEndGlobalSection");
            }
            content.AppendLine("EndGlobal");

            return(content);
        }
Пример #7
0
        Evaluate()
        {
            this.ReasonToExecute = null;
            if (!this.PerformCompilation)
            {
                return;
            }
            var graph   = Bam.Core.Graph.Instance;
            var factory = graph.MetaData as System.Threading.Tasks.TaskFactory;

            this.EvaluationTask = factory.StartNew(() =>
            {
                // does the object file exist?
                var objectFilePath = this.GeneratedPaths[Key].Parse();
                if (!System.IO.File.Exists(objectFilePath))
                {
                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.FileDoesNotExist(this.GeneratedPaths[Key]);
                    return;
                }
                var objectFileWriteTime = System.IO.File.GetLastWriteTime(objectFilePath);

                // has the source file been evaluated to be rebuilt?
                if ((this as IRequiresSourceModule).Source.ReasonToExecute != null)
                {
                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(this.GeneratedPaths[Key], this.InputPath);
                    return;
                }

                // is the source file newer than the object file?
                var sourcePath      = this.InputPath.Parse();
                var sourceWriteTime = System.IO.File.GetLastWriteTime(sourcePath);
                if (sourceWriteTime > objectFileWriteTime)
                {
                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(this.GeneratedPaths[Key], this.InputPath);
                    return;
                }

                if (this is WinResource)
                {
                    return;
                }

                // are there any headers as explicit dependencies (procedurally generated most likely), which are newer?
                var explicitHeadersUpdated  = new Bam.Core.StringArray();
                var explicitHeadersDeferred = new Bam.Core.StringArray();
                foreach (var dep in this.Dependents)
                {
                    if (!(dep is HeaderFile))
                    {
                        continue;
                    }
                    if (null == dep.ReasonToExecute)
                    {
                        continue;
                    }
                    if (dep.ReasonToExecute.Reason == Bam.Core.ExecuteReasoning.EReason.InputFileIsNewer)
                    {
                        explicitHeadersUpdated.AddUnique((dep as HeaderFile).InputPath.Parse());
                    }
                    else if (dep.ReasonToExecute.Reason == Bam.Core.ExecuteReasoning.EReason.DeferredEvaluation)
                    {
                        explicitHeadersDeferred.AddUnique((dep as HeaderFile).InputPath.Parse());
                    }
                }

                var includeSearchPaths = (this.Settings as C.ICommonCompilerSettings).IncludePaths;
                // implicitly search the same directory as the source path, as this is not needed to be explicitly on the include path list
                includeSearchPaths.AddUnique(this.CreateTokenizedString("@dir($(0))", this.InputPath));

                var filesToSearch = new System.Collections.Generic.Queue <string>();
                filesToSearch.Enqueue(sourcePath);

                var headerPathsFound = new Bam.Core.StringArray();
                while (filesToSearch.Count > 0)
                {
                    var fileToSearch = filesToSearch.Dequeue();

                    string fileContents = null;
                    using (System.IO.TextReader reader = new System.IO.StreamReader(fileToSearch))
                    {
                        fileContents = reader.ReadToEnd();
                    }

                    // never know if developers are consistent with #include "header.h" or #include <header.h> so look for both
                    // nor the amount of whitespace after #include
                    var matches = System.Text.RegularExpressions.Regex.Matches(
                        fileContents,
                        "^\\s*#include\\s*[\"<]([^\\s]*)[\">]",
                        System.Text.RegularExpressions.RegexOptions.Multiline);
                    if (0 == matches.Count)
                    {
                        // no #includes
                        return;
                    }

                    foreach (System.Text.RegularExpressions.Match match in matches)
                    {
                        var headerFile = match.Groups[1].Value;
                        bool exists    = false;
                        // search for the file on the include paths the compiler uses
                        foreach (var includePath in includeSearchPaths)
                        {
                            try
                            {
                                var potentialPath = System.IO.Path.Combine(includePath.Parse(), headerFile);
                                if (!System.IO.File.Exists(potentialPath))
                                {
                                    continue;
                                }
                                potentialPath       = System.IO.Path.GetFullPath(potentialPath);
                                var headerWriteTime = System.IO.File.GetLastWriteTime(potentialPath);

                                // early out - header is newer than generated object file
                                if (headerWriteTime > objectFileWriteTime)
                                {
                                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(
                                        this.GeneratedPaths[Key],
                                        Bam.Core.TokenizedString.CreateVerbatim(potentialPath));
                                    return;
                                }

                                // found #included header in list of explicitly dependent headers that have been updated
                                if (explicitHeadersUpdated.Contains(potentialPath))
                                {
                                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(
                                        this.GeneratedPaths[Key],
                                        Bam.Core.TokenizedString.CreateVerbatim(potentialPath));
                                    return;
                                }
                                // found #included header in list of explicitly dependent headers that require a deferred evaluation
                                if (explicitHeadersDeferred.Contains(potentialPath))
                                {
                                    this.ReasonToExecute = Bam.Core.ExecuteReasoning.DeferredUntilBuild(this.GeneratedPaths[Key]);
                                    return;
                                }

                                if (!headerPathsFound.Contains(potentialPath))
                                {
                                    headerPathsFound.Add(potentialPath);
                                    filesToSearch.Enqueue(potentialPath);
                                }

                                exists = true;
                                break;
                            }
                            catch (System.Exception ex)
                            {
                                Bam.Core.Log.MessageAll("IncludeDependency Exception: Cannot locate '{0}' on '{1}' due to {2}", headerFile, includePath, ex.Message);
                            }
                        }

                        if (!exists)
                        {
#if false
                            Bam.Core.Log.DebugMessage("***** Could not locate '{0}' on any include search path, included from {1}:\n{2}",
                                                      match.Groups[1],
                                                      fileToSearch,
                                                      entry.includePaths.ToString('\n'));
#endif
                        }
                    }
                }

                return;
            });
        }
Пример #8
0
        public System.Text.StringBuilder Serialize()
        {
            var ProjectTypeGuid = System.Guid.Parse("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942");
            var SolutionFolderGuid = System.Guid.Parse("2150E333-8FDC-42A3-9474-1A3956D46DE8");

            var content = new System.Text.StringBuilder();

            // TODO: obviously dependent on version
            content.AppendLine(@"Microsoft Visual Studio Solution File, Format Version 12.00");

            var configs = new Bam.Core.StringArray();
            foreach (var project in this.Projects)
            {
                content.AppendFormat("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"",
                    ProjectTypeGuid.ToString("B").ToUpper(),
                    System.IO.Path.GetFileNameWithoutExtension(project.ProjectPath),
                    project.ProjectPath, // TODO: relative to the solution file
                    project.GuidString);
                content.AppendLine();
                content.AppendLine("EndProject");

                foreach (var config in project.Configurations)
                {
                    configs.AddUnique(config.Value.FullName);
                }
            }
            foreach (var folder in this.SolutionFolders)
            {
                content.AppendFormat("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"",
                    SolutionFolderGuid.ToString("B").ToUpper(),
                    folder.Key,
                    folder.Key,
                    folder.Value.GuidString);
                content.AppendLine();
                content.AppendLine("EndProject");
            }
            content.AppendLine("Global");
            content.AppendLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
            foreach (var config in configs)
            {
                // TODO: I'm sure these are not meant to be identical, but I don't know what else to put here
                content.AppendFormat("\t\t{0} = {0}", config);
                content.AppendLine();
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
            foreach (var project in this.Projects)
            {
                foreach (var config in project.Configurations)
                {
                    var guid = project.GuidString;
                    content.AppendFormat("\t\t{0}.{1}.ActiveCfg = {1}", guid, config.Value.FullName);
                    content.AppendLine();
                    content.AppendFormat("\t\t{0}.{1}.Build.0 = {1}", guid, config.Value.FullName);
                    content.AppendLine();
                }
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(SolutionProperties) = preSolution");
            content.AppendLine("\t\tHideSolutionNode = FALSE");
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("\tGlobalSection(NestedProjects) = preSolution");
            foreach (var folder in this.SolutionFolders)
            {
                foreach (var nested in folder.Value.NestedEntities)
                {
                    content.AppendFormat("\t\t{0} = {1}", nested.GuidString, folder.Value.GuidString);
                    content.AppendLine();
                }
            }
            content.AppendLine("\tEndGlobalSection");
            content.AppendLine("EndGlobal");

            return content;
        }
Пример #9
0
        Serialize()
        {
            var document = new System.Xml.XmlDocument();

            var projectEl = this.CreateRootProject(document);
            projectEl.SetAttribute("ToolsVersion", "4.0"); // TODO: get this number from VisualC

            var filtersEl = document.CreateVSItemGroup(parentEl: projectEl);

            foreach (var filter in this.Filters)
            {
                var filterEl = document.CreateVSElement("Filter", parentEl: filtersEl);
                filterEl.SetAttribute("Include", filter.Key);
                document.CreateVSElement("UniqueIdentifier", new DeterministicGuid("VSFilter" + filter.Key).Guid.ToString("B").ToUpper(), parentEl: filterEl);

                var filesEl = document.CreateVSItemGroup(parentEl: projectEl);
                var extensions = new Bam.Core.StringArray();
                foreach (var setting in filter.Value)
                {
                    var path = setting.Include;
                    var extension = System.IO.Path.GetExtension(path.Parse()).TrimStart(new[] { '.' });
                    extensions.AddUnique(extension);
                    setting.Serialize(document, filesEl);
                }
                if (extensions.Count > 0)
                {
                    document.CreateVSElement("Extensions", extensions.ToString(';'), parentEl: filterEl);
                }
            }
            return document;
        }