diff --git a/Prebuild/src/Core/Nodes/OptionsNode.cs b/Prebuild/src/Core/Nodes/OptionsNode.cs index 3ec3732dd9..0c5ada7682 100755 --- a/Prebuild/src/Core/Nodes/OptionsNode.cs +++ b/Prebuild/src/Core/Nodes/OptionsNode.cs @@ -315,6 +315,67 @@ namespace Prebuild.Core.Nodes } } + [OptionNode("EnableDefaultItems")] + private bool m_EnableDefaultItems = true; + + public bool EnableDefaultItems + { + get + { + return m_EnableDefaultItems; + } + set + { + m_EnableDefaultItems = value; + } + } + + [OptionNode("UseCommonOutputDirectory")] + private bool m_UseCommonOutputDirectory = false; + + public bool UseCommonOutputDirectory + { + get + { + return m_UseCommonOutputDirectory; + } + set + { + m_UseCommonOutputDirectory = value; + } + } + + [OptionNode("AppendTargetFrameworkToOutputPath")] + private bool m_AppendTargetFrameworkToOutputPath = true; + + public bool AppendTargetFrameworkToOutputPath + { + get + { + return m_AppendTargetFrameworkToOutputPath; + } + set + { + m_AppendTargetFrameworkToOutputPath = value; + } + } + + [OptionNode("AppendRuntimeIdentifierToOutputPath")] + private bool m_AppendRuntimeIdentifierToOutputPath = true; + + public bool AppendRuntimeIdentifierToOutputPath + { + get + { + return m_AppendRuntimeIdentifierToOutputPath; + } + set + { + m_AppendRuntimeIdentifierToOutputPath = value; + } + } + + [OptionNode("OutputPath")] private string m_OutputPath = "bin/"; diff --git a/Prebuild/src/Core/Targets/VS2017Target.cs b/Prebuild/src/Core/Targets/VS2017Target.cs new file mode 100644 index 0000000000..7c9929b8d4 --- /dev/null +++ b/Prebuild/src/Core/Targets/VS2017Target.cs @@ -0,0 +1,151 @@ +using System; +using System.IO; +using System.Text; + +using Prebuild.Core.Attributes; +using Prebuild.Core.Interfaces; +using Prebuild.Core.Nodes; +using Prebuild.Core.Utilities; +using System.CodeDom.Compiler; + +namespace Prebuild.Core.Targets +{ + + /// + /// + /// + [Target("vs2017")] + public class VS2017Target : VSGenericTarget + { + #region Fields + + string solutionVersion = "12.00"; + string productVersion = "15.9.50"; + string schemaVersion = "2.0"; + string versionName = "Visual Studio 17"; + string name = "vs2017"; + VSVersion version = VSVersion.VS17; + + #endregion + + #region Properties + + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public override string SolutionVersion + { + get + { + return solutionVersion; + } + } + + /// + /// Gets or sets the product version. + /// + /// The product version. + public override string ProductVersion + { + get + { + return productVersion; + } + } + + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public override string SchemaVersion + { + get + { + return schemaVersion; + } + } + + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public override string VersionName + { + get + { + return versionName; + } + } + + /// + /// Gets or sets the version. + /// + /// The version. + public override VSVersion Version + { + get + { + return version; + } + } + + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return name; + } + } + + protected override string GetToolsVersionXml(FrameworkVersion frameworkVersion) + { + switch (frameworkVersion) + { + case FrameworkVersion.v4_8: + case FrameworkVersion.v4_7_2: + case FrameworkVersion.v4_7_1: + case FrameworkVersion.v4_7: + return "ToolsVersion=\"15.0\""; + case FrameworkVersion.v4_6_2: + case FrameworkVersion.v4_6_1: + case FrameworkVersion.v4_6: + return "ToolsVersion=\"14.0\""; + case FrameworkVersion.v4_5_2: + return "ToolsVersion=\"12.0\""; + case FrameworkVersion.v4_5_1: + case FrameworkVersion.v4_5: + case FrameworkVersion.v4_0: + case FrameworkVersion.v3_5: + return "ToolsVersion=\"4.0\""; + case FrameworkVersion.v3_0: + return "ToolsVersion=\"3.0\""; + default: + return "ToolsVersion=\"2.0\""; + } + } + + public override string SolutionTag + { + get { return "# Visual Studio 17"; } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public VS2017Target() + : base() + { + } + + #endregion + } +} \ No newline at end of file diff --git a/Prebuild/src/Core/Targets/VS2019Target.cs b/Prebuild/src/Core/Targets/VS2019Target.cs index 52a08a8f1d..caacfbe3f9 100644 --- a/Prebuild/src/Core/Targets/VS2019Target.cs +++ b/Prebuild/src/Core/Targets/VS2019Target.cs @@ -106,6 +106,10 @@ namespace Prebuild.Core.Targets { switch (frameworkVersion) { + case FrameworkVersion.netstandard2_0: + case FrameworkVersion.net5_0: + case FrameworkVersion.net6_0: + case FrameworkVersion.net7_0: case FrameworkVersion.v4_8: case FrameworkVersion.v4_7_2: return "ToolsVersion=\"16.0\""; diff --git a/Prebuild/src/Core/Targets/VS2022Target.cs b/Prebuild/src/Core/Targets/VS2022Target.cs new file mode 100644 index 0000000000..eec09d144f --- /dev/null +++ b/Prebuild/src/Core/Targets/VS2022Target.cs @@ -0,0 +1,157 @@ +using System; +using System.IO; +using System.Text; + +using Prebuild.Core.Attributes; +using Prebuild.Core.Interfaces; +using Prebuild.Core.Nodes; +using Prebuild.Core.Utilities; +using System.CodeDom.Compiler; + +namespace Prebuild.Core.Targets +{ + + /// + /// + /// + [Target("vs2022")] + public class VS2022Target : VSGenericTarget + { + #region Fields + + string solutionVersion = "12.00"; + string productVersion = "117.3.2"; + string schemaVersion = "2.0"; + string versionName = "Visual Studio Version 17"; + string name = "vs2022"; + VSVersion version = VSVersion.VS22; + + #endregion + + #region Properties + + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public override string SolutionVersion + { + get + { + return solutionVersion; + } + } + + /// + /// Gets or sets the product version. + /// + /// The product version. + public override string ProductVersion + { + get + { + return productVersion; + } + } + + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public override string SchemaVersion + { + get + { + return schemaVersion; + } + } + + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public override string VersionName + { + get + { + return versionName; + } + } + + /// + /// Gets or sets the version. + /// + /// The version. + public override VSVersion Version + { + get + { + return version; + } + } + + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return name; + } + } + + protected override string GetToolsVersionXml(FrameworkVersion frameworkVersion) + { + switch (frameworkVersion) + { + case FrameworkVersion.net5_0: + case FrameworkVersion.net6_0: + case FrameworkVersion.net7_0: + return "ToolsVersion=\"17.0\""; + case FrameworkVersion.netstandard2_0: + case FrameworkVersion.v4_8: + case FrameworkVersion.v4_7_2: + return "ToolsVersion=\"16.0\""; + case FrameworkVersion.v4_7_1: + case FrameworkVersion.v4_7: + return "ToolsVersion=\"15.0\""; + case FrameworkVersion.v4_6_2: + case FrameworkVersion.v4_6_1: + case FrameworkVersion.v4_6: + return "ToolsVersion=\"14.0\""; + case FrameworkVersion.v4_5_2: + return "ToolsVersion=\"12.0\""; + case FrameworkVersion.v4_5_1: + case FrameworkVersion.v4_5: + case FrameworkVersion.v4_0: + case FrameworkVersion.v3_5: + return "ToolsVersion=\"4.0\""; + case FrameworkVersion.v3_0: + return "ToolsVersion=\"3.0\""; + default: + return "ToolsVersion=\"2.0\""; + } + } + + public override string SolutionTag + { + get { return "# Visual Studio 22"; } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public VS2022Target() + : base() + { + } + + #endregion + } +} \ No newline at end of file diff --git a/Prebuild/src/Core/Targets/VSGenericTarget.cs b/Prebuild/src/Core/Targets/VSGenericTarget.cs index e31a90ead4..766c2f4000 100755 --- a/Prebuild/src/Core/Targets/VSGenericTarget.cs +++ b/Prebuild/src/Core/Targets/VSGenericTarget.cs @@ -317,7 +317,6 @@ namespace Prebuild.Core.Targets } - #region Files foreach (string filePath in project.Files) { @@ -674,6 +673,9 @@ namespace Prebuild.Core.Targets private void WriteProjectDotNet(SolutionNode solution, ProjectNode project, StreamWriter ps) { #region Project File + bool listFiles = false; + string prebuild = string.Empty; + string postbuild = string.Empty; using (ps) { ps.WriteLine(""); @@ -681,12 +683,17 @@ namespace Prebuild.Core.Targets ps.WriteLine(" "); ps.WriteLine(" {0}", project.FrameworkVersion.ToString().Replace("_", ".")); + ps.WriteLine(" false"); ps.WriteLine(" {0}", project.Type == ProjectType.Web ? ProjectType.Library.ToString() : project.Type.ToString()); ps.WriteLine(" false"); - ps.WriteLine(" 5.0.0"); + if(project.FrameworkVersion == FrameworkVersion.netstandard2_0) + ps.WriteLine(" 5.0.0"); ps.WriteLine(" disable"); ps.WriteLine(" {0}", project.AssemblyName); ps.WriteLine(" true"); + //ps.WriteLine(" false"); + ps.WriteLine(" false"); + ps.WriteLine(" false"); ps.WriteLine(" "); ps.WriteLine(); @@ -720,6 +727,16 @@ namespace Prebuild.Core.Targets ps.WriteLine(" {0}", conf.Options["FileAlignment"]); ps.WriteLine(" {0}", conf.Options["OptimizeCode"]); ps.WriteLine(" false"); + + ps.WriteLine(" {0}", conf.Options["UseCommonOutputDirectory"].ToString()); + ps.WriteLine(" {0}", conf.Options["AppendTargetFrameworkToOutputPath"].ToString()); + ps.WriteLine(" {0}", conf.Options["AppendRuntimeIdentifierToOutputPath"].ToString()); + if ((bool)conf.Options["EnableDefaultItems"] == false) + { + listFiles = true; + ps.WriteLine(" false"); + } + if (project.Type != ProjectType.Web) ps.WriteLine(" {0}", Helper.EndPath(Helper.NormalizePath(conf.Options["OutputPath"].ToString()))); @@ -734,6 +751,16 @@ namespace Prebuild.Core.Targets ps.WriteLine(" {0}", conf.Options["NoStdLib"]); ps.WriteLine(" {0}", conf.Options["SuppressWarnings"]); ps.WriteLine(" {0}", conf.Platform); + + if (conf.Options["PreBuildEvent"] != null && conf.Options["PreBuildEvent"].ToString().Length != 0) + { + prebuild = conf.Options["PreBuildEvent"].ToString(); + } + if (conf.Options["PostBuildEvent"] != null && conf.Options["PostBuildEvent"].ToString().Length != 0) + { + postbuild = conf.Options["PostBuildEvent"].ToString(); + } + ps.WriteLine(" "); } } @@ -762,6 +789,200 @@ namespace Prebuild.Core.Targets // Output the ItemGroup for project.References WriteProjectReferencesDotNet(solution, project, ps); + if (listFiles) + { + List list = new List(); + ps.WriteLine(" "); + foreach (string filePath in project.Files) + { + // Add the filePath with the destination as the key + // will use it later to form the copy parameters with Include lists + // for each destination + if (project.Files.GetBuildAction(filePath) == BuildAction.Copy) + continue; + // if (file == "Properties\\Bind.Designer.cs") + // { + // Console.WriteLine("Wait a minute!"); + // Console.WriteLine(project.Files.GetSubType(file).ToString()); + // } + SubType subType = project.Files.GetSubType(filePath); + + // Visual Studio chokes on file names if forward slash is used as a path separator + // instead of backslash. So we must make sure that all file paths written to the + // project file use \ as a path separator. + string file = filePath.Replace(@"/", @"\"); + + if (subType != SubType.Code && subType != SubType.Settings && subType != SubType.Designer + && subType != SubType.CodeBehind) + { + ps.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); + ps.WriteLine(" {0}", Path.GetFileName(file)); + ps.WriteLine(" Designer"); + ps.WriteLine(" "); + // + } + + if (subType == SubType.Designer) + { + ps.WriteLine(" ", file); + + string autogen_name = file.Substring(0, file.LastIndexOf('.')) + ".Designer.cs"; + string dependent_name = filePath.Substring(0, file.LastIndexOf('.')) + ".cs"; + + // Check for a parent .cs file with the same name as this designer file + if (File.Exists(Helper.NormalizePath(dependent_name))) + { + ps.WriteLine(" {0}", Path.GetFileName(dependent_name)); + } + else + { + ps.WriteLine(" ResXFileCodeGenerator"); + ps.WriteLine(" {0}", Path.GetFileName(autogen_name)); + ps.WriteLine(" " + subType + ""); + } + + ps.WriteLine(" "); + if (File.Exists(Helper.NormalizePath(autogen_name))) + { + ps.WriteLine(" ", autogen_name); + //ps.WriteLine(" True"); + + // If a parent .cs file exists, link this autogen file to it. Otherwise link + // to the designer file + if (File.Exists(dependent_name)) + { + ps.WriteLine(" {0}", Path.GetFileName(dependent_name)); + } + else + { + ps.WriteLine(" True"); + ps.WriteLine(" {0}", Path.GetFileName(filePath)); + } + + ps.WriteLine(" "); + } + list.Add(autogen_name); + } + if (subType == SubType.Settings) + { + ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); + ps.WriteLine("Include=\"{0}\">", file); + string fileName = Path.GetFileName(filePath); + if (project.Files.GetBuildAction(filePath) == BuildAction.None) + { + ps.WriteLine(" SettingsSingleFileGenerator"); + ps.WriteLine(" {0}", fileName.Substring(0, fileName.LastIndexOf('.')) + ".Designer.cs"); + } + else + { + ps.WriteLine(" Code"); + ps.WriteLine(" True"); + ps.WriteLine(" True"); + string fileNameShort = fileName.Substring(0, fileName.LastIndexOf('.')); + string fileNameShorter = fileNameShort.Substring(0, fileNameShort.LastIndexOf('.')); + ps.WriteLine(" {0}", Path.GetFileName(fileNameShorter + ".settings")); + } + ps.WriteLine(" ", project.Files.GetBuildAction(filePath)); + } + else if (subType != SubType.Designer) + { + string path = Helper.NormalizePath(file); + string path_lower = path.ToLower(); + + if (!list.Contains(filePath)) + { + ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); + + int startPos = 0; + if (project.Files.GetPreservePath(filePath)) + { + while ((@"./\").IndexOf(file.Substring(startPos, 1)) != -1) + startPos++; + + } + else + { + startPos = file.LastIndexOf(Path.GetFileName(path)); + } + + // be sure to write out the path with backslashes so VS recognizes + // the file properly. + ps.WriteLine("Include=\"{0}\">", file); + + int last_period_index = file.LastIndexOf('.'); + string short_file_name = (last_period_index >= 0) + ? file.Substring(0, last_period_index) + : file; + string extension = Path.GetExtension(path); + // make this upper case, so that when File.Exists tests for the + // existence of a designer file on a case-sensitive platform, + // it is correctly identified. + string designer_format = string.Format(".Designer{0}", extension); + + if (path_lower.EndsWith(designer_format.ToLowerInvariant())) + { + int designer_index = path.IndexOf(designer_format); + string file_name = path.Substring(0, designer_index); + + // There are two corrections to the next lines: + // 1. Fix the connection between a designer file and a form + // or usercontrol that don't have an associated resx file. + // 2. Connect settings files to associated designer files. + if (File.Exists(file_name + extension)) + ps.WriteLine(" {0}", Path.GetFileName(file_name + extension)); + else if (File.Exists(file_name + ".resx")) + ps.WriteLine(" {0}", Path.GetFileName(file_name + ".resx")); + else if (File.Exists(file_name + ".settings")) + { + ps.WriteLine(" {0}", Path.GetFileName(file_name + ".settings")); + ps.WriteLine(" True"); + ps.WriteLine(" True"); + } + } + else if (subType == SubType.CodeBehind) + { + ps.WriteLine(" {0}", Path.GetFileName(short_file_name)); + } + if (project.Files.GetIsLink(filePath)) + { + string alias = project.Files.GetLinkPath(filePath); + alias += file.Substring(startPos); + alias = Helper.NormalizePath(alias); + ps.WriteLine(" {0}", alias); + } + else if (project.Files.GetBuildAction(filePath) != BuildAction.None) + { + if (project.Files.GetBuildAction(filePath) != BuildAction.EmbeddedResource) + { + ps.WriteLine(" {0}", subType); + } + } + + if (project.Files.GetCopyToOutput(filePath) != CopyToOutput.Never) + { + ps.WriteLine(" {0}", project.Files.GetCopyToOutput(filePath)); + } + + ps.WriteLine(" ", project.Files.GetBuildAction(filePath)); + } + } + } + ps.WriteLine(" "); + } + + if (!string.IsNullOrEmpty(prebuild)) + { + ps.WriteLine(" "); + ps.WriteLine(" ", prebuild); + ps.WriteLine(" "); + } + if (!string.IsNullOrEmpty(postbuild)) + { + ps.WriteLine(" "); + ps.WriteLine(" ", postbuild); + ps.WriteLine(" "); + } + ps.WriteLine(""); #endregion @@ -790,6 +1011,7 @@ namespace Prebuild.Core.Targets foreach (ReferenceNode refr in otherReferences) { ps.Write(" "); @@ -1166,6 +1388,9 @@ namespace Prebuild.Core.Targets Helper.DeleteIfExists(projectFile); Helper.DeleteIfExists(userFile); + + string projectobj = Helper.MakeFilePath(project.FullPath,"obj"); + Helper.DeleteFolderIfExists(projectobj); } private void CleanSolution(SolutionNode solution) diff --git a/Prebuild/src/Core/Targets/VSVersion.cs b/Prebuild/src/Core/Targets/VSVersion.cs index 0958cce693..857e2d876f 100644 --- a/Prebuild/src/Core/Targets/VSVersion.cs +++ b/Prebuild/src/Core/Targets/VSVersion.cs @@ -63,6 +63,7 @@ namespace Prebuild.Core.Targets /// VS15, VS17, - VS19 + VS19, + VS22 } } diff --git a/Prebuild/src/Core/Utilities/Helper.cs b/Prebuild/src/Core/Utilities/Helper.cs index 6e5a3fa5a0..5976730503 100644 --- a/Prebuild/src/Core/Utilities/Helper.cs +++ b/Prebuild/src/Core/Utilities/Helper.cs @@ -232,6 +232,27 @@ namespace Prebuild.Core.Utilities return true; } + public static bool DeleteFolderIfExists(string file) + { + string resFile = null; + try + { + resFile = ResolvePath(file); + } + catch (ArgumentException) + { + return false; + } + + if (!Directory.Exists(resFile)) + { + return false; + } + + Directory.Delete(resFile, true); + return true; + } + static readonly char seperator = Path.DirectorySeparatorChar; // This little gem was taken from the NeL source, thanks guys! diff --git a/Prebuild/src/data/prebuild-1.10.xsd b/Prebuild/src/data/prebuild-1.10.xsd index ddfa2c5689..4136d9f076 100644 --- a/Prebuild/src/data/prebuild-1.10.xsd +++ b/Prebuild/src/data/prebuild-1.10.xsd @@ -187,8 +187,8 @@ - - + + @@ -214,6 +214,10 @@ + + + + diff --git a/bin/Prebuild.exe b/bin/Prebuild.exe index 1e4ef3fd66..3a050f088a 100755 Binary files a/bin/Prebuild.exe and b/bin/Prebuild.exe differ