示例#1
0
        protected override bool IsMergableCppFileElementInternal(SolutionConfigManager.ProjectConfig projectConfig, XNamespace ns, XElement cppFileElement)
        {
            // Get all elements with a Condition attribute. If others exist, we don't handle those currently,
            // so don't include the file in the unity merge.
            var conditionalBuildElements = (from element in cppFileElement.Elements()
                                            where element.Attribute("Condition") != null
                                            select element).ToList();

            if (cppFileElement.Elements().Count() != conditionalBuildElements.Count)
            {
                return(false);
            }

            XName excludedFromBuildName = ns + "ExcludedFromBuild";

            foreach (XElement conditionalBuildElement in conditionalBuildElements)
            {
                XAttribute conditionAttribute = conditionalBuildElement.Attribute("Condition");
                if (!IsConfigConditionTrue(projectConfig, conditionAttribute.Value))
                {
                    continue;
                }
                if (conditionalBuildElement.Name != excludedFromBuildName)
                {
                    return(false);
                }
                if (conditionalBuildElement.Value == "true")
                {
                    return(false);
                }
            }

            return(true);
        }
示例#2
0
        protected override bool IsMergableCppFileElementInternal(SolutionConfigManager.ProjectConfig projectConfig, XNamespace ns, XElement cppFileElement)
        {
            // Get all child elements called FileConfiguration with a Name and possibly ExcludedFromBuild attribute.
            // If others exist, we don't handle those currently, so don't include the file in the unity merge.
            var configBuildElements = (from element in cppFileElement.Elements()
                                       where IsValidFileConfigElement(ns, element)
                                       select element).ToList();

            if (cppFileElement.Elements().Count() != configBuildElements.Count)
            {
                return(false);
            }

            string currentConfigCondition = GetProjectConfigName(projectConfig);

            foreach (XElement configBuildElement in configBuildElements)
            {
                XAttribute nameAttribute = configBuildElement.Attribute("Name");
                if (nameAttribute.Value != currentConfigCondition)
                {
                    continue;
                }
                XAttribute excludedFromBuildAttribute = configBuildElement.Attribute("ExcludedFromBuild");
                if (null != excludedFromBuildAttribute && excludedFromBuildAttribute.Value == "true")
                {
                    return(false);
                }
            }

            return(true);
        }
示例#3
0
        private void ReadWriteFilters(string projectFileName, SolutionConfigManager.ProjectConfig projectConfig, UnityFileMerger merger)
        {
            string projectFiltersFileName = projectFileName + ".filters";

            if (!File.Exists(projectFiltersFileName))
            {
                return;
            }

            XDocument projectFiltersDocument = XDocument.Load(projectFiltersFileName);

            if (null == projectFiltersDocument)
            {
                throw new InvalidDataException("Couldn't load project filters file '" + projectFiltersFileName + "'.");
            }

            XNamespace ns                       = projectFiltersDocument.Root.Name.Namespace;
            XElement   projectElement           = GetProjectElement(projectFileName, ns, projectFiltersDocument);
            var        compileItemGroupElements = GetCompileItemGroupElements(ns, projectElement);

            if (compileItemGroupElements.Count() > 0)
            {
                compileItemGroupElements.First().Add(
                    from unityFileName in merger.UnityFilePaths
                    select new XElement(ns + "ClCompile", new XAttribute("Include", unityFileName)));
            }

            string destProjectFiltersFileName = _settings.ModifyFileName(projectFiltersFileName);
            var    writer = new ModifiedTextFileWriter(destProjectFiltersFileName, _settings.BuildOptions.ShouldForceWriteCachedFiles());

            if (writer.Write(projectFiltersDocument.ToString()))
            {
                _settings.Output.WriteLine("Creating project filters file " + destProjectFiltersFileName);
            }
        }
示例#4
0
        private XElement GetConfigurationElement(SolutionConfigManager.ProjectConfig projectConfig, XDocument projectDocument, XNamespace ns)
        {
            string projectConfigName = GetProjectConfigName(projectConfig);
            var    configElements    =
                from configElement in projectDocument.Descendants(ns + "Configuration")
                where configElement.Attribute(ns + "Name") != null && configElement.Attribute(ns + "Name").Value == projectConfigName
                select configElement;

            return(configElements.SingleOrDefault());
        }
示例#5
0
        private IEnumerable <XElement> GetConfigurationElements(SolutionConfigManager.ProjectConfig projectConfig, XDocument projectDocument, XNamespace ns)
        {
            var configElements =
                from configElement in projectDocument.Descendants(ns + "ItemDefinitionGroup")
                let configConditionElement = configElement.Attribute("Condition")
                                             where configConditionElement == null || IsConfigConditionTrue(projectConfig, configConditionElement.Value)
                                             select configElement;

            return(configElements);
        }
示例#6
0
        private bool TryToSetupMsBuildProcessObject(SolutionInfo solutionInfo, ref ProcessStartInfo info)
        {
            try
            {
                info.FileName = GetMsBuildPath();
                if (string.IsNullOrEmpty(info.FileName))
                {
                    _settings.Output.WriteLine(
                        "Warning: RudeBuild is setup to use MSBuild, but MSBuild could not be found.\n" +
                        "Falling back to using a regular Visual Studio build.\n" +
                        "Error: Couldn't find MSBuild command-line tool: " + info.FileName);
                    return(false);
                }

                string buildCommand = "Build";
                if (_settings.BuildOptions.Clean)
                {
                    buildCommand = "Clean";
                }
                else if (_settings.BuildOptions.Rebuild)
                {
                    buildCommand = "Rebuild";
                }

                string   target      = _settings.ModifyFileName(solutionInfo.FilePath);
                string[] buildConfig = _settings.BuildOptions.Config.Split('|');
                if (!string.IsNullOrEmpty(_settings.BuildOptions.Project))
                {
                    ProjectInfo projectInfo = solutionInfo.GetProjectInfo(_settings.BuildOptions.Project);
                    if (projectInfo != null)
                    {
                        string projectConfigName;
                        SolutionConfigManager.ProjectConfig projectConfig = solutionInfo.ConfigManager.GetProjectByFileName(projectInfo.FileName);
                        if (projectConfig.SolutionToProjectConfigMap.TryGetValue(_settings.BuildOptions.Config, out projectConfigName))
                        {
                            target      = _settings.ModifyFileName(Path.GetFullPath(projectInfo.FileName));
                            buildConfig = projectConfigName.Split('|');
                        }
                    }
                }
                info.Arguments = $"/nodeReuse:false /m /t:{buildCommand} /p:Configuration=\"{buildConfig[0]}\" /p:Platform=\"{buildConfig[1]}\" \"{target}\"";
            }
            catch (Exception ex)
            {
                _settings.Output.WriteLine(
                    "Warning: RudeBuild is setup to use MSBuild, but MSBuild doesn't seem to be installed properly.\n" +
                    "Falling back to using a regular Visual Studio build.\n" +
                    "Error: " + ex.Message);
                return(false);
            }
            return(true);
        }
示例#7
0
        private bool TryToSetupSnVsBuildProcessObject(SolutionInfo solutionInfo, ref ProcessStartInfo info)
        {
            try
            {
                info.FileName = GetSnVsBuildPath();
                if (string.IsNullOrEmpty(info.FileName))
                {
                    _settings.Output.WriteLine(
                        "Warning: RudeBuild is setup to use SN-DBS, but SN-DBS or VSI doesn't seem to be installed properly.\n" +
                        "Falling back to using a regular Visual Studio build.\n" +
                        "Error: Couldn't find VSI command-line tool: " + info.FileName);
                    return(false);
                }

                string buildCommand = "/build";
                if (_settings.BuildOptions.Clean)
                {
                    buildCommand = "/clean";
                }
                else if (_settings.BuildOptions.Rebuild)
                {
                    buildCommand = "/rebuild";
                }

                info.Arguments = string.Format(" \"{0}\" {1} \"{2}\"", _settings.ModifyFileName(solutionInfo.FilePath), buildCommand, _settings.BuildOptions.Config);
                if (!string.IsNullOrEmpty(_settings.BuildOptions.Project))
                {
                    ProjectInfo projectInfo = solutionInfo.GetProjectInfo(_settings.BuildOptions.Project);
                    if (projectInfo != null)
                    {
                        string projectConfigName = null;
                        SolutionConfigManager.ProjectConfig projectConfig = solutionInfo.ConfigManager.GetProjectByFileName(projectInfo.FileName);
                        if (projectConfig.SolutionToProjectConfigMap.TryGetValue(_settings.BuildOptions.Config, out projectConfigName))
                        {
                            info.Arguments += string.Format(" /project \"{0}\" /projectconfig \"{1}\"", _settings.ModifyFileName(projectInfo.FileName), projectConfigName);
                        }
                    }
                }
                info.Arguments += " /sn-dbs";
            }
            catch (Exception ex)
            {
                _settings.Output.WriteLine(
                    "Warning: RudeBuild is setup to use SN-DBS, but SN-DBS doesn't seem to be installed properly.\n" +
                    "Falling back to using a regular Visual Studio build.\n" +
                    "Error: " + ex.Message);
                return(false);
            }
            return(true);
        }
示例#8
0
        protected bool IsMergableCppFileElement(SolutionConfigManager.ProjectConfig projectConfig, XNamespace ns, XElement cppFileElement, string pathAttributeName)
        {
            if (!IsValidCppFileElement(ns, cppFileElement, pathAttributeName))
            {
                return(false);
            }

            // If the file element has no child elements, then we accept this file for the unity merge.
            if (!cppFileElement.HasElements)
            {
                return(true);
            }

            return(IsMergableCppFileElementInternal(projectConfig, ns, cppFileElement));
        }
示例#9
0
        private string GetPrecompiledHeader(SolutionConfigManager.ProjectConfig projectConfig, XDocument projectDocument, XNamespace ns)
        {
            IEnumerable <XElement> configElements = GetConfigurationElements(projectConfig, projectDocument, ns);
            int precompiledHeaderUseCount         = (from precompiledHeaderElement in configElements.Descendants(ns + "PrecompiledHeader")
                                                     where precompiledHeaderElement.Value == "Use"
                                                     select precompiledHeaderElement).Count();

            if (0 == precompiledHeaderUseCount)
            {
                return(string.Empty);
            }

            XElement precompiledHeaderFileElement = (from element in configElements.Descendants(ns + "PrecompiledHeaderFile")
                                                     select element).SingleOrDefault();

            return(null != precompiledHeaderFileElement ? precompiledHeaderFileElement.Value : "StdAfx.h");
        }
示例#10
0
        private bool IsConfigConditionTrue(SolutionConfigManager.ProjectConfig projectConfig, string condition)
        {
            string projectConfigName = GetProjectConfigName(projectConfig);

            if (condition == string.Format("'$(Configuration)|$(Platform)'=='{0}'", projectConfigName))
            {
                return(true);
            }

            int platformStartIndex = projectConfigName.IndexOf('|');

            if (platformStartIndex > 0)
            {
                string platformName = projectConfigName.Substring(platformStartIndex + 1);
                if (condition == string.Format("'$(Platform)'=='{0}'", platformName))
                {
                    return(true);
                }
            }

            return(false);
        }
示例#11
0
        private string GetPrecompiledHeader(SolutionConfigManager.ProjectConfig projectConfig, XDocument projectDocument, XNamespace ns)
        {
            XElement configElement = GetConfigurationElement(projectConfig, projectDocument, ns);

            if (null == configElement)
            {
                return(string.Empty);
            }

            XElement precompiledHeaderElement =
                (from toolElement in configElement.Elements(ns + "Tool")
                 where toolElement.Attribute(ns + "UsePrecompiledHeader") != null && toolElement.Attribute(ns + "UsePrecompiledHeader").Value == "2"
                 select toolElement).SingleOrDefault();

            if (null == precompiledHeaderElement)
            {
                return(string.Empty);
            }

            XAttribute precompiledHeader = precompiledHeaderElement.Attribute(ns + "PrecompiledHeaderThrough");

            return(null != precompiledHeader ? precompiledHeader.Value : "StdAfx.h");
        }
示例#12
0
        public override ProjectInfo ReadWrite(string projectFileName, SolutionInfo solutionInfo, XDocument projectDocument, bool performReadOnly)
        {
            SolutionConfigManager.ProjectConfig projectConfig = solutionInfo.ConfigManager.GetProjectByFileName(projectFileName);
            if (null == projectConfig)
            {
                throw new InvalidDataException("Couldn't find project " + projectFileName + " in solution " + solutionInfo.Name);
            }

            XNamespace ns = projectDocument.Root.Name.Namespace;

            var fileElements            = projectDocument.Descendants(ns + "File").ToList();
            var mergableCppFileElements =
                (from element in fileElements
                 where IsMergableCppFileElement(projectConfig, ns, element, "RelativePath")
                 select element).ToList();
            var mergableCppFileNames =
                from cppFileElement in mergableCppFileElements
                select cppFileElement.Attribute("RelativePath").Value;

            var allCppFileNames =
                from element in fileElements
                where IsValidCppFileElement(ns, element, "RelativePath")
                select element.Attribute("RelativePath").Value;

            var allIncludeFileNames =
                from element in fileElements
                where IsValidIncludeFileElement(ns, element, "RelativePath")
                select element.Attribute("RelativePath").Value;

            string projectName           = Path.GetFileNameWithoutExtension(projectFileName);
            string precompiledHeaderName = GetPrecompiledHeader(projectConfig, projectDocument, ns);
            var    projectInfo           = new ProjectInfo(solutionInfo, projectName, projectFileName, mergableCppFileNames.ToList(), allCppFileNames.ToList(), allIncludeFileNames.ToList(), precompiledHeaderName);

            if (!performReadOnly)
            {
                var merger = new UnityFileMerger(_settings);
                merger.Process(projectInfo);

                foreach (XElement cppFileNameElement in mergableCppFileElements)
                {
                    string cppFileName = cppFileNameElement.Attribute("RelativePath").Value;
                    if (merger.MergedCppFileNames.Contains(cppFileName))
                    {
                        cppFileNameElement.Remove();
                    }
                }

                XElement filesElement = projectDocument.Descendants(ns + "Files").Single();
                filesElement.Add(
                    from unityFileName in merger.UnityFilePaths
                    select new XElement(ns + "File", new XAttribute("RelativePath", unityFileName)));

                if (ShouldDisablePrecompiledHeaders(projectInfo))
                {
                    DisablePrecompiledHeaders(projectDocument, ns);
                }
                if (_settings.SolutionSettings.SetBigObjCompilerFlag)
                {
                    SetBigObjCompilerFlag(projectDocument, ns);
                }
            }

            return(projectInfo);
        }
示例#13
0
 protected abstract bool IsMergableCppFileElementInternal(SolutionConfigManager.ProjectConfig projectConfig, XNamespace ns, XElement cppFileElement);
示例#14
0
        public override ProjectInfo ReadWrite(string projectFileName, SolutionInfo solutionInfo, XDocument projectDocument, bool performReadOnly)
        {
            SolutionConfigManager.ProjectConfig projectConfig = solutionInfo.ConfigManager.GetProjectByFileName(projectFileName);
            if (null == projectConfig)
            {
                throw new InvalidDataException("Couldn't find project " + projectFileName + " in solution " + solutionInfo.Name);
            }

            XNamespace ns             = projectDocument.Root.Name.Namespace;
            XElement   projectElement = GetProjectElement(projectFileName, ns, projectDocument);

            // Determine the project name and ensure the generated RudeBuild project has a ProjectName element.
            string   projectName = Path.GetFileNameWithoutExtension(projectFileName);
            XElement globalPropertyGroupElement = GetGlobalProjectPropertyGroupElement(projectFileName, ns, projectElement);
            XElement projectNameElement         = globalPropertyGroupElement.Element(ns + "ProjectName");

            if (projectNameElement == null)
            {
                globalPropertyGroupElement.Add(new XElement(ns + "ProjectName", projectName));
            }
            else
            {
                projectName = projectNameElement.Value;
            }

            var compileItemGroupElements    = GetCompileItemGroupElements(ns, projectElement);
            var mergableCppFileNames        = new List <string>();
            var mergableCppFileNameElements = new List <XElement>();

            foreach (var compileItemGroupElement in compileItemGroupElements)
            {
                mergableCppFileNameElements.AddRange(
                    from compileElement in compileItemGroupElement.Elements(ns + "ClCompile")
                    where IsMergableCppFileElement(projectConfig, ns, compileElement, "Include")
                    select compileElement);
            }
            mergableCppFileNames.AddRange(
                from compileElement in mergableCppFileNameElements
                select compileElement.Attribute("Include").Value);

            IList <string> allCppFileNames       = GetAllCppFileNames(ns, projectElement);
            IList <string> allIncludeFileNames   = GetAllIncludeFileNames(ns, projectElement);
            string         precompiledHeaderName = GetPrecompiledHeader(projectConfig, projectDocument, ns);
            var            projectInfo           = new ProjectInfo(solutionInfo, projectName, projectFileName, mergableCppFileNames, allCppFileNames, allIncludeFileNames, precompiledHeaderName);

            if (!performReadOnly)
            {
                var merger = new UnityFileMerger(_settings);
                merger.Process(projectInfo);

                foreach (XElement cppFileNameElement in mergableCppFileNameElements)
                {
                    string cppFileName = cppFileNameElement.Attribute("Include").Value;
                    if (merger.MergedCppFileNames.Contains(cppFileName))
                    {
                        AddExcludedFromBuild(ns, cppFileNameElement);
                    }
                }

                if (compileItemGroupElements.Count() > 0)
                {
                    compileItemGroupElements.First().Add(
                        from unityFileName in merger.UnityFilePaths
                        select new XElement(ns + "ClCompile", new XAttribute("Include", unityFileName)));
                }

                if (ShouldDisablePrecompiledHeaders(projectInfo))
                {
                    DisablePrecompiledHeaders(projectDocument, ns);
                }
                if (_settings.SolutionSettings.SetBigObjCompilerFlag)
                {
                    SetBigObjCompilerFlag(projectDocument, ns);
                }

                if (!string.IsNullOrEmpty(_settings.GlobalSettings.IntDirSuffix))
                {
                    SetIntDir(ns, projectElement, _settings.GlobalSettings.IntDirSuffix);
                }

                FixupProjectReferences(projectDocument, ns, _settings);

                ReadWriteFilters(projectFileName, projectConfig, merger);
            }

            return(projectInfo);
        }
示例#15
0
        protected string GetProjectConfigName(SolutionConfigManager.ProjectConfig projectConfig)
        {
            string solutionConfigName = _settings.BuildOptions.Config;

            return(projectConfig.GetProjectConfig(solutionConfigName) ?? solutionConfigName);
        }