Fix minizip compile on Haiku (#16301)
[mono-project.git] / msvc / mono.winconfig.targets
blob6eba1cf38420413cc178b543cd23ea91eb66546e
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
4 <UsingTask TaskName="WinConfigSetup" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
5 <ParameterGroup>
6 <ConfigFileRoot ParameterType="System.String" Required="true" />
7 <DisableDefines ParameterType="System.String" Required="false" />
8 <EnableDefines ParameterType="System.String" Required="false" />
9 <HaveDefines ParameterType="System.String" Required="false" />
10 </ParameterGroup>
11 <Task>
12 <Code Type="Class" Language="cs">
13 <![CDATA[
14 using System;
15 using System.IO;
16 using System.Text;
17 using System.Linq;
18 using Microsoft.Build.Framework;
19 using Microsoft.Build.Utilities;
20 using System.Collections.Generic;
21 using System.Text.RegularExpressions;
23 public class _WinConfigSetup : Task
25 bool GetVersionsFromConfigureAC (string configureACFile, out string monoVersion, out string monoCorlibVersion)
27 bool result = true;
28 monoVersion = null;
29 monoCorlibVersion = null;
30 if (File.Exists (configureACFile))
32 // These are both fairly arbitrary strings.
33 var monoVersionRegEx = new Regex (@"^AC_INIT\s*\(\s*mono,\s*\[?\s*([^\],\s]+)");
34 var monoCorlibVersionRegEx = new Regex (@"^MONO_CORLIB_VERSION\s*=\s*(\S+)");
35 using (StreamReader reader = new StreamReader (configureACFile))
37 string line;
38 while ((line = reader.ReadLine ()) != null && (monoVersion == null || monoCorlibVersion == null))
40 var monoVersionMatch = monoVersionRegEx.Match (line);
41 if (monoVersionMatch.Success)
43 if (monoVersion != null)
45 Log.LogError("duplicate MONO_INIT in {0}", configureACFile);
46 result = false;
48 monoVersion = monoVersionMatch.Groups[1].Value;
49 Log.LogMessage ("{0}:AC_INIT:MONO_VERSION=\"{1}\"", configureACFile, monoVersion);
50 continue;
53 var monoCorlibVersionMatch = monoCorlibVersionRegEx.Match (line);
54 if (monoCorlibVersionMatch.Success)
56 if (monoCorlibVersion != null)
58 // This is misleading. The loop stops when both found, so duplicates usually not noticed.
59 Log.LogError("duplicate MONO_CORLIB_VERSION in {0}", configureACFile);
60 result = false;
62 monoCorlibVersion = monoCorlibVersionMatch.Groups[1].Value;
63 Log.LogMessage ("{0}:MONO_CORLIB_VERSION=\"{1}\"", configureACFile, monoCorlibVersion);
64 continue;
69 return result;
72 List<string> GetConfigFeatures (string path, string featuresRegex)
74 var features = new List<string> ();
75 if (File.Exists (path))
77 var regex = new Regex (featuresRegex);
78 using (StreamReader reader = new StreamReader (path))
80 string line;
81 while ((line = reader.ReadLine ()) != null)
83 var match = regex.Match (line);
84 if (match != null && match.Success)
86 if (match.Groups != null && match.Groups.Count == 1)
88 var configLine = match.Groups[0].ToString ();
89 if (!String.IsNullOrEmpty (configLine))
91 var configItems = configLine.Trim ().Split (' ');
92 if (configItems != null && configItems.Length == 3)
94 // Second item should be the define.
95 features.Add (configItems[1]);
103 return features;
106 string [] GetEnabledConfigFeatures (string path, string enableDefines)
108 string [] supportedFeatures = { "ENABLE_ICALL_SYMBOL_MAP",
109 "ENABLE_LLVM",
110 "ENABLE_LLVM_RUNTIME",
111 "ENABLE_HYBRID_SUSPEND",
112 "ENABLE_COOP_SUSPEND",
113 "ENABLE_NETCORE" };
115 var enableFeatures = GetConfigFeatures(path, ".*#define.*ENABLE_.*1");
116 if (enableDefines != null)
117 enableFeatures.AddRange (enableDefines.Split (';'));
119 // Only keep supported features on Windows platforms using MSVC.
120 var features = new List<string> ();
121 foreach (var feature in enableFeatures)
122 if (Array.Exists(supportedFeatures, s => String.CompareOrdinal (s,feature) == 0))
123 features.Add(feature);
124 return features.ToArray ();
127 string [] GetDisabledConfigFeatures (string path)
129 return GetConfigFeatures(path, ".*#define.*DISABLE_.*1").ToArray ();
132 void CreateConfigUsingTemplate (string templatePath, string targetPath, string [] disabledDefines, string [] enabledDefines, string [] haveDefines, string monoVersion, string monoCorlibVersion)
134 string tempFilePath = "";
138 if (File.Exists (templatePath))
140 var disabledDefinesRegex = new Regex (".*@DISABLE_DEFINES@.*");
141 var enabledDefinesRegex = new Regex (".*@ENABLE_DEFINES@.*");
142 var haveDefinesRegex = new Regex (".*@HAVE_DEFINES.*");
144 var definesList = new List<Tuple<Regex, string []>>
146 new Tuple<Regex, string []>(disabledDefinesRegex, disabledDefines),
147 new Tuple<Regex, string []>(enabledDefinesRegex, enabledDefines),
148 new Tuple<Regex, string []>(haveDefinesRegex, haveDefines)
151 var monoCorlibVersions = new string [] {
152 ".*#MONO_CORLIB_VERSION#.*",
153 "#MONO_CORLIB_VERSION#",
154 monoCorlibVersion
156 var monoCorlibVersionRegex = new Regex (monoCorlibVersions[0]);
158 var monoVersions = new string [] {
159 ".*#MONO_VERSION#.*",
160 "#MONO_VERSION#",
161 monoVersion
163 var monoVersionRegex = new Regex (monoVersions[0]);
165 var versionList = new List<Tuple<Regex, string []>>
167 new Tuple<Regex, string []>(monoCorlibVersionRegex, monoCorlibVersions),
168 new Tuple<Regex, string []>(monoVersionRegex, monoVersions)
171 tempFilePath = Path.GetTempFileName ();
173 using (StreamReader reader = new StreamReader (templatePath))
174 using (StreamWriter writer = new StreamWriter (tempFilePath))
176 string line;
177 Match match;
178 while ((line = reader.ReadLine ()) != null)
180 var replaced = false;
181 foreach (var defines in definesList)
183 match = defines.Item1.Match (line);
184 if (match != null && match.Success && defines.Item2 != null)
186 // Replace with disabled defines.
187 foreach (var define in defines.Item2)
189 writer.WriteLine ("#ifndef {0}", define);
190 writer.WriteLine ("#define {0} 1", define);
191 writer.WriteLine ("#endif");
193 replaced = true;
194 break;
198 if (!replaced)
200 foreach (var version in versionList)
202 match = version.Item1.Match (line);
203 if (match != null && match.Success)
205 writer.WriteLine (line.Replace(version.Item2[1], version.Item2[2]));
206 replaced = true;
207 break;
212 if (!replaced)
213 writer.WriteLine (line);
217 bool overwrite = true;
218 if (File.Exists (targetPath))
220 if (File.ReadAllBytes (tempFilePath).SequenceEqual (File.ReadAllBytes (targetPath)))
221 overwrite = false;
224 if (overwrite)
225 File.Copy (tempFilePath, targetPath, true);
228 finally
230 if (!String.IsNullOrEmpty (tempFilePath))
231 File.Delete (tempFilePath);
235 void CreateVersionFile (string targetFile)
237 string tempFile = "";
241 tempFile = Path.GetTempFileName ();
243 using (StreamWriter writer = new StreamWriter (tempFile))
245 writer.WriteLine ("#define FULL_VERSION \"Visual Studio built mono\"");
248 bool overwrite = true;
249 if (File.Exists (targetFile))
251 if (File.ReadAllBytes (tempFile).SequenceEqual (File.ReadAllBytes (targetFile)))
252 overwrite = false;
255 if (overwrite)
256 File.Copy (tempFile, targetFile, true);
258 finally
260 if (!String.IsNullOrEmpty (tempFile))
261 File.Delete (tempFile);
265 bool BackupConfigFile (string sourceConfigFile, string targetConfigFile)
267 bool result = false;
268 if (File.Exists (sourceConfigFile))
270 var includesCygconfig = new Regex (".*#include \"cygconfig.h\".*");
272 var allText = File.ReadAllText (sourceConfigFile);
273 var match = includesCygconfig.Match (allText);
274 if (match == null || !match.Success)
276 File.Copy (sourceConfigFile, targetConfigFile, true);
277 result = true;
281 return result;
284 public string ConfigFileRoot { get; set; }
285 public string DisableDefines { get; set; }
286 public string EnableDefines { get; set; }
287 public string HaveDefines { get; set; }
289 public override bool Execute ()
291 string configureACFile = Path.Combine (ConfigFileRoot, @"configure.ac");
292 string configFile = Path.Combine (ConfigFileRoot, @"config.h");
293 string cygConfigFile = Path.Combine (ConfigFileRoot, @"cygconfig.h");
294 string winConfigFile = Path.Combine (ConfigFileRoot, @"winconfig.h");
295 string versionFile = Path.Combine (ConfigFileRoot, @"mono\mini\version.h");
297 Log.LogMessage (MessageImportance.High, "Setting up Mono configuration headers...");
299 BackupConfigFile (configFile, cygConfigFile);
301 string monoVersion = null;
302 string monoCorlibVersion = null;
303 if (!GetVersionsFromConfigureAC (configureACFile, out monoVersion, out monoCorlibVersion))
304 return false;
306 if (monoVersion == null)
308 Log.LogError("failed to parse version from AC_INIT in {0}", configureACFile);
309 return false;
312 if (monoCorlibVersion == null)
314 Log.LogError("failed to parse MONO_CORLIB_VERSION from {0}", configureACFile);
315 return false;
318 var disableDefines = GetDisabledConfigFeatures (cygConfigFile);
319 var enableDefines = GetEnabledConfigFeatures (cygConfigFile, EnableDefines);
320 var haveDefines = (HaveDefines != null) ? HaveDefines.Split (';') : null;
321 CreateConfigUsingTemplate (winConfigFile, configFile, disableDefines, enableDefines, haveDefines, monoVersion, monoCorlibVersion);
323 CreateVersionFile (versionFile);
325 Log.LogMessage (MessageImportance.High, "Successfully setup Mono configuration headers {0} and {1} from {2}.", configFile, versionFile, winConfigFile);
327 return true;
331 </Code>
332 </Task>
333 </UsingTask>
335 <Target Name="RunWinConfigSetup">
336 <WinConfigSetup ConfigFileRoot="$(MSBuildThisFileDirectory)..\"
337 DisableDefines=""
338 EnableDefines=""
339 HaveDefines=""/>
340 </Target>
342 </Project>