aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Costa <miguel.costa@qt.io>2019-04-05 14:36:42 +0200
committerMiguel Costa <miguel.costa@qt.io>2019-05-08 10:59:33 +0000
commit1e0431d2fb4a52916e1697bc7033e67c0d33a407 (patch)
tree6540f6a50ddc47dfe269e13f95f664eae6f2db44
parent2e3834f664a8fe0a88d6bf0f5374210970ebd2b8 (diff)
Import qmake projects with repc custom builds
When generating the .vcxproj for a project that includes remote object templates, qmake will add a custom build step for those templates. For the "Import .pro file" feature, this custom build must be converted to a corresponding Qt/MSBuild item. Change-Id: If0fb34e069f050be3265bf81639cc69a5cbff3fe Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
-rw-r--r--src/qtprojectlib/MsBuildProject.cs30
-rw-r--r--src/qtprojectlib/QtMsBuild.cs259
-rw-r--r--src/qtprojectlib/QtProject.cs11
3 files changed, 283 insertions, 17 deletions
diff --git a/src/qtprojectlib/MsBuildProject.cs b/src/qtprojectlib/MsBuildProject.cs
index aa0ab1aa..21aa3c94 100644
--- a/src/qtprojectlib/MsBuildProject.cs
+++ b/src/qtprojectlib/MsBuildProject.cs
@@ -491,7 +491,7 @@ namespace QtProjectLib
var projItemsByPath = this[Files.Project].xml
.Elements(ns + "Project")
.Elements(ns + "ItemGroup")
- .Elements(ns + "ClCompile")
+ .Elements()
.Where(x => ((string)x.Attribute("Include"))
.IndexOfAny(Path.GetInvalidPathChars()) == -1)
.GroupBy(x => HelperFunctions.CanonicalPath(
@@ -502,7 +502,7 @@ namespace QtProjectLib
var filterItemsByPath = this[Files.Filters].xml
.Elements(ns + "Project")
.Elements(ns + "ItemGroup")
- .Elements(ns + "ClCompile")
+ .Elements()
.Where(x => ((string)x.Attribute("Include"))
.IndexOfAny(Path.GetInvalidPathChars()) == -1)
.GroupBy(x => HelperFunctions.CanonicalPath(
@@ -662,6 +662,31 @@ namespace QtProjectLib
QtRcc.Property.InputFile, "%(FullPath)");
}
+ //convert repc custom build steps
+ var repcCustomBuilds = GetCustomBuilds(QtRepc.ToolExecName);
+ if (!SetCommandLines(qtMsBuild, configurations, repcCustomBuilds,
+ QtRepc.ToolExecName, QtRepc.ItemTypeName,
+ Path.GetDirectoryName(this[Files.Project].filePath),
+ new ItemCommandLineReplacement[] { })) {
+ Rollback();
+ return false;
+ }
+ foreach (var qtRepc in repcCustomBuilds.Elements(ns + QtRepc.ItemTypeName)) {
+ var itemName = (string)qtRepc.Attribute("Include");
+ var configName = (string)qtRepc.Attribute("ConfigName");
+
+ //remove items with generated files
+ RemoveGeneratedFiles(projDir, cbEvals, configName, itemName,
+ projItemsByPath, filterItemsByPath);
+
+ //set properties
+ qtMsBuild.SetItemProperty(qtRepc,
+ QtRepc.Property.ExecutionDescription, "Repc'ing %(Identity)...");
+ qtMsBuild.SetItemProperty(qtRepc,
+ QtRepc.Property.InputFile, "%(FullPath)");
+ }
+
+
//convert uic custom build steps
var uicCustomBuilds = GetCustomBuilds(QtUic.ToolExecName);
if (!SetCommandLines(qtMsBuild, configurations, uicCustomBuilds,
@@ -702,6 +727,7 @@ namespace QtProjectLib
FinalizeProjectChanges(mocCustomBuilds.ToList(), QtMoc.ItemTypeName);
FinalizeProjectChanges(rccCustomBuilds.ToList(), QtRcc.ItemTypeName);
+ FinalizeProjectChanges(repcCustomBuilds.ToList(), QtRepc.ItemTypeName);
FinalizeProjectChanges(uicCustomBuilds.ToList(), QtUic.ItemTypeName);
this[Files.Project].isDirty = this[Files.Filters].isDirty = true;
diff --git a/src/qtprojectlib/QtMsBuild.cs b/src/qtprojectlib/QtMsBuild.cs
index 0a83fadf..009176d6 100644
--- a/src/qtprojectlib/QtMsBuild.cs
+++ b/src/qtprojectlib/QtMsBuild.cs
@@ -416,6 +416,18 @@ namespace QtProjectLib.QtMsBuild
}
public string GetPropertyChangedValue(
+ QtRepc.Property property,
+ string itemName,
+ string configName)
+ {
+ return GetPropertyChangedValue(
+ configName,
+ QtRepc.ItemTypeName,
+ itemName,
+ property.ToString());
+ }
+
+ public string GetPropertyChangedValue(
QtUic.Property property,
string itemName,
string configName)
@@ -438,6 +450,8 @@ namespace QtProjectLib.QtMsBuild
return SetQtMocCommandLine(propertyStorage, commandLine, macros);
case QtRcc.ItemTypeName:
return SetQtRccCommandLine(propertyStorage, commandLine, macros);
+ case QtRepc.ItemTypeName:
+ return SetQtRepcCommandLine(propertyStorage, commandLine, macros);
case QtUic.ItemTypeName:
return SetQtUicCommandLine(propertyStorage, commandLine, macros);
}
@@ -542,6 +556,55 @@ namespace QtProjectLib.QtMsBuild
}
#endregion
+ #region QtRepc
+ static QtRepc qtRepcInstance;
+ public static QtRepc QtRepcInstance
+ {
+ get
+ {
+ if (qtRepcInstance == null)
+ qtRepcInstance = new QtRepc();
+ return qtRepcInstance;
+ }
+ }
+
+ public string GetPropertyValue(object propertyStorage, QtRepc.Property property)
+ {
+ return GetPropertyValueByName(
+ propertyStorage,
+ QtRepc.ItemTypeName,
+ property.ToString());
+ }
+
+ public bool SetItemProperty(
+ object propertyStorage,
+ QtRepc.Property property,
+ string propertyValue)
+ {
+ return SetItemPropertyByName(propertyStorage, property.ToString(), propertyValue);
+ }
+
+ public bool SetQtRepcCommandLine(
+ object propertyStorage,
+ string commandLine,
+ IVSMacroExpander macros)
+ {
+ Dictionary<QtRepc.Property, string> properties;
+ if (!QtRepcInstance.ParseCommandLine(commandLine, macros, out properties))
+ return false;
+ foreach (var property in properties) {
+ if (!SetItemProperty(propertyStorage, property.Key, property.Value))
+ return false;
+ }
+ return true;
+ }
+
+ public string GenerateQtRepcCommandLine(object propertyStorage)
+ {
+ return QtRepcInstance.GenerateCommandLine(this, propertyStorage);
+ }
+ #endregion
+
#region QtUic
static QtUic qtUicInstance;
public static QtUic QtUicInstance
@@ -600,7 +663,7 @@ namespace QtProjectLib.QtMsBuild
protected CommandLineOption helpOption;
protected CommandLineOption versionOption;
- protected QtTool()
+ protected QtTool(bool defaultInputOutput = true)
{
parser = new CommandLineParser();
parser.SetSingleDashWordOptionMode(
@@ -609,10 +672,29 @@ namespace QtProjectLib.QtMsBuild
helpOption = parser.AddHelpOption();
versionOption = parser.AddVersionOption();
- outputOption = new CommandLineOption("o");
- outputOption.ValueName = "file";
- outputOption.Flags = CommandLineOption.Flag.ShortOptionStyle;
- parser.AddOption(outputOption);
+ if (defaultInputOutput) {
+ outputOption = new CommandLineOption("o");
+ outputOption.ValueName = "file";
+ outputOption.Flags = CommandLineOption.Flag.ShortOptionStyle;
+ parser.AddOption(outputOption);
+ }
+ }
+
+ protected virtual void ExtractInputOutput(
+ string toolExecName,
+ out string inputPath,
+ out string outputPath)
+ {
+ inputPath = outputPath = "";
+
+ string filePath = parser.PositionalArguments.Where(
+ arg => !arg.EndsWith(toolExecName, StringComparison.InvariantCultureIgnoreCase))
+ .FirstOrDefault();
+ if (!string.IsNullOrEmpty(filePath))
+ inputPath = filePath;
+
+ if (outputOption != null && parser.IsSet(outputOption))
+ outputPath = parser.Value(outputOption);
}
protected bool ParseCommandLine(
@@ -636,15 +718,7 @@ namespace QtProjectLib.QtMsBuild
qtDir = HelperFunctions.CanonicalPath(Path.Combine(execDir, ".."));
}
- string filePath = parser.PositionalArguments.Where(
- arg => !arg.EndsWith(toolExecName, StringComparison.InvariantCultureIgnoreCase))
- .FirstOrDefault();
- if (!string.IsNullOrEmpty(filePath))
- inputPath = filePath;
-
- if (parser.IsSet(outputOption))
- outputPath = parser.Value(outputOption);
-
+ ExtractInputOutput(toolExecName, out inputPath, out outputPath);
return true;
}
@@ -1180,6 +1254,163 @@ namespace QtProjectLib.QtMsBuild
}
}
+ public sealed class QtRepc : QtTool
+ {
+ public const string ItemTypeName = "QtRepc";
+ public const string ToolExecName = "repc.exe";
+
+ public enum Property
+ {
+ ExecutionDescription,
+ QTDIR,
+ InputFileType,
+ InputFile,
+ OutputFileType,
+ OutputFile,
+ IncludePath,
+ AlwaysClass,
+ PrintDebug,
+ }
+
+ Dictionary<Property, CommandLineOption> options
+ = new Dictionary<Property, CommandLineOption>();
+
+ public QtRepc() : base(defaultInputOutput: false)
+ {
+ parser.AddOption(options[Property.InputFileType] =
+ new CommandLineOption("i")
+ {
+ ValueName = "<rep|src>",
+ Flags = CommandLineOption.Flag.ShortOptionStyle
+ });
+
+ parser.AddOption(options[Property.OutputFileType] =
+ new CommandLineOption("o")
+ {
+ ValueName = "<source|replica|merged|rep>",
+ Flags = CommandLineOption.Flag.ShortOptionStyle
+ });
+
+ parser.AddOption(options[Property.IncludePath] =
+ new CommandLineOption("I")
+ {
+ ValueName = "dir",
+ Flags = CommandLineOption.Flag.ShortOptionStyle
+ });
+
+ parser.AddOption(options[Property.AlwaysClass] =
+ new CommandLineOption("c"));
+
+ parser.AddOption(options[Property.PrintDebug] =
+ new CommandLineOption("d"));
+ }
+
+ protected override void ExtractInputOutput(
+ string toolExecName,
+ out string inputPath,
+ out string outputPath)
+ {
+ inputPath = outputPath = "";
+
+ var args = new Queue<string>(parser.PositionalArguments
+ .Where(arg => !arg.EndsWith(toolExecName,
+ StringComparison.InvariantCultureIgnoreCase)));
+
+ if (args.Any())
+ inputPath = args.Dequeue();
+
+ if (args.Any())
+ outputPath = args.Dequeue();
+ }
+
+ public bool ParseCommandLine(
+ string commandLine,
+ IVSMacroExpander macros,
+ out Dictionary<Property, string> properties)
+ {
+ properties = new Dictionary<Property, string>();
+
+ string qtDir, inputPath, outputPath;
+ if (!ParseCommandLine(
+ commandLine,
+ macros,
+ ToolExecName,
+ out qtDir,
+ out inputPath,
+ out outputPath)) {
+ return false;
+ }
+
+ if (!string.IsNullOrEmpty(qtDir))
+ properties[Property.QTDIR] = qtDir;
+
+ if (parser.IsSet(options[Property.InputFileType])) {
+ properties[Property.InputFileType] =
+ string.Join(";", parser.Values(options[Property.InputFileType]));
+ }
+
+ if (!string.IsNullOrEmpty(inputPath))
+ properties[Property.InputFile] = inputPath;
+
+ if (parser.IsSet(options[Property.OutputFileType])) {
+ properties[Property.OutputFileType] =
+ string.Join(";", parser.Values(options[Property.OutputFileType]));
+ }
+
+ if (!string.IsNullOrEmpty(outputPath))
+ properties[Property.OutputFile] = outputPath;
+
+ if (parser.IsSet(options[Property.IncludePath])) {
+ properties[Property.IncludePath] =
+ string.Join(";", parser.Values(options[Property.IncludePath]));
+ }
+
+ if (parser.IsSet(options[Property.AlwaysClass]))
+ properties[Property.AlwaysClass] = "true";
+
+ if (parser.IsSet(options[Property.PrintDebug]))
+ properties[Property.PrintDebug] = "true";
+
+ return true;
+ }
+
+ public string GenerateCommandLine(QtMsBuildContainer container, object propertyStorage)
+ {
+ var cmd = new StringBuilder();
+ cmd.AppendFormat(@"""{0}\bin\{1}""",
+ container.GetPropertyValue(propertyStorage, Property.QTDIR), ToolExecName);
+
+ var inputType = container.GetPropertyValue(propertyStorage, Property.InputFileType);
+ if (!string.IsNullOrEmpty(inputType))
+ GenerateCommandLineOption(cmd, options[Property.InputFileType], inputType);
+
+ var outputType = container.GetPropertyValue(propertyStorage, Property.OutputFileType);
+ if (!string.IsNullOrEmpty(inputType))
+ GenerateCommandLineOption(cmd, options[Property.InputFileType], inputType);
+
+ string value = container.GetPropertyValue(propertyStorage, Property.IncludePath);
+ if (!string.IsNullOrEmpty(value))
+ GenerateCommandLineOption(cmd, options[Property.IncludePath], value, true);
+
+ if (container.GetPropertyValue(propertyStorage, Property.AlwaysClass) == "true")
+ GenerateCommandLineOption(cmd, options[Property.AlwaysClass]);
+
+ if (container.GetPropertyValue(propertyStorage, Property.PrintDebug) == "true")
+ GenerateCommandLineOption(cmd, options[Property.PrintDebug]);
+
+ value = container.GetPropertyValue(propertyStorage, Property.InputFile);
+ if (!string.IsNullOrEmpty(value))
+ cmd.AppendFormat(" \"{0}\"", value);
+
+ value = container.GetPropertyValue(propertyStorage, Property.OutputFile);
+ if (!string.IsNullOrEmpty(value))
+ cmd.AppendFormat(" \"{0}\"", value);
+
+ return cmd.ToString();
+ }
+
+ }
+
public sealed class QtUic : QtTool
{
public const string ItemTypeName = "QtUic";
diff --git a/src/qtprojectlib/QtProject.cs b/src/qtprojectlib/QtProject.cs
index bf7bf135..56cf246f 100644
--- a/src/qtprojectlib/QtProject.cs
+++ b/src/qtprojectlib/QtProject.cs
@@ -3868,7 +3868,7 @@ namespace QtProjectLib
VCCustomBuildTool tool;
VCMacroExpander macros;
- enum FileItemType { Other = 0, CustomBuild, QtMoc, QtRcc, QtUic };
+ enum FileItemType { Other = 0, CustomBuild, QtMoc, QtRcc, QtRepc, QtUic };
FileItemType itemType = FileItemType.Other;
public QtCustomBuildTool(VCFileConfiguration vcConfig, QtMsBuildContainer container = null)
{
@@ -3886,6 +3886,8 @@ namespace QtProjectLib
itemType = FileItemType.QtMoc;
else if (vcFile.ItemType == QtRcc.ItemTypeName)
itemType = FileItemType.QtRcc;
+ else if (vcFile.ItemType == QtRepc.ItemTypeName)
+ itemType = FileItemType.QtRepc;
else if (vcFile.ItemType == QtUic.ItemTypeName)
itemType = FileItemType.QtUic;
}
@@ -3905,6 +3907,8 @@ namespace QtProjectLib
return qtMsBuild.GenerateQtMocCommandLine(vcConfig);
case FileItemType.QtRcc:
return qtMsBuild.GenerateQtRccCommandLine(vcConfig);
+ case FileItemType.QtRepc:
+ return qtMsBuild.GenerateQtRepcCommandLine(vcConfig);
case FileItemType.QtUic:
return qtMsBuild.GenerateQtUicCommandLine(vcConfig);
}
@@ -3923,6 +3927,9 @@ namespace QtProjectLib
case FileItemType.QtRcc:
qtMsBuild.SetQtRccCommandLine(vcConfig, value, macros);
break;
+ case FileItemType.QtRepc:
+ qtMsBuild.SetQtRepcCommandLine(vcConfig, value, macros);
+ break;
case FileItemType.QtUic:
qtMsBuild.SetQtUicCommandLine(vcConfig, value, macros);
break;
@@ -3941,6 +3948,8 @@ namespace QtProjectLib
return qtMsBuild.GetPropertyValue(vcConfig, QtMoc.Property.OutputFile);
case FileItemType.QtRcc:
return qtMsBuild.GetPropertyValue(vcConfig, QtRcc.Property.OutputFile);
+ case FileItemType.QtRepc:
+ return qtMsBuild.GetPropertyValue(vcConfig, QtRepc.Property.OutputFile);
case FileItemType.QtUic:
return qtMsBuild.GetPropertyValue(vcConfig, QtUic.Property.OutputFile);
}