[genproj] Do not use \r on the Unix parts of the build hook, add RabbitMQ hooks
[mono.git] / msvc / scripts / genproj.cs
index b8f01a62291de9f5599f94f9edc7da2de19622cf..7c775bb70c9b554b0b0df1092e9c5ae59d026546 100644 (file)
@@ -70,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");
@@ -650,7 +654,7 @@ class MsbuildGenerator {
 
        public VsCsproj Csproj;
 
-       public VsCsproj Generate (Dictionary<string,MsbuildGenerator> projects, bool showWarnings = false)
+       public VsCsproj Generate (string library_output, Dictionary<string,MsbuildGenerator> projects, bool showWarnings = false)
        {
                var generatedProjFile = NativeName (Csproj.csProjFilename);
                //Console.WriteLine ("Generating: {0}", generatedProjFile);
@@ -692,29 +696,10 @@ class MsbuildGenerator {
                }
                //
                // Prebuild code, might be in inputs, check:
-               //  inputs/LIBRARY-PROFILE.pre
                //  inputs/LIBRARY.pre
                //
-               string prebuild = Load (library + ".pre");
-               string prebuild_windows, prebuild_unix;
-               
-               int q = library.IndexOf ("-");
-               if (q != -1)
-                       prebuild = prebuild + Load (library.Substring (0, q) + ".pre");
-
-               if (prebuild.IndexOf ("@MONO@") != -1){
-                       prebuild_unix = prebuild.Replace ("@MONO@", "mono").Replace ("@CAT@", "cat");
-                       prebuild_windows = prebuild.Replace ("@MONO@", "").Replace ("@CAT@", "type");
-               } else {
-                       prebuild_unix = prebuild.Replace ("jay.exe", "jay");
-                       prebuild_windows = prebuild;
-               }
-               
-               const string condition_unix    = "Condition=\" '$(OS)' != 'Windows_NT' \"";
-               const string condition_windows = "Condition=\" '$(OS)' == 'Windows_NT' \"";
-               prebuild =
-                       "    <PreBuildEvent " + condition_unix + ">" + NewLine + prebuild_unix + NewLine + "    </PreBuildEvent>" + NewLine +
-                       "    <PreBuildEvent " + condition_windows + ">" + NewLine + prebuild_windows + NewLine + "    </PreBuildEvent>" + NewLine;
+               string prebuild = GenerateStep (library, ".pre", "PreBuildEvent");
+               string postbuild = GenerateStep (library, ".post", "PostBuildEvent");
 
                var all_args = new Queue<string []> ();
                all_args.Enqueue (flags.Split ());
@@ -732,7 +717,7 @@ class MsbuildGenerator {
                                        var resp_file_full = Path.Combine (base_dir, response_file);
                                        extra_args = LoadArgs (resp_file_full);
                                        if (extra_args == null) {
-                                               Console.WriteLine ("Unable to open response file: " + resp_file_full);
+                                               Console.WriteLine ($"{library_output}: Unable to open response file: {resp_file_full}");
                                                Environment.Exit (1);
                                        }
 
@@ -742,13 +727,12 @@ class MsbuildGenerator {
 
                                if (CSCParseOption (f [i], ref f))
                                        continue;
-                               Console.WriteLine ("Failure with {0}", f [i]);
+                               Console.WriteLine ("{library_output}: Failure with {0}", f [i]);
                                Environment.Exit (1);
                        }
                }
 
                string [] source_files;
-               //Console.WriteLine ("Base: {0} res: {1}", base_dir, response);
                using (var reader = new StreamReader (NativeName (base_dir + "\\" + response))) {
                        source_files = reader.ReadToEnd ().Split ();
                }
@@ -808,7 +792,10 @@ class MsbuildGenerator {
                if (embedded_resources.Count > 0) {
                        resources.AppendFormat ("  <ItemGroup>" + NewLine);
                        foreach (var dk in embedded_resources) {
-                               resources.AppendFormat ("    <EmbeddedResource Include=\"{0}\">" + NewLine, dk.Key);
+                               var source = dk.Key;
+                               if (source.EndsWith (".resources"))
+                                       source = source.Replace (".resources", ".resx");
+                               resources.AppendFormat ("    <EmbeddedResource Include=\"{0}\">" + NewLine, source);
                                resources.AppendFormat ("      <LogicalName>{0}</LogicalName>" + NewLine, dk.Value);
                                resources.AppendFormat ("    </EmbeddedResource>" + NewLine);
                        }
@@ -827,19 +814,19 @@ class MsbuildGenerator {
                        //  <Name>System-basic</Name>
                        //</ProjectReference>
                        var refdistinct = references.Distinct ();
-                       foreach (string r in refdistinct) {
+                       foreach (string reference in refdistinct) {
                                
-                               var match = GetMatchingCsproj (r, projects);
+                               var match = GetMatchingCsproj (library_output, reference, projects);
                                if (match != null) {
-                                       AddProjectReference (refs, Csproj, match, r, null);
+                                       AddProjectReference (refs, Csproj, match, reference, null);
                                } else {
                                        if (showWarnings){
-                                               Console.WriteLine ("{0}: Could not find a matching project reference for {1}", library, Path.GetFileName (r));
+                                               Console.WriteLine ("{0}: Could not find a matching project reference for {1}", library, Path.GetFileName (reference));
                                                Console.WriteLine ("  --> Adding reference with hintpath instead");
                                        }
-                                       refs.Append ("    <Reference Include=\"" + r + "\">" + NewLine);
+                                       refs.Append ("    <Reference Include=\"" + reference + "\">" + NewLine);
                                        refs.Append ("      <SpecificVersion>False</SpecificVersion>" + NewLine);
-                                       refs.Append ("      <HintPath>" + r + "</HintPath>" + NewLine);
+                                       refs.Append ("      <HintPath>" + reference + "</HintPath>" + NewLine);
                                        refs.Append ("      <Private>False</Private>" + NewLine);
                                        refs.Append ("    </Reference>" + NewLine);
                                }
@@ -849,7 +836,7 @@ class MsbuildGenerator {
                                int index = r.IndexOf ('=');
                                string alias = r.Substring (0, index);
                                string assembly = r.Substring (index + 1);
-                               var match = GetMatchingCsproj (assembly, projects, explicitPath: true);
+                               var match = GetMatchingCsproj (library_output, assembly, projects, explicitPath: true);
                                if (match != null) {
                                        AddProjectReference (refs, Csproj, match, r, alias);
                                } else {
@@ -873,15 +860,6 @@ class MsbuildGenerator {
                        build_output_dir = Path.GetDirectoryName (LibraryOutput);
                else
                        build_output_dir = "bin\\Debug\\" + library;
-               
-
-               string postbuild_unix = string.Empty;
-               string postbuild_windows = string.Empty;
-
-               var postbuild =  
-                       "    <PostBuildEvent " + condition_unix + ">" + NewLine + postbuild_unix + NewLine + "    </PostBuildEvent>" + NewLine +
-                       "    <PostBuildEvent " + condition_windows + ">" + NewLine + postbuild_windows + NewLine + "    </PostBuildEvent>";
-                       
 
                bool basic_or_build = (library.Contains ("-basic") || library.Contains ("-build"));
 
@@ -913,13 +891,14 @@ class MsbuildGenerator {
                        Replace ("@FX_VERSION", fx_version).
                        Replace ("@ASSEMBLYNAME@", Path.GetFileNameWithoutExtension (output_name)).
                        Replace ("@OUTPUTDIR@", build_output_dir).
+                       Replace ("@OUTPUTSUFFIX@", Path.GetFileName (build_output_dir)).
                        Replace ("@DEFINECONSTANTS@", defines.ToString ()).
                        Replace ("@DEBUG@", want_debugging_support ? "true" : "false").
                        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 ("@STARTUPOBJECT@", main == null ? "" : $"<StartupObject>{main}</StartupObject>").
                        //Replace ("@ADDITIONALLIBPATHS@", String.Format ("<AdditionalLibPaths>{0}</AdditionalLibPaths>", string.Join (",", libs.ToArray ()))).
                        Replace ("@ADDITIONALLIBPATHS@", String.Empty).
                        Replace ("@RESOURCES@", resources.ToString ()).
@@ -934,6 +913,30 @@ class MsbuildGenerator {
                return Csproj;
        }
 
+       string GenerateStep (string library, string suffix, string eventKey)
+       {
+               string target = Load (library + suffix);
+               string target_windows, target_unix;
+
+               int q = library.IndexOf ("-");
+               if (q != -1)
+                       target = target + Load (library.Substring (0, q) + suffix);
+                       
+               if (target.IndexOf ("@MONO@") != -1){
+                       target_unix = target.Replace ("@MONO@", "mono").Replace ("@CAT@", "cat");
+                       target_windows = target.Replace ("@MONO@", "").Replace ("@CAT@", "type");
+               } else {
+                       target_unix = target.Replace ("jay.exe", "jay");
+                       target_windows = target;
+               }
+               const string condition_unix    = "Condition=\" '$(OS)' != 'Windows_NT' \"";
+               const string condition_windows = "Condition=\" '$(OS)' == 'Windows_NT' \"";
+               var result =
+                       $"    <{eventKey} {condition_unix}>\n{target_unix}\n    </{eventKey}>{NewLine}" +
+                       $"    <{eventKey} {condition_windows}>{NewLine}{target_windows}{NewLine}    </{eventKey}>";
+               return result;
+       }
+       
        void AddProjectReference (StringBuilder refs, VsCsproj result, MsbuildGenerator match, string r, string alias)
        {
                refs.AppendFormat ("    <ProjectReference Include=\"{0}\">{1}", GetRelativePath (result.csProjFilename, match.CsprojFilename), NewLine);
@@ -957,11 +960,11 @@ class MsbuildGenerator {
                return ret;
        }
 
-       MsbuildGenerator GetMatchingCsproj (string dllReferenceName, Dictionary<string,MsbuildGenerator> projects, bool explicitPath = false)
+       MsbuildGenerator GetMatchingCsproj (string library_output, string dllReferenceName, Dictionary<string,MsbuildGenerator> projects, bool explicitPath = false)
        {
                // libDir would be "./../../class/lib/net_4_x for example
                // project 
-               if (!dllReferenceName.EndsWith (".dll"))
+               if (!dllReferenceName.EndsWith (".dll") && !dllReferenceName.EndsWith (".exe"))
                        dllReferenceName += ".dll";
 
                var probe = Path.GetFullPath (Path.Combine (base_dir, dllReferenceName));
@@ -981,9 +984,17 @@ class MsbuildGenerator {
                                        return project.Value;
                        }
                }
-               Console.WriteLine ("Did not find referenced {0} with libs={1}", dllReferenceName, String.Join (", ", libs));
+
+               // Last attempt, try to find the library in all the projects
+               foreach (var project in projects) {
+                       if (project.Value.AbsoluteLibraryOutput.EndsWith (dllReferenceName))
+                               return project.Value;
+
+               }
+               var ljoined = String.Join (", ", libs);
+               Console.WriteLine ($"{library_output}: did not find referenced {dllReferenceName} with libs={ljoined}");
                foreach (var p in projects) {
-               //      Console.WriteLine ("{0}", p.Value.AbsoluteLibraryOutput);
+                       Console.WriteLine ("{0}", p.Value.AbsoluteLibraryOutput);
                }
                return null;
        }
@@ -1000,6 +1011,7 @@ public class Driver {
                        string library = project.Attribute ("library").Value;
                        var profile = project.Element ("profile").Value;
 
+#if false
                        // Skip facades for now, the tool doesn't know how to deal with them yet.
                        if (dir.Contains ("Facades"))
                                continue;
@@ -1019,7 +1031,7 @@ public class Driver {
                                        yield return project;
                                continue;
                        }
-                       
+#endif
                        //
                        // 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).
@@ -1030,9 +1042,17 @@ public class Driver {
                        // The next ones are to make debugging easier for now
                        if (profile == "basic")
                                continue;
-                       if (profile != "net_4_x" || library.Contains ("tests"))
-                               continue;
 
+                       // For now -- problem is, our resolver currently only considers the assembly name, and we ahve
+                       // conflicing 2.0 and 2.4 versions so for now, we just skip the nunit20 versions
+                       if (dir.Contains ("nunit20"))
+                               continue;
+                       
+#if true
+                       if (profile != "net_4_x" || library.Contains ("tests")) 
+                               continue;
+#endif
+                       //Console.WriteLine ("Going to handle {0}", library);
                        yield return project;
                }
        }
@@ -1074,9 +1094,10 @@ public class Driver {
                }
                foreach (var project in GetProjects (makefileDeps)){
                        var library_output = project.Element ("library_output").Value;
+                       //Console.WriteLine ("=== {0} ===", library_output);
                        var gen = projects [library_output];
                        try {
-                               var csproj = gen.Generate (projects);
+                               var csproj = gen.Generate (library_output, projects);
                                var csprojFilename = csproj.csProjFilename;
                                if (!sln_gen.ContainsProjectIdentifier (csproj.library)) {
                                        sln_gen.Add (csproj);
@@ -1103,7 +1124,7 @@ public class Driver {
                        Console.WriteLine (sb.ToString ());
                }
 
-               WriteSolution (four_five_sln_gen, MakeSolutionName (MsbuildGenerator.profile_4_x));
+               WriteSolution (four_five_sln_gen, Path.Combine ("..", "..", MakeSolutionName (MsbuildGenerator.profile_4_x)));
 
                if (makefileDeps){
                        const string classDirPrefix = "./../../";
@@ -1127,7 +1148,7 @@ public class Driver {
                
                // A few other optional solutions
                // Solutions with 'everything' and the most common libraries used in development may be of interest
-               //WriteSolution (sln_gen, "mcs_full.sln");
+               //WriteSolution (sln_gen, "./mcs_full.sln");
                //WriteSolution (small_full_sln_gen, "small_full.sln");
                // The following may be useful if lacking visual studio or MonoDevelop, to bootstrap mono compiler self-hosting
                //WriteSolution (basic_sln_gen, "mcs_basic.sln");