Anope IRC Services  Version 2.0
Config.cs
Go to the documentation of this file.
1 /*
2  * Config.cs - Windows Configuration
3  *
4  * (C) 2003-2014 Anope Team
5  * Contact us at team@anope.org
6  *
7  * This program is free but copyrighted software; see the file COPYING for
8  * details.
9  *
10  * Based on the original code of Epona by Lara.
11  * Based on the original code of Services by Andy Church.
12  *
13  * Written by Scott <stealtharcher.scott@gmail.com>
14  * Written by Adam <Adam@anope.org>
15  * Cleaned up by Naram Qashat <cyberbotx@anope.org>
16  *
17  * Compile with: csc /out:../../Config.exe /win32icon:anope-icon.ico Config.cs
18  */
19 
20 using System;
21 using System.Collections.Generic;
22 using System.Diagnostics;
23 using System.IO;
24 using System.Reflection;
25 
26 namespace Config
27 {
28  class Config
29  {
30  static string ExecutablePath, InstallDirectory, VSVersion, VSShortVer, ExtraIncludeDirs, ExtraLibDirs, ExtraArguments;
31  static bool UseNMake = true, BuildDebug = false;
32 
33  static bool CheckResponse(string InstallerResponse)
34  {
35  if (string.Compare(InstallerResponse, "yes", true) == 0 || string.Compare(InstallerResponse, "y", true) == 0)
36  return true;
37  return false;
38  }
39 
40  static bool LoadCache()
41  {
42  try
43  {
44  string[] cache = File.ReadAllLines(string.Format(@"{0}\config.cache", ExecutablePath));
45  if (cache.Length > 0)
46  Console.WriteLine("Using defaults from config.cache");
47  foreach (string line in cache)
48  {
49  int e = line.IndexOf('=');
50  string name = line.Substring(0, e);
51  string value = line.Substring(e + 1);
52 
53  if (name == "INSTDIR")
54  InstallDirectory = value;
55  else if (name == "DEBUG")
56  BuildDebug = CheckResponse(value);
57  else if (name == "USENMAKE")
58  UseNMake = CheckResponse(value);
59  else if (name == "EXTRAINCLUDE")
60  ExtraIncludeDirs = value;
61  else if (name == "EXTRALIBS")
62  ExtraLibDirs = value;
63  else if (name == "EXTRAARGS")
64  ExtraArguments = value;
65  else if (name == "VSVERSION")
66  VSVersion = value;
67  else if (name == "VSSHORTVER")
68  VSShortVer = value;
69  }
70 
71  return true;
72  }
73  catch (Exception)
74  {
75  }
76 
77  return false;
78  }
79 
80  static void SaveCache()
81  {
82  using (TextWriter tw = new StreamWriter(string.Format(@"{0}\config.cache", ExecutablePath)))
83  {
84  tw.WriteLine("INSTDIR={0}", InstallDirectory);
85  tw.WriteLine("DEBUG={0}", BuildDebug ? "yes" : "no");
86  tw.WriteLine("USENMAKE={0}", UseNMake ? "yes" : "no");
87  tw.WriteLine("EXTRAINCLUDE={0}", ExtraIncludeDirs);
88  tw.WriteLine("EXTRALIBS={0}", ExtraLibDirs);
89  tw.WriteLine("EXTRAARGS={0}", ExtraArguments);
90  tw.WriteLine("VSVERSION={0}", VSVersion);
91  tw.WriteLine("VSSHORTVER={0}", VSShortVer);
92  }
93  }
94 
95  static string HandleCache(int i)
96  {
97  switch (i)
98  {
99  case 0:
100  Console.Write("[{0}] ", InstallDirectory);
101  return InstallDirectory;
102  case 1:
103  Console.Write("[{0}] ", UseNMake ? "yes" : "no");
104  return UseNMake ? "yes" : "no";
105  case 2:
106  Console.Write("[{0}] ", VSShortVer);
107  return VSShortVer;
108  case 3:
109  Console.Write("[{0}] ", BuildDebug ? "yes" : "no");
110  return BuildDebug ? "yes" : "no";
111  case 4:
112  Console.Write("[{0}] ", ExtraIncludeDirs);
113  return ExtraIncludeDirs;
114  case 5:
115  Console.Write("[{0}] ", ExtraLibDirs);
116  return ExtraLibDirs;
117  case 6:
118  Console.Write("[{0}] ", ExtraArguments);
119  return ExtraArguments;
120  default:
121  break;
122  }
123 
124  return null;
125  }
126 
127  static string FindAnopeVersion()
128  {
129  if (!File.Exists(string.Format(@"{0}\src\version.sh", ExecutablePath)))
130  return "Unknown";
131 
132  Dictionary<string, string> versions = new Dictionary<string, string>();
133  string[] versionfile = File.ReadAllLines(string.Format(@"{0}\src\version.sh", ExecutablePath));
134  foreach (string line in versionfile)
135  if (line.StartsWith("VERSION_"))
136  {
137  string key = line.Split('_')[1].Split('=')[0];
138  if (!versions.ContainsKey(key))
139  versions.Add(key, line.Split('=')[1].Replace("\"", "").Replace("\'", ""));
140  }
141 
142  try
143  {
144  if (versions.ContainsKey("BUILD"))
145  return string.Format("{0}.{1}.{2}.{3}{4}", versions["MAJOR"], versions["MINOR"], versions["PATCH"], versions["BUILD"], versions["EXTRA"]);
146  else
147  return string.Format("{0}.{1}.{2}{3}", versions["MAJOR"], versions["MINOR"], versions["PATCH"], versions["EXTRA"]);
148  }
149  catch (Exception e)
150  {
151  Console.WriteLine(e.Message);
152  return "Unknown";
153  }
154  }
155 
156  static void RunCMake(string cMake)
157  {
158  Console.WriteLine("cmake {0}", cMake);
159  try
160  {
161  ProcessStartInfo processStartInfo = new ProcessStartInfo("cmake")
162  {
163  RedirectStandardError = true,
164  RedirectStandardOutput = true,
165  UseShellExecute = false,
166  Arguments = cMake
167  };
168  Process pCMake = Process.Start(processStartInfo);
169  StreamReader stdout = pCMake.StandardOutput, stderr = pCMake.StandardError;
170  string stdoutr, stderrr;
171  List<string> errors = new List<string>();
172  while (!pCMake.HasExited)
173  {
174  if ((stdoutr = stdout.ReadLine()) != null)
175  Console.WriteLine(stdoutr);
176  if ((stderrr = stderr.ReadLine()) != null)
177  errors.Add(stderrr);
178  }
179  foreach (string error in errors)
180  Console.WriteLine(error);
181  Console.WriteLine();
182  if (pCMake.ExitCode == 0)
183  {
184  if (UseNMake)
185  Console.WriteLine("To compile Anope, run 'nmake'. To install, run 'nmake install'");
186  else
187  Console.WriteLine("To compile Anope, open Anope.sln and build the solution. To install, do a build on the INSTALL project");
188  }
189  else
190  Console.WriteLine("There was an error attempting to run CMake! Check the above error message, and contact the Anope team if you are unsure how to proceed.");
191  }
192  catch (Exception e)
193  {
194  Console.WriteLine();
195  Console.WriteLine(DateTime.UtcNow + " UTC: " + e.Message);
196  Console.WriteLine("There was an error attempting to run CMake! Check the above error message, and contact the Anope team if you are unsure how to proceed.");
197  }
198  }
199 
200  static int Main(string[] args)
201  {
202  bool IgnoreCache = false, NoIntro = false, DoQuick = false;
203 
204  if (args.Length > 0)
205  {
206  if (args[0] == "--help")
207  {
208  Console.WriteLine("Config utility for Anope");
209  Console.WriteLine("------------------------");
210  Console.WriteLine("Syntax: .\\Config.exe [options]");
211  Console.WriteLine("-nocache Ignore settings saved in config.cache");
212  Console.WriteLine("-nointro Skip intro (disclaimer, etc)");
213  Console.WriteLine("-quick or -q Skip questions, go straight to cmake");
214  return 0;
215  }
216  else if (args[0] == "-nocache")
217  IgnoreCache = true;
218  else if (args[0] == "-nointro")
219  NoIntro = true;
220  else if (args[0] == "-quick" || args[0] == "-q")
221  DoQuick = true;
222  }
223 
224  ExecutablePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
225 
226  string AnopeVersion = FindAnopeVersion();
227 
228  if (!NoIntro && File.Exists(string.Format(@"{0}\.BANNER", ExecutablePath)))
229  Console.WriteLine(File.ReadAllText(string.Format(@"{0}\.BANNER", ExecutablePath)).Replace("CURVER", AnopeVersion).Replace("For more options type SOURCE_DIR/Config --help", ""));
230 
231  Console.WriteLine("Press Enter to begin");
232  Console.WriteLine();
233  Console.ReadKey();
234 
235  bool UseCache = false;
236 
237  if (DoQuick || !IgnoreCache)
238  {
239  UseCache = LoadCache();
240  if (DoQuick && !UseCache)
241  {
242  Console.WriteLine("Can't find cache file (config.cache), aborting...");
243  return 1;
244  }
245  }
246 
247  if (!DoQuick)
248  {
249  List<string> InstallerQuestions = new List<string>()
250  {
251  "Where do you want Anope to be installed?",
252  "Would you like to build using NMake instead of using Visual Studio?\r\nNOTE: If you decide to use NMake, you must be in an environment where\r\nNMake can function, such as the Visual Studio command line. If you say\r\nyes to this while not in an environment that can run NMake, it can\r\ncause the CMake configuration to enter an endless loop. [y/n]",
253  "Are you using Visual Studio 2008, 2010, or 2012? You can leave this blank\nand have CMake try and auto detect it, but this usually doesn't\nwork correctly. [2008/2010/2012]",
254  "Would you like to build a debug version of Anope? [y/n]",
255  "Are there any extra include directories you wish to use?\nYou may only need to do this if CMake is unable to locate missing dependencies without hints.\nSeparate directories with semicolons and use slashes (aka /) instead of backslashes (aka \\).\nIf you need no extra include directories, enter NONE in all caps.",
256  "Are there any extra library directories you wish to use?\nYou may only need to do this if CMake is unable to locate missing dependencies without hints.\nSeparate directories with semicolons and use slashes (aka /) instead of backslashes (aka \\).\nIf you need no extra library directories, enter NONE in all caps.",
257  "Are there any extra arguments you wish to pass to CMake?\nIf you need no extra arguments to CMake, enter NONE in all caps."
258  };
259 
260  for (int i = 0; i < InstallerQuestions.Count; ++i)
261  {
262  Console.WriteLine(InstallerQuestions[i]);
263  string CacheResponse = null;
264  if (UseCache)
265  CacheResponse = HandleCache(i);
266  string InstallerResponse = Console.ReadLine();
267  Console.WriteLine();
268 
269  if (!string.IsNullOrWhiteSpace(CacheResponse) && string.IsNullOrWhiteSpace(InstallerResponse))
270  InstallerResponse = CacheResponse;
271 
272  // Question 5-7 are optional
273  if (i < 4 && string.IsNullOrWhiteSpace(InstallerResponse))
274  {
275  Console.WriteLine("Invalid option");
276  --i;
277  continue;
278  }
279 
280  switch (i)
281  {
282  case 0:
283  if (!Directory.Exists(InstallerResponse))
284  {
285  Console.WriteLine("Directory does not exist! Creating directory.");
286  Console.WriteLine();
287  try
288  {
289  Directory.CreateDirectory(InstallerResponse);
290  InstallDirectory = InstallerResponse;
291  }
292  catch (Exception e)
293  {
294  Console.WriteLine("Unable to create directory: " + e.Message);
295  --i;
296  }
297  }
298  else if (File.Exists(InstallerResponse + @"\include\services.h"))
299  {
300  Console.WriteLine("You cannot use the Anope source directory as the target directory!");
301  --i;
302  }
303  else
304  InstallDirectory = InstallerResponse;
305  break;
306  case 1:
307  UseNMake = CheckResponse(InstallerResponse);
308  if (UseNMake)
309  ++i;
310  break;
311  case 2:
312  if (InstallerResponse == "2012")
313  {
314  VSVersion = "-G\"Visual Studio 11\" ";
315  VSShortVer = "2012";
316  }
317  else if (InstallerResponse == "2010")
318  {
319  VSVersion = "-G\"Visual Studio 10\" ";
320  VSShortVer = "2010";
321  }
322  else if (InstallerResponse == "2008")
323  {
324  VSVersion = "-G\"Visual Studio 9 2008\" ";
325  VSShortVer = "2008";
326  }
327  break;
328  case 3:
329  BuildDebug = CheckResponse(InstallerResponse);
330  break;
331  case 4:
332  if (InstallerResponse == "NONE")
333  ExtraIncludeDirs = null;
334  else
335  ExtraIncludeDirs = InstallerResponse;
336  break;
337  case 5:
338  if (InstallerResponse == "NONE")
339  ExtraLibDirs = null;
340  else
341  ExtraLibDirs = InstallerResponse;
342  break;
343  case 6:
344  if (InstallerResponse == "NONE")
345  ExtraArguments = null;
346  else
347  ExtraArguments = InstallerResponse;
348  break;
349  default:
350  break;
351  }
352  }
353  }
354 
355  Console.WriteLine("Anope will be compiled with the following options:");
356  Console.WriteLine("Install directory: {0}", InstallDirectory);
357  Console.WriteLine("Use NMake: {0}", UseNMake ? "Yes" : "No");
358  if (!string.IsNullOrWhiteSpace(VSShortVer))
359  Console.WriteLine("Using Visual Studio: {0}", VSShortVer);
360  else
361  Console.WriteLine("Using Visual Studio: No");
362  Console.WriteLine("Build debug: {0}", BuildDebug ? "Yes" : "No");
363  Console.WriteLine("Anope Version: {0}", AnopeVersion);
364  Console.WriteLine("Extra Include Directories: {0}", ExtraIncludeDirs);
365  Console.WriteLine("Extra Library Directories: {0}", ExtraLibDirs);
366  Console.WriteLine("Extra Arguments: {0}", ExtraArguments);
367  Console.WriteLine("Press Enter to continue...");
368  Console.ReadKey();
369 
370  SaveCache();
371 
372  if (!string.IsNullOrWhiteSpace(ExtraIncludeDirs))
373  ExtraIncludeDirs = string.Format("-DEXTRA_INCLUDE:STRING={0} ", ExtraIncludeDirs);
374  else
375  ExtraIncludeDirs = "";
376  if (!string.IsNullOrWhiteSpace(ExtraLibDirs))
377  ExtraLibDirs = string.Format("-DEXTRA_LIBS:STRING={0} ", ExtraLibDirs);
378  else
379  ExtraLibDirs = "";
380  if (!string.IsNullOrWhiteSpace(ExtraArguments))
381  ExtraArguments += " ";
382  else
383  ExtraArguments = "";
384 
385  InstallDirectory = "-DINSTDIR:STRING=\"" + InstallDirectory.Replace('\\', '/') + "\" ";
386  string NMake = UseNMake ? "-G\"NMake Makefiles\" " : "";
387  string Debug = BuildDebug ? "-DCMAKE_BUILD_TYPE:STRING=DEBUG " : "-DCMAKE_BUILD_TYPE:STRING=RELEASE ";
388  string cMake = InstallDirectory + NMake + Debug + VSVersion + ExtraIncludeDirs + ExtraLibDirs + ExtraArguments + "\"" + ExecutablePath.Replace('\\', '/') + "\"";
389  RunCMake(cMake);
390 
391  return 0;
392  }
393  }
394 }
static string FindAnopeVersion()
Definition: Config.cs:127
static string HandleCache(int i)
Definition: Config.cs:95
static int Main(string[] args)
Definition: Config.cs:200
static void SaveCache()
Definition: Config.cs:80
static void RunCMake(string cMake)
Definition: Config.cs:156
static bool CheckResponse(string InstallerResponse)
Definition: Config.cs:33
Definition: Config.cs:26
static bool LoadCache()
Definition: Config.cs:40
static string VSVersion
Definition: Config.cs:30
CoreExport int Debug
Definition: main.cpp:27
Anope::string name
Definition: access.cpp:22
void Process(const Anope::string &)
Definition: process.cpp:19