Graduate the csproj/solution to completed - you can now build with the toplevel net_4...
[mono.git] / msvc / scripts / genproj.cs
index 49967e6eefb4356903817f8b26b27bc520a659a5..e220a95a5064211fa66452f243715c49347846c1 100644 (file)
@@ -1,3 +1,16 @@
+//
+// Consumes the order.xml file that contains a list of all the assemblies to build
+// and produces a solution and the csproj files for it
+//
+// Currently this hardcodes a set of assemblies to build, the net-4.x series, but 
+// it can be extended to handle the command line tools.
+//
+// KNOWN ISSUES:
+//    * This fails to find matches for "System" and "System.xml" when processing the
+//      RabbitMQ executable, likely, because we do not process executables yet
+//
+//    * Has not been tested in a while with the command line tools
+//
 using System;
 using System.IO;
 using System.Collections.Generic;
@@ -57,11 +70,15 @@ class SlnGenerator {
 
        public void Write (string filename)
        {
+               var fullPath = Path.GetDirectoryName (filename) + "/";
+               
                using (var sln = new StreamWriter (filename)) {
                        sln.WriteLine ();
                        sln.WriteLine (header);
                        foreach (var proj in libraries) {
-                               sln.WriteLine (project_start, proj.library, proj.csProjFilename, proj.projectGuid);
+                               var unixProjFile = proj.csProjFilename.Replace ("\\", "/");
+                               var fullProjPath = Path.GetFullPath (unixProjFile);
+                               sln.WriteLine (project_start, proj.library, MsbuildGenerator.GetRelativePath (fullPath, fullProjPath), proj.projectGuid);
                                sln.WriteLine (project_end);
                        }
                        sln.WriteLine ("Global");
@@ -104,7 +121,7 @@ class MsbuildGenerator {
        public const string profile_2_0 = "_2_0";
        public const string profile_3_5 = "_3_5";
        public const string profile_4_0 = "_4_0";
-       public const string profile_4_5 = "_4_5";
+       public const string profile_4_x = "_4_x";
 
        static void Usage ()
        {
@@ -190,6 +207,7 @@ class MsbuildGenerator {
        StringBuilder defines = new StringBuilder ();
        bool Optimize = true;
        bool want_debugging_support = false;
+       string main = null;
        Dictionary<string, string> embedded_resources = new Dictionary<string, string> ();
        List<string> warning_as_error = new List<string> ();
        List<int> ignore_warning = new List<int> ();
@@ -198,7 +216,7 @@ class MsbuildGenerator {
        List<string> references = new List<string> ();
        List<string> libs = new List<string> ();
        List<string> reference_aliases = new List<string> ();
-       bool showWarnings = false;
+       bool showWarnings = true;
 
        // Currently unused
 #pragma warning disable 0219, 0414
@@ -210,7 +228,7 @@ class MsbuildGenerator {
        string win32IconFile;
        string StrongNameKeyFile;
        bool copyLocal = true;
-       Target Target = Target.Exe;
+       Target Target = Target.Library;
        string TargetExt = ".exe";
        string OutputFile;
        string StrongNameKeyContainer;
@@ -373,6 +391,9 @@ class MsbuildGenerator {
                                return true;
                        }
                case "/main":
+                       main = value;
+                       return true;
+
                case "/m":
                case "/addmodule":
                case "/win32res":
@@ -539,6 +560,12 @@ class MsbuildGenerator {
                case "/codepage":
                        CodePage = value;
                        return true;
+
+               case "/publicsign":
+                       return true;
+                       
+               case "/-getresourcestrings":
+                       return true;
                }
 
                Console.WriteLine ("Failing with : {0}", arg);
@@ -637,9 +664,11 @@ class MsbuildGenerator {
                boot = xproject.Element ("boot").Value;
                flags = xproject.Element ("flags").Value;
                output_name = xproject.Element ("output").Value;
+               if (output_name.EndsWith (".exe"))
+                       Target = Target.Exe;
                built_sources = xproject.Element ("built_sources").Value;
                response = xproject.Element ("response").Value;
-               //if (library.EndsWith("-build")) fx_version = "2.0"; // otherwise problem if .NET4.5 is installed, seems. (https://github.com/nikhilk/scriptsharp/issues/156)
+
                profile = xproject.Element ("profile").Value;
                if (string.IsNullOrEmpty (response)) {
                        // Address the issue where entries are missing the fx_version
@@ -660,9 +689,9 @@ class MsbuildGenerator {
                        } else if (response.Contains (profile_4_0)) {
                                fx_version = "4.0";
                                profile = "net_4_0";
-                       } else if (response.Contains (profile_4_5)) {
+                       } else if (response.Contains (profile_4_x)) {
                                fx_version = "4.5";
-                               profile = "net_4_5";
+                               profile = "net_4_x";
                        }
                }
                //
@@ -803,7 +832,8 @@ class MsbuildGenerator {
                        //</ProjectReference>
                        var refdistinct = references.Distinct ();
                        foreach (string r in refdistinct) {
-                               var match = GetMatchingCsproj (Path.GetFileName (r), projects);
+                               
+                               var match = GetMatchingCsproj (r, projects);
                                if (match != null) {
                                        AddProjectReference (refs, Csproj, match, r, null);
                                } else {
@@ -875,6 +905,7 @@ class MsbuildGenerator {
                                "  </PropertyGroup>", StrongNameKeyFile, StrongNameDelaySign ? "    <DelaySign>true</DelaySign>" + NewLine : "");
                }
                Csproj.output = template.
+                       Replace ("@OUTPUTTYPE@", Target == Target.Library ? "Library" : "Exe").
                        Replace ("@SIGNATURE@", strongNameSection).
                        Replace ("@PROJECTGUID@", Csproj.projectGuid).
                        Replace ("@DEFINES@", defines.ToString ()).
@@ -891,6 +922,7 @@ class MsbuildGenerator {
                        Replace ("@DEBUGTYPE@", want_debugging_support ? "full" : "pdbonly").
                        Replace ("@REFERENCES@", refs.ToString ()).
                        Replace ("@PREBUILD@", prebuild).
+                       Replace ("@STARTUPOBJECT@", main == null ? "" : $"<StartupObject>{main}</StartupObject>").
                        Replace ("@POSTBUILD@", postbuild).
                        //Replace ("@ADDITIONALLIBPATHS@", String.Format ("<AdditionalLibPaths>{0}</AdditionalLibPaths>", string.Join (",", libs.ToArray ()))).
                        Replace ("@ADDITIONALLIBPATHS@", String.Empty).
@@ -931,25 +963,23 @@ class MsbuildGenerator {
 
        MsbuildGenerator GetMatchingCsproj (string dllReferenceName, Dictionary<string,MsbuildGenerator> projects, bool explicitPath = false)
        {
-               // libDir would be "./../../class/lib/net_4_5 for example
+               // libDir would be "./../../class/lib/net_4_x for example
                // project 
                if (!dllReferenceName.EndsWith (".dll"))
                        dllReferenceName += ".dll";
 
-               if (explicitPath){
-                       var probe = Path.GetFullPath (Path.Combine (base_dir, dllReferenceName));
-                       foreach (var project in projects){
-                               if (probe == project.Value.AbsoluteLibraryOutput)
-                                       return project.Value;
-                       }
-               } 
+               var probe = Path.GetFullPath (Path.Combine (base_dir, dllReferenceName));
+               foreach (var project in projects){
+                       if (probe == project.Value.AbsoluteLibraryOutput)
+                               return project.Value;
+               }
 
                // not explicit, search for the library in the lib path order specified
 
                foreach (var libDir in libs) {
                        var abs = Path.GetFullPath (Path.Combine (base_dir, libDir));
                        foreach (var project in projects){
-                               var probe = Path.Combine (abs, dllReferenceName);
+                               probe = Path.Combine (abs, dllReferenceName);
 
                                if (probe == project.Value.AbsoluteLibraryOutput)
                                        return project.Value;
@@ -957,7 +987,7 @@ class MsbuildGenerator {
                }
                Console.WriteLine ("Did not find referenced {0} with libs={1}", dllReferenceName, String.Join (", ", libs));
                foreach (var p in projects) {
-                       Console.WriteLine ("    => {0}", p.Value.AbsoluteLibraryOutput);
+               //      Console.WriteLine ("{0}", p.Value.AbsoluteLibraryOutput);
                }
                return null;
        }
@@ -974,6 +1004,14 @@ public class Driver {
                        string library = project.Attribute ("library").Value;
                        var profile = project.Element ("profile").Value;
 
+                       // Skip facades for now, the tool doesn't know how to deal with them yet.
+                       if (dir.Contains ("Facades"))
+                               continue;
+
+                       // These are currently broken, skip until they're fixed.
+                       if (dir.StartsWith ("mcs") || dir.Contains ("apigen"))
+                               continue;
+
                        //
                        // Do only class libraries for now
                        //
@@ -996,7 +1034,7 @@ public class Driver {
                        // The next ones are to make debugging easier for now
                        if (profile == "basic")
                                continue;
-                       if (profile != "net_4_5" || library.Contains ("tests"))
+                       if (profile != "net_4_x" || library.Contains ("tests"))
                                continue;
 
                        yield return project;
@@ -1030,9 +1068,6 @@ public class Driver {
                var makefileDeps =  (args.Length > 0 && args [0] == "deps");
 
                var sln_gen = new SlnGenerator (slnVersion);
-               var two_sln_gen = new SlnGenerator (slnVersion);
-               var four_sln_gen = new SlnGenerator (slnVersion);
-               var three_five_sln_gen = new SlnGenerator (slnVersion);
                var four_five_sln_gen = new SlnGenerator (slnVersion);
                var projects = new Dictionary<string,MsbuildGenerator> ();
 
@@ -1061,22 +1096,18 @@ public class Driver {
                Func<MsbuildGenerator.VsCsproj, bool> additionalFilter;
                additionalFilter = fullSolutions ? (Func<MsbuildGenerator.VsCsproj, bool>)null : IsCommonLibrary;
 
-               FillSolution (two_sln_gen, MsbuildGenerator.profile_2_0, projects.Values, additionalFilter);
-               FillSolution (four_five_sln_gen, MsbuildGenerator.profile_4_5, projects.Values, additionalFilter);
-               FillSolution (four_sln_gen, MsbuildGenerator.profile_4_0, projects.Values, additionalFilter);
-               FillSolution (three_five_sln_gen, MsbuildGenerator.profile_3_5, projects.Values, additionalFilter);
+               FillSolution (four_five_sln_gen, MsbuildGenerator.profile_4_x, projects.Values, additionalFilter);
 
-               var sb = new StringBuilder ();
-               sb.AppendLine ("WARNING: Skipped some project references, apparent duplicates in order.xml:");
-               foreach (var item in duplicates) {
-                       sb.AppendLine (item);
+               if (duplicates.Count () > 0) {
+                       var sb = new StringBuilder ();
+                       sb.AppendLine ("WARNING: Skipped some project references, apparent duplicates in order.xml:");
+                       foreach (var item in duplicates) {
+                               sb.AppendLine (item);
+                       }
+                       Console.WriteLine (sb.ToString ());
                }
-               Console.WriteLine (sb.ToString ());
 
-               WriteSolution (two_sln_gen, MakeSolutionName (MsbuildGenerator.profile_2_0));
-               WriteSolution (three_five_sln_gen, MakeSolutionName (MsbuildGenerator.profile_3_5));
-               WriteSolution (four_sln_gen, MakeSolutionName (MsbuildGenerator.profile_4_0));
-               WriteSolution (four_five_sln_gen, MakeSolutionName (MsbuildGenerator.profile_4_5));
+               WriteSolution (four_five_sln_gen, Path.Combine ("..", "..", MakeSolutionName (MsbuildGenerator.profile_4_x)));
 
                if (makefileDeps){
                        const string classDirPrefix = "./../../";