rename net_2_1 to moonlight
[mono.git] / msvc / scripts / genproj.cs
index 337fbdc7a74fe8d4c477fd627179727b419f7610..a42fb3ec64b0555121b171dfbaa496daa16a6ec9 100644 (file)
@@ -3,6 +3,7 @@ using System.IO;
 using System.Collections.Generic;
 using System.Text;
 using System.Globalization;
+using System.Xml.Linq;
 
 public enum Target {
        Library, Exe, Module, WinExe
@@ -18,52 +19,143 @@ public enum LanguageVersion
        Default         = LINQ
 }
 
-class MsbuildGenerator {
-       static string read ()
+class SlnGenerator {
+       const string header = "Microsoft Visual Studio Solution File, Format Version 10.00\n" +
+               "# Visual Studio 2008";
+
+       const string project_start = "Project(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{0}\", \"{1}\", \"{{{2}}}\"";
+       const string project_end = "EndProject";
+
+       Dictionary<string, string> libraries = new Dictionary<string, string> ();
+
+       public void Add (string library)
        {
-               return Console.ReadLine ();
+               try {
+                       libraries.Add (library, Guid.NewGuid ().ToString ().ToUpper ());
+               }
+               catch (Exception ex) {
+                       Console.WriteLine (ex);
+               }
        }
 
-       // Currently used
-       static bool Unsafe = false;
-       static StringBuilder defines = new StringBuilder ();
-       static bool StdLib = true;
+       public void Write (string filename)
+       {
+               using (var sln = new StreamWriter (filename)) {
+                       sln.WriteLine ();
+                       sln.WriteLine (header);
+                       foreach (var library in libraries) {
+                               var library_name = Path.GetFileNameWithoutExtension (library.Key);
+                               sln.WriteLine (project_start, library_name, library.Key, library.Value);
+                               sln.WriteLine (project_end);
+                       }
+                       sln.WriteLine ("Global");
 
-       // Currently unused
-       static Target Target = Target.Exe;
-       static string TargetExt = ".exe";
-       static string OutputFile;
-       static bool Optimize = true;
-       static bool VerifyClsCompliance = true;
-
-       static string win32IconFile;
-       static bool want_debugging_support = false;
-       static bool Checked = false;
-       static bool WarningsAreErrors;
-       static Dictionary<string,string> embedded_resources = new Dictionary<string,string> ();
-       static List<string> references = new List<string> ();
-       static List<string> warning_as_error = new List<string> ();
-       static int WarningLevel = 4;
-       static List<int> ignore_warning = new List<int> ();
-       static bool load_default_config = true;
-       static string StrongNameKeyFile;
-       static string StrongNameKeyContainer;
-       static bool StrongNameDelaySign = false;
-       static LanguageVersion Version = LanguageVersion.Default;
-       static string CodePage;
-
-       static readonly char[] argument_value_separator = new char [] { ';', ',' };
+                       sln.WriteLine ("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
+                       sln.WriteLine ("\t\tDebug|Any CPU = Debug|Any CPU");
+                       sln.WriteLine ("\t\tRelease|Any CPU = Release|Any CPU");
+                       sln.WriteLine ("\tEndGlobalSection");
+                       
+                       sln.WriteLine ("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
+                       foreach (var library in libraries) {
+                               sln.WriteLine ("\t\t{{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", library.Value);
+                               sln.WriteLine ("\t\t{{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU", library.Value);
+                               sln.WriteLine ("\t\t{{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU", library.Value);
+                               sln.WriteLine ("\t\t{{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU", library.Value);
+                       }
+                       sln.WriteLine ("\tEndGlobalSection");
+                               
+                       sln.WriteLine ("\tGlobalSection(SolutionProperties) = preSolution");
+                       sln.WriteLine ("\t\tHideSolutionNode = FALSE");
+                       sln.WriteLine ("\tEndGlobalSection");
+
+                       sln.WriteLine ("EndGlobal");
+               }
+       }
+}
 
+class MsbuildGenerator {
        static void Usage ()
        {
                Console.WriteLine ("Invalid argument");
        }
+
+       static string template;
+       static MsbuildGenerator ()
+       {
+               using (var input = new StreamReader ("csproj.tmpl")){
+                       template = input.ReadToEnd ();
+               }
+       }
+
+       // The directory as specified in order.xml
+       string dir;
+
+       //
+       // Our base directory, this is relative to our exectution point mono/msvc/scripts
+       string base_dir;
+
+       string mcs_topdir;
+
+       // Class directory, relative to 
+       string class_dir;
+       
+       public MsbuildGenerator (string dir)
+       {
+               this.dir = dir;
+               
+               if (dir == "mcs"){
+                       mcs_topdir = "..\\";
+                       class_dir = "..\\class\\";
+                       base_dir = "..\\..\\..\\mcs\\mcs";
+               } else {
+                       mcs_topdir = "..\\";
+                       
+                       foreach (char c in dir){
+                               if (c == '/')
+                                       mcs_topdir = "..\\" + mcs_topdir;
+                       }
+                       class_dir = mcs_topdir.Substring (3);
+                       
+                       base_dir = "..\\..\\..\\mcs\\" + dir;
+               }
+       }
        
+       // Currently used
+       bool Unsafe = false;
+       StringBuilder defines = new StringBuilder ();
+       bool StdLib = true;
+
+       // Currently unused
+       Target Target = Target.Exe;
+       string TargetExt = ".exe";
+       string OutputFile;
+       bool Optimize = true;
+       bool VerifyClsCompliance = true;
+
+       string win32IconFile;
+       bool want_debugging_support = false;
+       bool Checked = false;
+       bool WarningsAreErrors;
+       Dictionary<string,string> embedded_resources = new Dictionary<string,string> ();
+       List<string> references = new List<string> ();
+       List<string> reference_aliases = new List<string> ();
+       List<string> warning_as_error = new List<string> ();
+       int WarningLevel = 4;
+       List<int> ignore_warning = new List<int> ();
+       bool load_default_config = true;
+       string StrongNameKeyFile;
+       string StrongNameKeyContainer;
+       bool StrongNameDelaySign = false;
+       LanguageVersion Version = LanguageVersion.Default;
+       string CodePage;
+
+       readonly char[] argument_value_separator = new char [] { ';', ',' };
+
        //
        // This parses the -arg and /arg options to the compiler, even if the strings
        // in the following text use "/arg" on the strings.
        //
-       static bool CSCParseOption (string option, ref string [] args)
+       bool CSCParseOption (string option, ref string [] args)
        {
                int idx = option.IndexOf (':');
                string arg, value;
@@ -199,12 +291,8 @@ class MsbuildGenerator {
                                string val = r;
                                int index = val.IndexOf ('=');
                                if (index > -1) {
-                                       Console.WriteLine ("/reference = not supported");
-                                       Environment.Exit (1);
-                                       //string alias = r.Substring (0, index);
-                                       //string assembly = r.Substring (index + 1);
-                                       //AddExternAlias (alias, assembly);
-                                       //return true;
+                                       reference_aliases.Add (r);
+                                       continue;
                                }
 
                                if (val.Length != 0)
@@ -219,9 +307,8 @@ class MsbuildGenerator {
                case "/doc": 
                case "/lib": 
                {
-                       Console.WriteLine ("{0} = not supported", option);
-                       Environment.Exit (1);
-                       return true;
+                       Console.WriteLine ("{0} = not supported", arg);
+                       throw new Exception ();
                }
                case "/win32icon": {
                        win32IconFile = value;
@@ -377,84 +464,136 @@ class MsbuildGenerator {
                return false;
        }
 
-       static string FindMcsRoot ()
+       static string [] LoadArgs (string file)
        {
-               string p = Path.GetFullPath (".");
-               string steps = "";
-
-               while (p != Path.GetPathRoot (p)){
-                       if (Directory.Exists (Path.Combine (p, "jay")) &&
-                           Directory.Exists (Path.Combine (p, "ilasm")))
-                               return steps;
-
-                       p = Path.GetFullPath (Path.Combine (p, ".."));
-                       steps = Path.Combine (steps, "..");
+               StreamReader f;
+               var args = new List<string> ();
+               string line;
+               try {
+                       f = new StreamReader (file);
+               } catch {
+                       return null;
                }
-               Console.WriteLine ("Can not detect the root of MCS");
-               Environment.Exit (1);
-               return null;
+               
+               StringBuilder sb = new StringBuilder ();
+               
+               while ((line = f.ReadLine ()) != null){
+                       int t = line.Length;
+                       
+                       for (int i = 0; i < t; i++){
+                               char c = line [i];
+                               
+                               if (c == '"' || c == '\''){
+                                       char end = c;
+                                       
+                                       for (i++; i < t; i++){
+                                               c = line [i];
+                                               
+                                               if (c == end)
+                                                       break;
+                                               sb.Append (c);
+                                       }
+                               } else if (c == ' '){
+                                       if (sb.Length > 0){
+                                               args.Add (sb.ToString ());
+                                               sb.Length = 0;
+                                       }
+                               } else
+                                       sb.Append (c);
+                       }
+                       if (sb.Length > 0){
+                               args.Add (sb.ToString ());
+                               sb.Length = 0;
+                       }
+               }
+               
+               string [] ret_value = new string [args.Count];
+               args.CopyTo (ret_value, 0);
+               
+               return ret_value;
        }
 
-       static string FindClassRoot ()
+       static string Load (string f)
        {
-               string p = Path.GetFullPath (".");
-               string steps = "";
-
-               while (p != Path.GetPathRoot (p)){
-                       if (Directory.Exists (Path.Combine (p, "corlib")) &&
-                           Directory.Exists (Path.Combine (p, "Managed.Windows.Forms")))
-                               return steps;
-
-                       p = Path.GetFullPath (Path.Combine (p, ".."));
-                       steps = Path.Combine (steps, "..");
-               }
-               Console.WriteLine ("Can not detect the mcs/class directory");
-               Environment.Exit (1);
-               return null;
+               if (File.Exists (f)){
+                       using (var sr = new StreamReader (f)){
+                               return sr.ReadToEnd ();
+                       }
+               } else
+                       return "";
        }
-
-       static void Main (string [] args)
+       
+       public string Generate (XElement xproject)
        {
-               if (args.Length != 2){
-                       Console.WriteLine ("You must specify the template file and the output file");
-                       return;
-               }
-               
+               string library = xproject.Attribute ("library").Value;
                string boot, mcs, flags, output_name, built_sources, library_output, response;
 
-               boot = read ();
-               mcs = read ();
-               flags = read ();
-               output_name = read ();
-               built_sources = read ();
-               library_output = read ();
-               response = read ();
+               boot  = xproject.Element ("boot").Value;
+               mcs   = xproject.Element ("mcs").Value;
+               flags = xproject.Element ("flags").Value;
+               output_name =xproject.Element ("output").Value;
+               built_sources = xproject.Element ("built_sources").Value;
+               library_output = xproject.Element ("library_output").Value;
+               response = xproject.Element ("response").Value;
 
-               string [] f = flags.Split ();
-               for (int i = 0; i < f.Length; i++){
-                       if (f [i][0] == '-')
-                               f [i] = "/" + f [i].Substring (1);
+               //
+               // Prebuild code, might be in inputs, check:
+               //  inputs/LIBRARY-PROFILE.pre
+               //  inputs/LIBRARY.pre
+               //
+               string prebuild = Load (library + ".pre");
 
-                       if (CSCParseOption (f [i], ref f))
-                               continue;
-                       Console.WriteLine ("Failure with {0}", f [i]);
-                       Environment.Exit (1);
-               }
+               int q = library.IndexOf ("-");
+               if (q != -1)
+                       prebuild = prebuild + Load (library.Substring (0, q) + ".pre");
+                       
+               var all_args = new Queue<string []> ();
+               all_args.Enqueue (flags.Split ());
+               while (all_args.Count > 0){
+                       string [] f = all_args.Dequeue ();
+                       
+                       for (int i = 0; i < f.Length; i++){
+                               if (f [i][0] == '-')
+                                       f [i] = "/" + f [i].Substring (1);
+                               
+                               if (f [i][0] == '@') {
+                                       string [] extra_args;
+                                       string response_file = f [i].Substring (1);
+                                       
+                                       extra_args = LoadArgs (base_dir + "\\" + response_file);
+                                       if (extra_args == null) {
+                                               Console.WriteLine ("Unable to open response file: " + response_file);
+                                               Environment.Exit (1);
+                                       }
 
+                                       all_args.Enqueue (extra_args);
+                                       continue;
+                               }
+                               
+                               if (CSCParseOption (f [i], ref f))
+                                       continue;
+                               Console.WriteLine ("Failure with {0}", f [i]);
+                               Environment.Exit (1);
+                       }
+               }
+               
                string [] source_files;
-               using (var reader = new StreamReader (response)){
+               using (var reader = new StreamReader (base_dir + "\\" + response)){
                        source_files  = reader.ReadToEnd ().Split ();
                }
                StringBuilder sources = new StringBuilder ();
                foreach (string s in source_files){
                        if (s.Length == 0)
                                continue;
-                       sources.Append (String.Format ("   <Compile Include=\"{0}\" />\n", s));
+                       sources.Append (String.Format ("   <Compile Include=\"{0}\" />\n", s.Replace ("/", "\\")));
+               }
+               foreach (string s in built_sources.Split ()){
+                       if (s.Length == 0)
+                               continue;
+                       
+                       sources.Append (String.Format ("   <Compile Include=\"{0}\" />\n", s.Replace ("/", "\\")));
                }
                
-               var input = new StreamReader (args [0]);
-               string template = input.ReadToEnd ();
-
                //
                // Compute the csc command that we need to use
                //
@@ -467,20 +606,20 @@ class MsbuildGenerator {
                        mcs = mcs.Substring (10);
                
                var compiler = mcs.Substring (mcs.LastIndexOf (' ') + 1);
-               if (compiler.EndsWith ("class/lib/basic/mcs.exe"))
-                       compiler = "basic";
-               else if (compiler.EndsWith ("class/lib/net_1_1_bootstrap/mcs.exe"))
-                       compiler = "net_1_1_bootstrap";
-               else if (compiler.EndsWith ("class/lib/net_1_1/mcs.exe"))
-                       compiler = "net_1_1";
+               if (compiler.EndsWith ("class/lib/basic/gmcs.exe"))
+                       compiler = "gmcs";
                else if (compiler.EndsWith ("class/lib/net_2_0_bootstrap/gmcs.exe"))
                        compiler = "net_2_0_bootstrap";
                else if (compiler.EndsWith ("mcs/gmcs.exe"))
                        compiler = "gmcs";
-               else if (compiler.EndsWith ("class/lib/net_2_1_bootstrap/smcs.exe"))
-                       compiler = "net_2_1_bootstrap";
-               else if (compiler.EndsWith ("class/lib/net_2_1_raw/smcs.exe"))
-                       compiler = "net_2_1_raw";
+               else if (compiler.EndsWith ("class/lib/moonlight_bootstrap/smcs.exe"))
+                       compiler = "moonlight_bootstrap";
+               else if (compiler.EndsWith ("class/lib/moonlight_raw/smcs.exe"))
+                       compiler = "moonlight_raw";
+               else if (compiler.EndsWith ("class/lib/net_4_0_bootstrap/dmcs.exe"))
+                       compiler = "net_4_0_bootstrap";
+               else if (compiler.EndsWith ("class/lib/net_4_0/dmcs.exe"))
+                       compiler = "dmcs";
                else {
                        Console.WriteLine ("Can not determine compiler from {0}", compiler);
                        Environment.Exit (1);
@@ -494,29 +633,60 @@ class MsbuildGenerator {
                }
                
                var encoded_mono_paths = string.Join ("-", mono_paths).Replace ("--", "-");
-
-               Console.WriteLine ("The root is at {0}", FindMcsRoot ());
-               string csc_tool_path = FindMcsRoot ().Replace ("/", "\\") + "\\..\\mono\\msvc\\scripts\\" + encoded_mono_paths + "-" + compiler;
-               csc_tool_path = csc_tool_path.Replace ("--", "-");
-
+               var encoded_mp_compiler = (encoded_mono_paths + "-" + compiler).Replace ("--", "-");
+               
+               string csc_tool_path = mcs_topdir + "..\\mono\\msvc\\scripts\\" + encoded_mp_compiler;
+               if (!Directory.Exists (encoded_mp_compiler)){
+                       Console.WriteLine ("Created {0}", encoded_mp_compiler);
+                       Directory.CreateDirectory (encoded_mp_compiler);
+               }
+               if (!File.Exists (Path.Combine (encoded_mp_compiler, "csc.exe"))){
+                       File.Copy ("monowrap.exe", Path.Combine (encoded_mp_compiler, "csc.exe"));
+                       File.Copy ("monowrap.pdb", Path.Combine (encoded_mp_compiler, "csc.pdb"));
+               }
+               
                var refs = new StringBuilder ();
+               //
+               // mcs is different that csc in this regard, somehow with -noconfig we still import System and System.XML
+               //
+               if (dir == "mcs" && !load_default_config){
+                       references.Add ("System.dll");
+                       references.Add ("System.Xml.dll");
+               }
                
-               if (references.Count > 0){
+               if (references.Count > 0 || reference_aliases.Count > 0){
                        refs.Append ("<ItemGroup>\n");
-                       string class_root = FindClassRoot ();
                        string last = mono_paths [0].Substring (mono_paths [0].LastIndexOf ('/') + 1);
                        
-                       string hint_path = FindClassRoot () + "\\lib\\" + last;
-                       
+                       string hint_path = class_dir + "\\lib\\" + last;
+
                        foreach (string r in references){
                                refs.Append ("    <Reference Include=\"" + r + "\">\n");
                                refs.Append ("      <SpecificVersion>False</SpecificVersion>\n");
                                refs.Append ("      <HintPath>" + hint_path + "\\" + r + "</HintPath>\n");
                                refs.Append ("    </Reference>\n");
                        }
+
+                       foreach (string r in reference_aliases){
+                               int index = r.IndexOf ('=');
+                               string alias = r.Substring (0, index);
+                               string assembly = r.Substring (index + 1);
+
+                               refs.Append ("    <Reference Include=\"" + assembly + "\">\n");
+                               refs.Append ("      <SpecificVersion>False</SpecificVersion>\n");
+                               refs.Append ("      <HintPath>" + hint_path + "\\" + r + "</HintPath>\n");
+                               refs.Append ("      <Aliases>" + alias + "</Aliases>\n");
+                               refs.Append ("    </Reference>\n");
+                       }
                        
                        refs.Append ("  </ItemGroup>\n");
                }
+
+               try {
+                       Path.GetDirectoryName (library_output);
+               } catch {
+                       Console.WriteLine ("Error in path: {0} while processing {1}", library_output, library);
+               }
                
                //
                // Replace the template values
@@ -530,11 +700,60 @@ class MsbuildGenerator {
                        Replace ("@DEFINECONSTANTS@", defines.ToString ()).
                        Replace ("@CSCTOOLPATH@", csc_tool_path).
                        Replace ("@DEBUG@", want_debugging_support ? "true" : "false").
+                       Replace ("@DEBUGTYPE@", want_debugging_support ? "full" : "pdbonly").
                        Replace ("@REFERENCES@", refs.ToString ()).
+                       Replace ("@PREBUILD@", prebuild).
                        Replace ("@SOURCES@", sources.ToString ());
 
-               using (var o = new StreamWriter (args [1])){
+
+               string ofile = "..\\..\\..\\mcs\\" + dir + "\\" + library + ".csproj";
+               ofile = ofile.Replace ('/', '\\');
+               //Console.WriteLine ("Generated {0}", ofile.Replace ("\\", "/"));
+               using (var o = new StreamWriter (ofile)){
                        o.WriteLine (output);
                }
+
+               return ofile;
        }
-}
\ No newline at end of file
+       
+}
+
+public class Driver {
+       
+       static void Main (string [] args)
+       {
+               if (!File.Exists ("genproj.cs") || !File.Exists ("monowrap.cs")){
+                       Console.WriteLine ("This command should be ran from mono/msvc/scripts");
+                       Environment.Exit (1);
+               }
+
+               var sln_gen = new SlnGenerator ();
+               XDocument doc = XDocument.Load ("order.xml");
+               foreach (XElement project in doc.Root.Elements ()){
+                       string dir = project.Attribute ("dir").Value;
+                       string library = project.Attribute ("library").Value;
+
+                       //
+                       // Do only class libraries for now
+                       //
+                       if (!(dir.StartsWith ("class") || dir.StartsWith ("mcs")))
+                               continue;
+
+                       //
+                       // Do not do 2.1, it is not working yet
+                       // Do not do basic, as there is no point (requires a system mcs to be installed).
+                       //
+                       if (library.Contains ("moonlight") || library.Contains ("-basic"))
+                               continue;
+                       
+                       var gen = new MsbuildGenerator (dir);
+                       try {
+                               sln_gen.Add (gen.Generate (project));
+                       } catch (Exception e) {
+                               Console.WriteLine ("Error in {0}\n{1}", dir, e);
+                       }
+               }
+               sln_gen.Write ("mcs_full.sln");
+    }
+
+}