bool SetCommandLines( QtMsBuildContainer qtMsBuild, IEnumerable <string> configurations, IEnumerable <XElement> customBuilds, string itemType) { var query = from customBuild in customBuilds let itemName = customBuild.Attribute("Include").Value from configName in configurations from command in customBuild.Elements(ns + "Command") let commandLine = command.Value where command.Attribute("Condition").Value == string.Format( "'$(Configuration)|$(Platform)'=='{0}'", configName) select new { customBuild, itemName, configName, commandLine }; foreach (var row in query) { XElement item; row.customBuild.Add(item = new XElement(ns + itemType, new XAttribute("Include", row.itemName), new XAttribute("ConfigName", row.configName))); if (!qtMsBuild.SetCommandLine(itemType, item, row.commandLine)) { return(false); } } return(true); }
bool SetCommandLines( QtMsBuildContainer qtMsBuild, IEnumerable <XElement> configurations, IEnumerable <XElement> customBuilds, string itemType, string workingDir) { var query = from customBuild in customBuilds let itemName = customBuild.Attribute("Include").Value from config in configurations from command in customBuild.Elements(ns + "Command") let commandLine = command.Value where command.Attribute("Condition").Value == string.Format( "'$(Configuration)|$(Platform)'=='{0}'", (string)config.Attribute("Include")) select new { customBuild, itemName, config, commandLine }; using (var evaluator = new MSBuildEvaluator(this[Files.Project])) { foreach (var row in query) { XElement item; row.customBuild.Add(item = new XElement(ns + itemType, new XAttribute("Include", row.itemName), new XAttribute("ConfigName", (string)row.config.Attribute("Include")))); var configName = (string)row.config.Element(ns + "Configuration"); var platformName = (string)row.config.Element(ns + "Platform"); var commandLine = row.commandLine .Replace(Path.GetFileName(row.itemName), "%(Filename)%(Extension)", StringComparison.InvariantCultureIgnoreCase) .Replace(configName, "$(Configuration)", StringComparison.InvariantCultureIgnoreCase) .Replace(platformName, "$(Platform)", StringComparison.InvariantCultureIgnoreCase); evaluator.Properties.Clear(); foreach (var configProp in row.config.Elements()) { evaluator.Properties.Add(configProp.Name.LocalName, (string)configProp); } if (!qtMsBuild.SetCommandLine(itemType, item, commandLine, evaluator)) { return(false); } } } return(true); }
public bool ConvertCustomBuildToQtMsBuild() { var cbEvals = EvaluateCustomBuild(); var qtMsBuild = new QtMsBuildContainer(new MsBuildConverterProvider()); qtMsBuild.BeginSetItemProperties(); var projDir = Path.GetDirectoryName(this[Files.Project].filePath); var configurations = this[Files.Project].xml .Elements(ns + "Project") .Elements(ns + "ItemGroup") .Elements(ns + "ProjectConfiguration"); var projItemsByPath = this[Files.Project].xml .Elements(ns + "Project") .Elements(ns + "ItemGroup") .Elements(ns + "ClCompile") .Where(x => ((string)x.Attribute("Include")) .IndexOfAny(Path.GetInvalidPathChars()) == -1) .ToDictionary(x => HelperFunctions.CanonicalPath( Path.Combine(projDir, (string)x.Attribute("Include"))), StringComparer.InvariantCultureIgnoreCase); var filterItemsByPath = this[Files.Filters].xml .Elements(ns + "Project") .Elements(ns + "ItemGroup") .Elements(ns + "ClCompile") .Where(x => ((string)x.Attribute("Include")) .IndexOfAny(Path.GetInvalidPathChars()) == -1) .ToDictionary(x => HelperFunctions.CanonicalPath( Path.Combine(projDir, (string)x.Attribute("Include"))), StringComparer.InvariantCultureIgnoreCase); var cppIncludePaths = this[Files.Project].xml .Elements(ns + "Project") .Elements(ns + "ItemDefinitionGroup") .Elements(ns + "ClCompile") .Elements(ns + "AdditionalIncludeDirectories"); //add generated files path to C++ additional include dirs foreach (var cppIncludePath in cppIncludePaths) { cppIncludePath.Value = AddGeneratedFilesPath((string)cppIncludePath); } // replace each set of .moc.cbt custom build steps // with a single .cpp custom build step var mocCbtCustomBuilds = GetCustomBuilds(QtMoc.ToolExecName) .Where(x => ((string)x.Attribute("Include")).EndsWith(".cbt", StringComparison.InvariantCultureIgnoreCase) || ((string)x.Attribute("Include")).EndsWith(".moc", StringComparison.InvariantCultureIgnoreCase)) .GroupBy(cbt => CustomBuildMocInput(cbt)); List <XElement> cbtToRemove = new List <XElement>(); foreach (var cbtGroup in mocCbtCustomBuilds) { //create new CustomBuild item for .cpp var newCbt = new XElement(ns + "CustomBuild", new XAttribute("Include", cbtGroup.Key), new XElement(ns + "FileType", "Document")); //add properties from .moc.cbt items List <string> cbtPropertyNames = new List <string> { "AdditionalInputs", "Command", "Message", "Outputs", }; foreach (var cbt in cbtGroup) { var enabledProperties = cbt.Elements().Where(x => cbtPropertyNames.Contains(x.Name.LocalName) && !x.Parent.Elements(ns + "ExcludedFromBuild").Where(y => (string)x.Attribute("Condition") == (string)y.Attribute("Condition")) .Any()); foreach (var property in enabledProperties) { newCbt.Add(new XElement(property)); } cbtToRemove.Add(cbt); } cbtGroup.First().AddBeforeSelf(newCbt); //remove ClCompile item (cannot have duplicate items) var cppMocItems = this[Files.Project].xml .Elements(ns + "Project") .Elements(ns + "ItemGroup") .Elements(ns + "ClCompile") .Where(x => cbtGroup.Key.Equals((string)x.Attribute("Include"), StringComparison.InvariantCultureIgnoreCase)); foreach (var cppMocItem in cppMocItems) { cppMocItem.Remove(); } //change type of item in filter cppMocItems = this[Files.Filters].xml .Elements(ns + "Project") .Elements(ns + "ItemGroup") .Elements(ns + "ClCompile") .Where(x => cbtGroup.Key.Equals((string)x.Attribute("Include"), StringComparison.InvariantCultureIgnoreCase)); foreach (var cppMocItem in cppMocItems) { cppMocItem.Name = ns + "CustomBuild"; } } //remove .moc.cbt CustomBuild items cbtToRemove.ForEach(x => x.Remove()); //convert moc custom build steps var mocCustomBuilds = GetCustomBuilds(QtMoc.ToolExecName); if (!SetCommandLines(qtMsBuild, configurations, mocCustomBuilds, QtMoc.ItemTypeName, Path.GetDirectoryName(this[Files.Project].filePath))) { Rollback(); return(false); } List <XElement> mocDisableDynamicSource = new List <XElement>(); foreach (var qtMoc in mocCustomBuilds.Elements(ns + QtMoc.ItemTypeName)) { var itemName = (string)qtMoc.Attribute("Include"); var configName = (string)qtMoc.Attribute("ConfigName"); //remove items with generated files var hasGeneratedFiles = RemoveGeneratedFiles( projDir, cbEvals, configName, itemName, projItemsByPath, filterItemsByPath); //set properties qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.ExecutionDescription, "Moc'ing %(Identity)..."); qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.InputFile, "%(FullPath)"); if (!HelperFunctions.IsSourceFile(itemName)) { qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.OutputFile, string.Format(@"{0}\moc_%(Filename).cpp", QtVSIPSettings.GetMocDirectory())); qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.DynamicSource, "output"); if (!hasGeneratedFiles) { mocDisableDynamicSource.Add(qtMoc); } } else { qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.OutputFile, string.Format(@"{0}\%(Filename).moc", QtVSIPSettings.GetMocDirectory())); qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.DynamicSource, "input"); } var includePath = qtMsBuild.GetPropertyChangedValue( QtMoc.Property.IncludePath, itemName, configName); if (!string.IsNullOrEmpty(includePath)) { qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.IncludePath, AddGeneratedFilesPath(includePath)); } } //convert rcc custom build steps var rccCustomBuilds = GetCustomBuilds(QtRcc.ToolExecName); if (!SetCommandLines(qtMsBuild, configurations, rccCustomBuilds, QtRcc.ItemTypeName, Path.GetDirectoryName(this[Files.Project].filePath))) { Rollback(); return(false); } foreach (var qtRcc in rccCustomBuilds.Elements(ns + QtRcc.ItemTypeName)) { var itemName = (string)qtRcc.Attribute("Include"); var configName = (string)qtRcc.Attribute("ConfigName"); //remove items with generated files RemoveGeneratedFiles(projDir, cbEvals, configName, itemName, projItemsByPath, filterItemsByPath); //set properties qtMsBuild.SetItemProperty(qtRcc, QtRcc.Property.ExecutionDescription, "Rcc'ing %(Identity)..."); qtMsBuild.SetItemProperty(qtRcc, QtRcc.Property.InputFile, "%(FullPath)"); qtMsBuild.SetItemProperty(qtRcc, QtRcc.Property.OutputFile, string.Format(@"{0}\qrc_%(Filename).cpp", QtVSIPSettings.GetRccDirectory())); } //convert uic custom build steps var uicCustomBuilds = GetCustomBuilds(QtUic.ToolExecName); if (!SetCommandLines(qtMsBuild, configurations, uicCustomBuilds, QtUic.ItemTypeName, Path.GetDirectoryName(this[Files.Project].filePath))) { Rollback(); return(false); } foreach (var qtUic in uicCustomBuilds.Elements(ns + QtUic.ItemTypeName)) { var itemName = (string)qtUic.Attribute("Include"); var configName = (string)qtUic.Attribute("ConfigName"); //remove items with generated files RemoveGeneratedFiles(projDir, cbEvals, configName, itemName, projItemsByPath, filterItemsByPath); //set properties qtMsBuild.SetItemProperty(qtUic, QtUic.Property.ExecutionDescription, "Uic'ing %(Identity)..."); qtMsBuild.SetItemProperty(qtUic, QtUic.Property.InputFile, "%(FullPath)"); qtMsBuild.SetItemProperty(qtUic, QtUic.Property.OutputFile, string.Format(@"{0}\ui_%(Filename).h", QtVSIPSettings.GetRccDirectory())); } qtMsBuild.EndSetItemProperties(); //disable dynamic C++ source for moc headers without generated files //(needed for the case of #include "moc_foo.cpp" in source file) foreach (var qtMoc in mocDisableDynamicSource) { qtMsBuild.SetItemProperty(qtMoc, QtMoc.Property.DynamicSource, "false"); } FinalizeProjectChanges(mocCustomBuilds.ToList(), QtMoc.ItemTypeName); FinalizeProjectChanges(rccCustomBuilds.ToList(), QtRcc.ItemTypeName); FinalizeProjectChanges(uicCustomBuilds.ToList(), QtUic.ItemTypeName); this[Files.Project].isDirty = this[Files.Filters].isDirty = true; Commit(); return(true); }