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); }
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); }
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); } }
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()); }
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); }
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); }
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); }
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)); }
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"); }
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); }
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"); }
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); }
protected abstract bool IsMergableCppFileElementInternal(SolutionConfigManager.ProjectConfig projectConfig, XNamespace ns, XElement cppFileElement);
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); }
protected string GetProjectConfigName(SolutionConfigManager.ProjectConfig projectConfig) { string solutionConfigName = _settings.BuildOptions.Config; return(projectConfig.GetProjectConfig(solutionConfigName) ?? solutionConfigName); }