anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

Config.cs (12380B)

      1 /*
      2  * Config.cs - Windows Configuration
      3  *
      4  * (C) 2003-2022 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, 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 				}
     66 
     67 				return true;
     68 			}
     69 			catch (Exception)
     70 			{
     71 			}
     72 
     73 			return false;
     74 		}
     75 
     76 		static void SaveCache()
     77 		{
     78 			using (TextWriter tw = new StreamWriter(string.Format(@"{0}\config.cache", ExecutablePath)))
     79 			{
     80 				tw.WriteLine("INSTDIR={0}", InstallDirectory);
     81 				tw.WriteLine("DEBUG={0}", BuildDebug ? "yes" : "no");
     82 				tw.WriteLine("USENMAKE={0}", UseNMake ? "yes" : "no");
     83 				tw.WriteLine("EXTRAINCLUDE={0}", ExtraIncludeDirs);
     84 				tw.WriteLine("EXTRALIBS={0}", ExtraLibDirs);
     85 				tw.WriteLine("EXTRAARGS={0}", ExtraArguments);
     86 			}
     87 		}
     88 
     89 		static string HandleCache(int i)
     90 		{
     91 			switch (i)
     92 			{
     93 				case 0:
     94 					Console.Write("[{0}] ", InstallDirectory);
     95 					return InstallDirectory;
     96 				case 1:
     97 					Console.Write("[{0}] ", UseNMake ? "yes" : "no");
     98 					return UseNMake ? "yes" : "no";
     99 				case 2:
    100 					Console.Write("[{0}] ", BuildDebug ? "yes" : "no");
    101 					return BuildDebug ? "yes" : "no";
    102 				case 3:
    103 					Console.Write("[{0}] ", ExtraIncludeDirs);
    104 					return ExtraIncludeDirs;
    105 				case 4:
    106 					Console.Write("[{0}] ", ExtraLibDirs);
    107 					return ExtraLibDirs;
    108 				case 5:
    109 					Console.Write("[{0}] ", ExtraArguments);
    110 					return ExtraArguments;
    111 				default:
    112 					break;
    113 			}
    114 
    115 			return null;
    116 		}
    117 
    118 		static string FindAnopeVersion()
    119 		{
    120 			if (!File.Exists(string.Format(@"{0}\src\version.sh", ExecutablePath)))
    121 				return "Unknown";
    122 
    123 			Dictionary<string, string> versions = new Dictionary<string, string>();
    124 			string[] versionfile = File.ReadAllLines(string.Format(@"{0}\src\version.sh", ExecutablePath));
    125 			foreach (string line in versionfile)
    126 				if (line.StartsWith("VERSION_"))
    127 				{
    128 					string key = line.Split('_')[1].Split('=')[0];
    129 					if (!versions.ContainsKey(key))
    130 						versions.Add(key, line.Split('=')[1].Replace("\"", "").Replace("\'", ""));
    131 				}
    132 
    133 			try
    134 			{
    135 				if (versions.ContainsKey("BUILD"))
    136 					return string.Format("{0}.{1}.{2}.{3}{4}", versions["MAJOR"], versions["MINOR"], versions["PATCH"], versions["BUILD"], versions["EXTRA"]);
    137 				else
    138 					return string.Format("{0}.{1}.{2}{3}", versions["MAJOR"], versions["MINOR"], versions["PATCH"], versions["EXTRA"]);
    139 			}
    140 			catch (Exception e)
    141 			{
    142 				Console.WriteLine(e.Message);
    143 				return "Unknown";
    144 			}
    145 		}
    146 
    147 		static void RunCMake(string cMake)
    148 		{
    149 			Console.WriteLine("cmake {0}", cMake);
    150 			try
    151 			{
    152 				ProcessStartInfo processStartInfo = new ProcessStartInfo("cmake")
    153 				{
    154 					RedirectStandardError = true,
    155 					RedirectStandardOutput = true,
    156 					UseShellExecute = false,
    157 					Arguments = cMake
    158 				};
    159 				Process pCMake = Process.Start(processStartInfo);
    160 				StreamReader stdout = pCMake.StandardOutput, stderr = pCMake.StandardError;
    161 				string stdoutr, stderrr;
    162 				List<string> errors = new List<string>();
    163 				while (!pCMake.HasExited)
    164 				{
    165 					if ((stdoutr = stdout.ReadLine()) != null)
    166 						Console.WriteLine(stdoutr);
    167 					if ((stderrr = stderr.ReadLine()) != null)
    168 						errors.Add(stderrr);
    169 				}
    170 				foreach (string error in errors)
    171 					Console.WriteLine(error);
    172 				Console.WriteLine();
    173 				if (pCMake.ExitCode == 0)
    174 				{
    175 					if (UseNMake)
    176 						Console.WriteLine("To compile Anope, run 'nmake'. To install, run 'nmake install'");
    177 					else
    178 						Console.WriteLine("To compile Anope, open Anope.sln and build the solution. To install, do a build on the INSTALL project");
    179 				}
    180 				else
    181 					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.");
    182 			}
    183 			catch (Exception e)
    184 			{
    185 				Console.WriteLine();
    186 				Console.WriteLine(DateTime.UtcNow + " UTC: " + e.Message);
    187 				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.");
    188 			}
    189 		}
    190 
    191 		static int Main(string[] args)
    192 		{
    193 			bool IgnoreCache = false, NoIntro = false, DoQuick = false;
    194 
    195 			if (args.Length > 0)
    196 			{
    197 				if (args[0] == "--help")
    198 				{
    199 					Console.WriteLine("Config utility for Anope");
    200 					Console.WriteLine("------------------------");
    201 					Console.WriteLine("Syntax: .\\Config.exe [options]");
    202 					Console.WriteLine("-nocache     Ignore settings saved in config.cache");
    203 					Console.WriteLine("-nointro     Skip intro (disclaimer, etc)");
    204 					Console.WriteLine("-quick or -q Skip questions, go straight to cmake");
    205 					return 0;
    206 				}
    207 				else if (args[0] == "-nocache")
    208 					IgnoreCache = true;
    209 				else if (args[0] == "-nointro")
    210 					NoIntro = true;
    211 				else if (args[0] == "-quick" || args[0] == "-q")
    212 					DoQuick = true;
    213 			}
    214 
    215 			ExecutablePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    216 
    217 			string AnopeVersion = FindAnopeVersion();
    218 
    219 			if (!NoIntro && File.Exists(string.Format(@"{0}\.BANNER", ExecutablePath)))
    220 				Console.WriteLine(File.ReadAllText(string.Format(@"{0}\.BANNER", ExecutablePath)).Replace("CURVER", AnopeVersion).Replace("For more options type SOURCE_DIR/Config --help", ""));
    221 
    222 			Console.WriteLine("Press Enter to begin");
    223 			Console.WriteLine();
    224 			Console.ReadKey();
    225 
    226 			bool UseCache = false;
    227 
    228 			if (DoQuick || !IgnoreCache)
    229 			{
    230 				UseCache = LoadCache();
    231 				if (DoQuick && !UseCache)
    232 				{
    233 					Console.WriteLine("Can't find cache file (config.cache), aborting...");
    234 					return 1;
    235 				}
    236 			}
    237 
    238 			if (!DoQuick)
    239 			{
    240 				List<string> InstallerQuestions = new List<string>()
    241 				{
    242 					"Where do you want Anope to be installed?",
    243 					"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]",
    244 					"Would you like to build a debug version of Anope? [y/n]",
    245 					"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.",
    246 					"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.",
    247 					"Are there any extra arguments you wish to pass to CMake?\nIf you need no extra arguments to CMake, enter NONE in all caps."
    248 				};
    249 
    250 				for (int i = 0; i < InstallerQuestions.Count; ++i)
    251 				{
    252 					Console.WriteLine(InstallerQuestions[i]);
    253 					string CacheResponse = null;
    254 					if (UseCache)
    255 						CacheResponse = HandleCache(i);
    256 					string InstallerResponse = Console.ReadLine();
    257 					Console.WriteLine();
    258 
    259 					if (!string.IsNullOrWhiteSpace(CacheResponse) && string.IsNullOrWhiteSpace(InstallerResponse))
    260 						InstallerResponse = CacheResponse;
    261 
    262 					// Question 4+ are optional
    263 					if (i < 3 && string.IsNullOrWhiteSpace(InstallerResponse))
    264 					{
    265 						Console.WriteLine("Invalid option");
    266 						--i;
    267 						continue;
    268 					}
    269 
    270 					switch (i)
    271 					{
    272 						case 0:
    273 							if (!Directory.Exists(InstallerResponse))
    274 							{
    275 								Console.WriteLine("Directory does not exist! Creating directory.");
    276 								Console.WriteLine();
    277 								try
    278 								{
    279 									Directory.CreateDirectory(InstallerResponse);
    280 									InstallDirectory = InstallerResponse;
    281 								}
    282 								catch (Exception e)
    283 								{
    284 									Console.WriteLine("Unable to create directory: " + e.Message);
    285 									--i;
    286 								}
    287 							}
    288 							else if (File.Exists(InstallerResponse + @"\include\services.h"))
    289 							{
    290 								Console.WriteLine("You cannot use the Anope source directory as the target directory!");
    291 								--i;
    292 							}
    293 							else
    294 								InstallDirectory = InstallerResponse;
    295 							break;
    296 						case 1:
    297 							UseNMake = CheckResponse(InstallerResponse);
    298 							if (UseNMake)
    299 								++i;
    300 							break;
    301 						case 2:
    302 							BuildDebug = CheckResponse(InstallerResponse);
    303 							break;
    304 						case 3:
    305 							if (InstallerResponse == "NONE")
    306 								ExtraIncludeDirs = null;
    307 							else
    308 								ExtraIncludeDirs = InstallerResponse;
    309 							break;
    310 						case 4:
    311 							if (InstallerResponse == "NONE")
    312 								ExtraLibDirs = null;
    313 							else
    314 								ExtraLibDirs = InstallerResponse;
    315 							break;
    316 						case 5:
    317 							if (InstallerResponse == "NONE")
    318 								ExtraArguments = null;
    319 							else
    320 								ExtraArguments = InstallerResponse;
    321 							break;
    322 						default:
    323 							break;
    324 					}
    325 				}
    326 			}
    327 
    328 			Console.WriteLine("Anope will be compiled with the following options:");
    329 			Console.WriteLine("Install directory: {0}", InstallDirectory);
    330 			Console.WriteLine("Use NMake: {0}", UseNMake ? "Yes" : "No");
    331 			Console.WriteLine("Build debug: {0}", BuildDebug ? "Yes" : "No");
    332 			Console.WriteLine("Anope Version: {0}", AnopeVersion);
    333 			Console.WriteLine("Extra Include Directories: {0}", ExtraIncludeDirs);
    334 			Console.WriteLine("Extra Library Directories: {0}", ExtraLibDirs);
    335 			Console.WriteLine("Extra Arguments: {0}", ExtraArguments);
    336 			Console.WriteLine("Press Enter to continue...");
    337 			Console.ReadKey();
    338 
    339 			SaveCache();
    340 
    341 			if (!string.IsNullOrWhiteSpace(ExtraIncludeDirs))
    342 				ExtraIncludeDirs = string.Format("-DEXTRA_INCLUDE:STRING={0} ", ExtraIncludeDirs);
    343 			else
    344 				ExtraIncludeDirs = "";
    345 			if (!string.IsNullOrWhiteSpace(ExtraLibDirs))
    346 				ExtraLibDirs = string.Format("-DEXTRA_LIBS:STRING={0} ", ExtraLibDirs);
    347 			else
    348 				ExtraLibDirs = "";
    349 			if (!string.IsNullOrWhiteSpace(ExtraArguments))
    350 				ExtraArguments += " ";
    351 			else
    352 				ExtraArguments = "";
    353 
    354 			InstallDirectory = "-DINSTDIR:STRING=\"" + InstallDirectory.Replace('\\', '/') + "\" ";
    355 			string NMake = UseNMake ? "-G\"NMake Makefiles\" " : "";
    356 			string Debug = BuildDebug ? "-DCMAKE_BUILD_TYPE:STRING=DEBUG " : "-DCMAKE_BUILD_TYPE:STRING=RELEASE ";
    357 			string cMake = InstallDirectory + NMake + Debug + ExtraIncludeDirs + ExtraLibDirs + ExtraArguments + "\"" + ExecutablePath.Replace('\\', '/') + "\"";
    358 			RunCMake(cMake);
    359 
    360 			return 0;
    361 		}
    362 	}
    363 }