Merge pull request #2947 from mfilippov/master
[mono.git] / mcs / class / Microsoft.Build.Utilities / Microsoft.Build.Utilities / ToolLocationHelper.cs
1 // 
2 // ToolLocationHelper.cs:
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //
7 // (C) 2005 Marek Sieradzki
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 using System;
29 using System.IO;
30 using System.Xml;
31 using System.Linq;
32
33 namespace Microsoft.Build.Utilities
34 {
35         #if MICROSOFT_BUILD_DLL
36         internal
37         #else
38         public
39         #endif
40         static class ToolLocationHelper
41         {
42                 static string lib_mono_dir;
43                 static string [] mono_dir;
44                 static bool runningOnDotNet;
45
46                 static ToolLocationHelper ()
47                 {
48                         string assemblyLocation;
49                         DirectoryInfo t1, t2;
50
51                         // /usr/local/lib/mono/1.0
52                         assemblyLocation = Path.GetDirectoryName (typeof (object).Assembly.Location);
53                         t1 = new DirectoryInfo (assemblyLocation);
54
55                         // usr/local/lib/mono
56                         t2 = t1.Parent;
57
58                         lib_mono_dir = t2.FullName;
59
60                         var windowsPath = Environment.GetFolderPath (Environment.SpecialFolder.Windows);
61                         runningOnDotNet = !string.IsNullOrEmpty (windowsPath) && lib_mono_dir.StartsWith (windowsPath);
62
63                         if (Environment.GetEnvironmentVariable ("TESTING_MONO") != null) {
64                                 mono_dir = new string [] {                   // TargetDotNetFrameworkVersion:
65                                         Path.Combine (lib_mono_dir, "net_1_0"),  // Version11
66                                         Path.Combine (lib_mono_dir, "net_2_0"),  // Version20
67                                         Path.Combine (lib_mono_dir, "net_2_0"),  // Version30
68                                         Path.Combine (lib_mono_dir, "net_3_5"),  // Version35
69                                         // mono's 4.0 is not an actual framework directory with all tools etc
70                                         // it's simply reference assemblies. So like .NET we consider 4.5 to
71                                         // be a complete replacement for 4.0.
72                                         Path.Combine (lib_mono_dir, "net_4_x"),  // Version40
73                                         Path.Combine (lib_mono_dir, "net_4_x"),  // Version45
74                                         Path.Combine (lib_mono_dir, "net_4_x"),  // Version451
75                                         Path.Combine (lib_mono_dir, "net_4_x"),  // Version46
76                                         Path.Combine (lib_mono_dir, "net_4_x"),  // Version461
77                                 };      
78                         } else if (runningOnDotNet) {
79                                 mono_dir = new string [] {
80                                         Path.Combine (lib_mono_dir, "v1.0.3705"),   // Version11
81                                         Path.Combine (lib_mono_dir, "v2.0.50727"),  // Version20
82                                         Path.Combine (lib_mono_dir, "v2.0.50727"),  // Version30
83                                         Path.Combine (lib_mono_dir, "v3.5"),        // Version35
84                                         Path.Combine (lib_mono_dir, "v4.0.30319"),  // Version40
85                                         Path.Combine (lib_mono_dir, "v4.0.30319"),  // Version45
86                                         Path.Combine (lib_mono_dir, "v4.0.30319"),  // Version451
87                                         Path.Combine (lib_mono_dir, "v4.0.30319"),  // Version46
88                                         Path.Combine (lib_mono_dir, "v4.0.30319"),  // Version461
89                                 };
90                         } else {
91                                 mono_dir = new string [] {
92                                         Path.Combine (lib_mono_dir, "1.0"),  // Version11
93                                         Path.Combine (lib_mono_dir, "2.0"),  // Version20
94                                         Path.Combine (lib_mono_dir, "2.0"),  // Version30
95                                         Path.Combine (lib_mono_dir, "3.5"),  // Version35
96                                         // see comment above regarding 4.0/4.5
97                                         Path.Combine (lib_mono_dir, "4.5"),  // Version40
98                                         Path.Combine (lib_mono_dir, "4.5"),  // Version45
99                                         Path.Combine (lib_mono_dir, "4.5"),  // Version451
100                                         Path.Combine (lib_mono_dir, "4.5"),  // Version46
101                                         Path.Combine (lib_mono_dir, "4.5"),  // Version461
102                                 };
103                         }
104
105                 }
106
107                 [MonoTODO]
108                 public static string GetDotNetFrameworkRootRegistryKey (TargetDotNetFrameworkVersion version)
109                 {
110                         throw new NotImplementedException ();
111                 }
112
113                 [MonoTODO]
114                 public static string GetDotNetFrameworkSdkInstallKeyValue (TargetDotNetFrameworkVersion version)
115                 {
116                         throw new NotImplementedException ();
117                 }
118
119                 [MonoTODO]
120                 public static string GetDotNetFrameworkVersionFolderPrefix (TargetDotNetFrameworkVersion version)
121                 {
122                         throw new NotImplementedException ();
123                 }
124
125                 public static string GetPathToDotNetFramework (TargetDotNetFrameworkVersion version)
126                 {
127                         return mono_dir [(int)version];
128                 }
129
130                 public static string GetPathToDotNetFrameworkFile (string fileName,
131                                                                   TargetDotNetFrameworkVersion version)
132                 {
133                         string dir = GetPathToDotNetFramework (version);
134                         string file = Path.Combine (dir, fileName);
135                         if (File.Exists (file))
136                                 return file;
137
138                         //Mono doesn't ship multiple versions of tools that are backwards/forwards compatible
139                         if (!runningOnDotNet) {
140                                 //most of the 3.5 tools are in the 2.0 directory
141                                 if (version == TargetDotNetFrameworkVersion.Version35)
142                                         return GetPathToDotNetFrameworkFile (fileName, TargetDotNetFrameworkVersion.Version20);
143                                 //unversioned tools are in the 4.5 directory
144                                 if (version == TargetDotNetFrameworkVersion.Version20)
145                                         return GetPathToDotNetFrameworkFile (fileName, (TargetDotNetFrameworkVersion)5);
146                         }
147
148                         return null;
149                 }
150
151                 public static string GetPathToDotNetFrameworkBinFile (string fileName)
152                 {
153                         string dir = Path.Combine(Directory.GetParent(Directory.GetParent(lib_mono_dir).FullName).FullName, "bin");
154                         string file = Path.Combine (dir, fileName);
155                         if (File.Exists (file))
156                                 return file;
157
158                         return null;
159                 }
160
161                 public static string GetPathToDotNetFrameworkSdk (TargetDotNetFrameworkVersion version)
162                 {
163                         return GetPathToDotNetFramework (version);
164                 }
165
166                 [MonoTODO]
167                 public static string GetPathToDotNetFrameworkSdkFile (string fileName,
168                                                                       TargetDotNetFrameworkVersion version)
169                 {
170                         throw new NotImplementedException ();
171                 }
172
173                 public static string GetPathToStandardLibraries (string targetFrameworkIdentifier,
174                                                                  string targetFrameworkVersion,
175                                                                  string targetFrameworkProfile)
176                 {
177                         return GetPathToStandardLibraries (targetFrameworkIdentifier, targetFrameworkVersion, targetFrameworkProfile, null);
178                 }
179
180                 [MonoTODO]
181                 #if XBUILD_12
182                 public
183                 #endif
184                 static string GetPathToStandardLibraries (string targetFrameworkIdentifier,
185                                                           string targetFrameworkVersion,
186                                                           string targetFrameworkProfile,
187                                                           string platformTarget)
188                 {
189                         // FIXME: support platformTarget
190                         if (platformTarget != null)
191                                 throw new NotImplementedException ("platformTarget support is not implemented");
192                         
193                         var ext = Environment.GetEnvironmentVariable ("XBUILD_FRAMEWORK_FOLDERS_PATH");
194                         var ret = ext != null ? GetPathToStandardLibrariesWith (ext, targetFrameworkIdentifier, targetFrameworkVersion, targetFrameworkProfile) : null;
195                         return ret ?? GetPathToStandardLibrariesWith (Path.GetFullPath (Path.Combine (lib_mono_dir, "xbuild-frameworks")), targetFrameworkIdentifier, targetFrameworkVersion, targetFrameworkProfile);
196                 }
197                         
198                 static string GetPathToStandardLibrariesWith (string xbuildFxDir,
199                                                               string targetFrameworkIdentifier,
200                                                               string targetFrameworkVersion,
201                                                               string targetFrameworkProfile)
202                 {
203                         var path = Path.Combine (xbuildFxDir, targetFrameworkIdentifier);
204                         if (!string.IsNullOrEmpty (targetFrameworkVersion)) {
205                                 path = Path.Combine (path, targetFrameworkVersion);
206                                 if (!string.IsNullOrEmpty (targetFrameworkProfile))
207                                         path = Path.Combine (path, "Profile", targetFrameworkProfile);
208                         }
209                         if (!Directory.Exists (path))
210                                 return null;
211                         var flist = Path.Combine (path, "RedistList", "FrameworkList.xml");
212                         if (!File.Exists (flist))
213                                 return null;
214                         var xml = XmlReader.Create (flist);
215                         xml.MoveToContent ();
216                         var targetFxDir = xml.GetAttribute ("TargetFrameworkDirectory");
217                         targetFxDir = targetFxDir != null ? Path.GetFullPath (Path.Combine (path, "dummy", targetFxDir.Replace ('\\', Path.DirectorySeparatorChar))) : null;
218                         if (Directory.Exists (targetFxDir))
219                                 return targetFxDir;
220                         // I'm not sure if this is completely valid assumption...
221                         return path;
222                 }
223
224                 [MonoTODO]
225                 public static string GetPathToSystemFile (string fileName)
226                 {
227                         throw new NotImplementedException ();
228                 }
229
230                 [MonoTODO]
231                 public static string PathToSystem {
232                         get {
233                                 throw new NotImplementedException ();
234                         }
235                 }
236
237 #if XBUILD_12
238                 public static string CurrentToolsVersion {
239                         get {
240                                 return XBuildConsts.Version;
241                         }
242                 }
243
244                 public static string GetPathToBuildTools (string toolsVersion)
245                 {
246                         string path;
247                         switch (toolsVersion) {
248                         case "12.0":
249                                 path = "xbuild_12";
250                                 break;
251                         case "14.0":
252                                 path = "xbuild_14";
253                                 break;
254                         default:
255                                 return null;
256                         }
257
258                         if (Environment.GetEnvironmentVariable ("TESTING_MONO") != null)
259                                 return Path.Combine (lib_mono_dir, path);
260
261                         if (runningOnDotNet) {
262                                 //see http://msdn.microsoft.com/en-us/library/vstudio/bb397428(v=vs.120).aspx
263                                 var programFiles = Environment.GetFolderPath (Environment.SpecialFolder.ProgramFilesX86);
264                                 return Path.Combine (programFiles, "MSBuild", toolsVersion, "bin");
265                         }
266
267                         return Path.Combine (lib_mono_dir, "xbuild", toolsVersion, "bin");
268                 }
269 #endif
270         }
271 }