aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.BuildTasks/CreateProjectReferenceDefineConstants.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2018-07-19 00:58:00 -0700
committerRob Mensching <rob@firegiant.com>2018-07-21 07:36:59 -0700
commit2724cfee4c163f3297ee25edfd2372767cfd4945 (patch)
tree8cdda34c83bea014a586a491e3b4b187ad8f16da /src/WixToolset.BuildTasks/CreateProjectReferenceDefineConstants.cs
parent4d40bef9cf51b8cff7e1f6a73fdf68b9722eb8a0 (diff)
downloadwix-2724cfee4c163f3297ee25edfd2372767cfd4945.tar.gz
wix-2724cfee4c163f3297ee25edfd2372767cfd4945.tar.bz2
wix-2724cfee4c163f3297ee25edfd2372767cfd4945.zip
Move tool projects to Tools repo
Diffstat (limited to 'src/WixToolset.BuildTasks/CreateProjectReferenceDefineConstants.cs')
-rw-r--r--src/WixToolset.BuildTasks/CreateProjectReferenceDefineConstants.cs271
1 files changed, 0 insertions, 271 deletions
diff --git a/src/WixToolset.BuildTasks/CreateProjectReferenceDefineConstants.cs b/src/WixToolset.BuildTasks/CreateProjectReferenceDefineConstants.cs
deleted file mode 100644
index 7cda6b01..00000000
--- a/src/WixToolset.BuildTasks/CreateProjectReferenceDefineConstants.cs
+++ /dev/null
@@ -1,271 +0,0 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.BuildTasks
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.IO;
9 using Microsoft.Build.Framework;
10 using Microsoft.Build.Utilities;
11
12 /// <summary>
13 /// An MSBuild task to create a list of preprocessor defines to be passed to candle from the
14 /// list of referenced projects.
15 /// </summary>
16 public sealed class CreateProjectReferenceDefineConstants : Task
17 {
18 private ITaskItem[] defineConstants;
19 private ITaskItem[] projectConfigurations;
20 private ITaskItem[] projectReferencePaths;
21
22 [Output]
23 public ITaskItem[] DefineConstants
24 {
25 get { return this.defineConstants; }
26 }
27
28 [Required]
29 public ITaskItem[] ProjectReferencePaths
30 {
31 get { return this.projectReferencePaths; }
32 set { this.projectReferencePaths = value; }
33 }
34
35 public ITaskItem[] ProjectConfigurations
36 {
37 get { return this.projectConfigurations; }
38 set { this.projectConfigurations = value; }
39 }
40
41 public override bool Execute()
42 {
43 List<ITaskItem> outputItems = new List<ITaskItem>();
44 Dictionary<string, string> defineConstants = new Dictionary<string, string>();
45
46 for (int i = 0; i < this.ProjectReferencePaths.Length; i++)
47 {
48 ITaskItem item = this.ProjectReferencePaths[i];
49
50 string configuration = item.GetMetadata("Configuration");
51 string fullConfiguration = item.GetMetadata("FullConfiguration");
52 string platform = item.GetMetadata("Platform");
53
54 string projectPath = CreateProjectReferenceDefineConstants.GetProjectPath(this.ProjectReferencePaths, i);
55 string projectDir = Path.GetDirectoryName(projectPath) + Path.DirectorySeparatorChar;
56 string projectExt = Path.GetExtension(projectPath);
57 string projectFileName = Path.GetFileName(projectPath);
58 string projectName = Path.GetFileNameWithoutExtension(projectPath);
59
60 string referenceName = CreateProjectReferenceDefineConstants.GetReferenceName(item, projectName);
61
62 string targetPath = item.GetMetadata("FullPath");
63 string targetDir = Path.GetDirectoryName(targetPath) + Path.DirectorySeparatorChar;
64 string targetExt = Path.GetExtension(targetPath);
65 string targetFileName = Path.GetFileName(targetPath);
66 string targetName = Path.GetFileNameWithoutExtension(targetPath);
67
68 // If there is no configuration metadata on the project reference task item,
69 // check for any additional configuration data provided in the optional task property.
70 if (String.IsNullOrEmpty(fullConfiguration))
71 {
72 fullConfiguration = this.FindProjectConfiguration(projectName);
73 if (!String.IsNullOrEmpty(fullConfiguration))
74 {
75 string[] typeAndPlatform = fullConfiguration.Split('|');
76 configuration = typeAndPlatform[0];
77 platform = (typeAndPlatform.Length > 1 ? typeAndPlatform[1] : String.Empty);
78 }
79 }
80
81 // write out the platform/configuration defines
82 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.Configuration", referenceName)] = configuration;
83 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.FullConfiguration", referenceName)] = fullConfiguration;
84 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.Platform", referenceName)] = platform;
85
86 // write out the ProjectX defines
87 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.ProjectDir", referenceName)] = projectDir;
88 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.ProjectExt", referenceName)] = projectExt;
89 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.ProjectFileName", referenceName)] = projectFileName;
90 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.ProjectName", referenceName)] = projectName;
91 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.ProjectPath", referenceName)] = projectPath;
92
93 // write out the TargetX defines
94 string targetDirDefine = String.Format(CultureInfo.InvariantCulture, "{0}.TargetDir", referenceName);
95 if (defineConstants.ContainsKey(targetDirDefine))
96 {
97 //if target dir was already defined, redefine it as the common root shared by multiple references from the same project
98 string commonDir = FindCommonRoot(targetDir, defineConstants[targetDirDefine]);
99 if (!String.IsNullOrEmpty(commonDir))
100 {
101 targetDir = commonDir;
102 }
103 }
104 defineConstants[targetDirDefine] = CreateProjectReferenceDefineConstants.EnsureEndsWithBackslash(targetDir);
105
106 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.TargetExt", referenceName)] = targetExt;
107 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.TargetFileName", referenceName)] = targetFileName;
108 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.TargetName", referenceName)] = targetName;
109
110 //if target path was already defined, append to it creating a list of multiple references from the same project
111 string targetPathDefine = String.Format(CultureInfo.InvariantCulture, "{0}.TargetPath", referenceName);
112 if (defineConstants.ContainsKey(targetPathDefine))
113 {
114 string oldTargetPath = defineConstants[targetPathDefine];
115 if (!targetPath.Equals(oldTargetPath, StringComparison.OrdinalIgnoreCase))
116 {
117 defineConstants[targetPathDefine] += ";" + targetPath;
118 }
119
120 //If there was only one targetpath we need to create its culture specific define
121 if (!oldTargetPath.Contains(";"))
122 {
123 string oldSubFolder = FindSubfolder(oldTargetPath, targetDir, targetFileName);
124 if (!String.IsNullOrEmpty(oldSubFolder))
125 {
126 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.{1}.TargetPath", referenceName, oldSubFolder.Replace('\\', '_'))] = oldTargetPath;
127 }
128 }
129
130 // Create a culture specific define
131 string subFolder = FindSubfolder(targetPath, targetDir, targetFileName);
132 if (!String.IsNullOrEmpty(subFolder))
133 {
134 defineConstants[String.Format(CultureInfo.InvariantCulture, "{0}.{1}.TargetPath", referenceName, subFolder.Replace('\\', '_'))] = targetPath;
135 }
136
137 }
138 else
139 {
140 defineConstants[targetPathDefine] = targetPath;
141 }
142 }
143
144 foreach (KeyValuePair<string, string> define in defineConstants)
145 {
146 outputItems.Add(new TaskItem(String.Format(CultureInfo.InvariantCulture, "{0}={1}", define.Key, define.Value)));
147 }
148
149 this.defineConstants = outputItems.ToArray();
150
151 return true;
152 }
153
154 public static string GetProjectPath(ITaskItem[] projectReferencePaths, int i)
155 {
156 return projectReferencePaths[i].GetMetadata("MSBuildSourceProjectFile");
157 }
158
159 public static string GetReferenceName(ITaskItem item, string projectName)
160 {
161 string referenceName = item.GetMetadata("Name");
162 if (String.IsNullOrEmpty(referenceName))
163 {
164 referenceName = projectName;
165 }
166
167 // We cannot have an equals sign in the variable name because it
168 // messes with the preprocessor definitions on the command line.
169 referenceName = referenceName.Replace('=', '_');
170
171 // We cannot have a double quote on the command line because it
172 // there is no way to escape it on the command line.
173 referenceName = referenceName.Replace('\"', '_');
174
175 // We cannot have parens in the variable name because the WiX
176 // preprocessor will not be able to parse it.
177 referenceName = referenceName.Replace('(', '_');
178 referenceName = referenceName.Replace(')', '_');
179
180 return referenceName;
181 }
182
183 /// <summary>
184 /// Look through the configuration data in the ProjectConfigurations property
185 /// to find the configuration for a project, if available.
186 /// </summary>
187 /// <param name="projectName">Name of the project that is being searched for.</param>
188 /// <returns>Full configuration spec, for example "Release|Win32".</returns>
189 private string FindProjectConfiguration(string projectName)
190 {
191 string configuration = String.Empty;
192
193 if (this.ProjectConfigurations != null)
194 {
195 foreach (ITaskItem configItem in this.ProjectConfigurations)
196 {
197 string configProject = configItem.ItemSpec;
198 if (configProject.Length > projectName.Length &&
199 configProject.StartsWith(projectName) &&
200 configProject[projectName.Length] == '=')
201 {
202 configuration = configProject.Substring(projectName.Length + 1);
203 break;
204 }
205 }
206 }
207
208 return configuration;
209 }
210
211 /// <summary>
212 /// Finds the common root between two paths
213 /// </summary>
214 /// <param name="path1"></param>
215 /// <param name="path2"></param>
216 /// <returns>common root on success, empty string on failure</returns>
217 private static string FindCommonRoot(string path1, string path2)
218 {
219 path1 = path1.TrimEnd(Path.DirectorySeparatorChar);
220 path2 = path2.TrimEnd(Path.DirectorySeparatorChar);
221
222 while (!String.IsNullOrEmpty(path1))
223 {
224 for (string searchPath = path2; !String.IsNullOrEmpty(searchPath); searchPath = Path.GetDirectoryName(searchPath))
225 {
226 if (path1.Equals(searchPath, StringComparison.OrdinalIgnoreCase))
227 {
228 return searchPath;
229 }
230 }
231
232 path1 = Path.GetDirectoryName(path1);
233 }
234
235 return path1;
236 }
237
238 /// <summary>
239 /// Finds the subfolder of a path, excluding a root and filename.
240 /// </summary>
241 /// <param name="path">Path to examine</param>
242 /// <param name="rootPath">Root that must be present </param>
243 /// <param name="fileName"></param>
244 /// <returns></returns>
245 private static string FindSubfolder(string path, string rootPath, string fileName)
246 {
247 if (Path.GetFileName(path).Equals(fileName, StringComparison.OrdinalIgnoreCase))
248 {
249 path = Path.GetDirectoryName(path);
250 }
251
252 if (path.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
253 {
254 // cut out the root and return the subpath
255 return path.Substring(rootPath.Length).Trim(Path.DirectorySeparatorChar);
256 }
257
258 return String.Empty;
259 }
260
261 private static string EnsureEndsWithBackslash(string dir)
262 {
263 if (dir[dir.Length - 1] != Path.DirectorySeparatorChar)
264 {
265 dir += Path.DirectorySeparatorChar;
266 }
267
268 return dir;
269 }
270 }
271}