string AddGeneratedFilesPath(string includePathList) { HashSet <string> includes = new HashSet <string> { QtVSIPSettings.GetMocDirectory(), QtVSIPSettings.GetRccDirectory(), QtVSIPSettings.GetUicDirectory(), }; foreach (var includePath in includePathList.Split(new char[] { ';' })) { includes.Add(includePath); } return(string.Join <string>(";", includes)); }
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); }
private static ProFileContent CreateProFileContent(Project project) { ProFileOption option; var qtPro = QtProject.Create(project); var content = new ProFileContent(qtPro.VCProject); // hack to get active config var activeConfig = project.ConfigurationManager.ActiveConfiguration.ConfigurationName; var activePlatform = project.ConfigurationManager.ActiveConfiguration.PlatformName; var config = (VCConfiguration)((IVCCollection)qtPro.VCProject.Configurations).Item(activeConfig); var compiler = CompilerToolWrapper.Create(config); var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool"); var libTool = (VCLibrarianTool)((IVCCollection)config.Tools).Item("VCLibrarianTool"); var outPut = config.PrimaryOutput; var fi = new FileInfo(outPut); var destdir = HelperFunctions.GetRelativePath(qtPro.VCProject.ProjectDirectory, fi.DirectoryName); destdir = HelperFunctions.ChangePathFormat(destdir); var target = qtPro.VCProject.Name; option = new ProFileOption("TEMPLATE"); option.Comment = Resources.ec_Template; option.ShortComment = "Template"; option.NewOption = null; // just one option... option.AssignSymbol = ProFileOption.AssignType.AT_Equals; content.Options.Add(option); if (config.ConfigurationType == ConfigurationTypes.typeApplication) { option.List.Add("app"); } else { option.List.Add("lib"); } option = new ProFileOption("TARGET"); option.Comment = Resources.ec_Target; option.ShortComment = "Target Name"; option.NewOption = null; // just one option... option.AssignSymbol = ProFileOption.AssignType.AT_Equals; content.Options.Add(option); option.List.Add(target); option = new ProFileOption("DESTDIR"); option.Comment = Resources.ec_DestDir; option.ShortComment = "Destination Directory"; option.NewOption = null; // just one option... option.AssignSymbol = ProFileOption.AssignType.AT_Equals; content.Options.Add(option); option.List.Add(destdir); // add the qt option option = new ProFileOption("QT"); var optionQT = option; option.Comment = Resources.ec_Qt; option.ShortComment = "Qt Options"; option.NewOption = " "; // just space between the options... content.Options.Add(option); // add the config option option = new ProFileOption("CONFIG"); var optionCONFIG = option; option.Comment = Resources.ec_Config; option.ShortComment = "Config Options"; option.NewOption = " "; // just space between the options... content.Options.Add(option); AddModules(qtPro, optionQT, optionCONFIG); if (config.ConfigurationType == ConfigurationTypes.typeStaticLibrary) { option.List.Add("staticlib"); } if (linker != null) { if (linker.GenerateDebugInformation) { option.List.Add("debug"); } else { option.List.Add("release"); } if (linker.SubSystem == subSystemOption.subSystemConsole) { option.List.Add("console"); } if (linker.AdditionalDependencies != null) { if (linker.AdditionalDependencies.IndexOf("QAxServer", StringComparison.Ordinal) > -1) { option.List.Add("qaxserver"); } else if (linker.AdditionalDependencies.IndexOf("QAxContainer", StringComparison.Ordinal) > -1) { option.List.Add("qaxcontainer"); } else if (linker.AdditionalDependencies.IndexOf("QtHelp", StringComparison.Ordinal) > -1) { option.List.Add("help"); } } } if (qtPro.IsDesignerPluginProject()) { option.List.Add("designer"); option.List.Add("plugin"); } // add defines option = new ProFileOption("DEFINES"); option.Comment = Resources.ec_Defines; option.ShortComment = "Defines"; option.NewOption = " "; option.AssignSymbol = ProFileOption.AssignType.AT_PlusEquals; content.Options.Add(option); AddPreprocessorDefinitions(option, compiler.GetPreprocessorDefinitions()); // add the include path option option = new ProFileOption("INCLUDEPATH"); option.Comment = Resources.ec_IncludePath; option.ShortComment = "Include Path"; content.Options.Add(option); AddIncludePaths(project, option, compiler.GetAdditionalIncludeDirectories()); option = new ProFileOption("LIBS"); option.Comment = Resources.ec_Libs; option.ShortComment = "Additional Libraries"; content.Options.Add(option); if (linker != null) { AddLibraries(project, option, linker.AdditionalLibraryDirectories, linker.AdditionalDependencies); } else if (libTool != null) { AddLibraries(project, option, libTool.AdditionalLibraryDirectories, libTool.AdditionalDependencies); } option = new ProFileOption("PRECOMPILED_HEADER"); option.Comment = Resources.ec_PrecompiledHeader; option.ShortComment = "Using Precompiled Headers"; option.AssignSymbol = ProFileOption.AssignType.AT_Equals; content.Options.Add(option); if (qtPro.UsesPrecompiledHeaders()) { option.List.Add(compiler.GetPrecompiledHeaderThrough()); } // add the depend path option option = new ProFileOption("DEPENDPATH"); option.Comment = Resources.ec_DependPath; option.ShortComment = "Depend Path"; content.Options.Add(option); option.List.Add("."); var mocDir = QtVSIPSettings.GetMocDirectory(project, activeConfig.ToLower(), activePlatform.ToLower()); mocDir = mocDir.Replace('\\', '/'); option = new ProFileOption("MOC_DIR"); option.Comment = Resources.ec_MocDir; option.ShortComment = "Moc Directory"; option.NewOption = null; // just one option... content.Options.Add(option); option.List.Add(mocDir); option = new ProFileOption("OBJECTS_DIR"); option.Comment = Resources.ec_ObjDir; option.ShortComment = "Objects Directory"; option.NewOption = null; // just one option... content.Options.Add(option); option.List.Add(config.ConfigurationName.ToLower()); var uiDir = QtVSIPSettings.GetUicDirectory(project); uiDir = uiDir.Replace('\\', '/'); option = new ProFileOption("UI_DIR"); option.Comment = Resources.ec_UiDir; option.ShortComment = "UI Directory"; option.NewOption = null; // just one option... content.Options.Add(option); option.List.Add(uiDir); var rccDir = QtVSIPSettings.GetRccDirectory(project); rccDir = rccDir.Replace('\\', '/'); option = new ProFileOption("RCC_DIR"); option.Comment = Resources.ec_RccDir; option.ShortComment = "RCC Directory"; option.NewOption = null; // just one option... content.Options.Add(option); option.List.Add(rccDir); // add the include path option option = new ProFileOption("include"); option.Comment = Resources.ec_Include; option.ShortComment = "Include file(s)"; option.IncludeComment = false; // print the comment in the output file option.AssignSymbol = ProFileOption.AssignType.AT_Function; content.Options.Add(option); // add the translation files option = new ProFileOption("TRANSLATIONS"); option.Comment = Resources.ec_Translations; option.ShortComment = "Translation files"; option.IncludeComment = false; content.Options.Add(option); option.List.AddRange(HelperFunctions.GetProjectFiles(project, FilesToList.FL_Translation)); // add the rc file if (File.Exists(qtPro.VCProject.ProjectDirectory + "\\" + project.Name + ".rc")) { option = new ProFileOption("win32:RC_FILE"); option.Comment = Resources.ec_rcFile; option.ShortComment = "Windows resource file"; option.IncludeComment = false; option.AssignSymbol = ProFileOption.AssignType.AT_Equals; content.Options.Add(option); option.List.Add(project.Name + ".rc"); } if (qtPro.IsDesignerPluginProject()) { option = new ProFileOption("target.path"); option.ShortComment = "Install the plugin in the designer plugins directory."; option.IncludeComment = true; option.AssignSymbol = ProFileOption.AssignType.AT_Equals; option.List.Add("$$[QT_INSTALL_PLUGINS]/designer"); content.Options.Add(option); option = new ProFileOption("INSTALLS"); option.IncludeComment = false; option.AssignSymbol = ProFileOption.AssignType.AT_PlusEquals; option.List.Add("target"); content.Options.Add(option); } return(content); }