Esempio n. 1
0
        protected void Init()
        {
            bool debugLog       = true;
            bool multithreaded  = false;
            bool writeFiles     = false;
            bool dumpDependency = true;

            DependencyTracker.GraphWriteLegend = false;

            Builder = new Builder(
                new BuildContext.GenerateAll(debugLog, writeFiles),
                multithreaded,
                dumpDependency,
                false,
                false,
                false,
                false,
                true,
                GetGeneratorsManager,
                null
                );

            Builder.Arguments.ConfigureOrder = _configureOrder;

            // Force the test to load and register CommonPlatforms.dll as a Sharpmake extension
            // because sometimes you get the "no implementation of XX for platform YY."
            switch (_initType)
            {
            case InitType.Cpp:
            {
                // HACK: Explicitly reference something from CommonPlatforms to get
                // visual studio to load the assembly
                var platformWin64Type = typeof(Windows.Win64Platform);
                PlatformRegistry.RegisterExtensionAssembly(platformWin64Type.Assembly);
            }
            break;

            case InitType.CSharp:
            {
                var platformDotNetType = typeof(DotNetPlatform);
                PlatformRegistry.RegisterExtensionAssembly(platformDotNetType.Assembly);
            }
            break;

            default:
                throw new ArgumentOutOfRangeException(nameof(_initType), _initType, null);
            }

            Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);

            // Allow message log from builder.
            Builder.EventOutputError   += (message, args) => { ++ErrorCount; Util.LogWrite(message, args); };
            Builder.EventOutputWarning += (message, args) => { ++WarningCount; Util.LogWrite(message, args); };
            Builder.EventOutputMessage += Util.LogWrite;
            Builder.EventOutputDebug   += Util.LogWrite;
        }
Esempio n. 2
0
        private static int Main()
        {
            if (CommandLine.ContainParameter("breakintodebugger"))
            {
                System.Windows.Forms.MessageBox.Show("Debugger requested. Please attach a debugger and press OK");
                Debugger.Break();
            }
            // This GC gives a little bit better results than the other ones. "LowLatency" is giving really bad results(twice slower than the other ones).
            System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.SustainedLowLatency;

            Mutex    oneInstanceMutex = null;
            Argument parameters       = new Argument();
            ExitCode exitCode         = ExitCode.Success;

            try
            {
                DebugEnable = CommandLine.ContainParameter("verbose") || CommandLine.ContainParameter("debug") || CommandLine.ContainParameter("diagnostics");

                Version version       = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                string  versionString = string.Join(".", version.Major, version.Minor, version.Build);
                if (version.Revision != 0)
                {
                    versionString += " (non-official)";
                }
                LogWriteLine($"sharpmake {versionString}");
                LogWriteLine("  arguments : {0}", CommandLine.GetProgramCommandLine());
                LogWriteLine("  directory : {0}", Directory.GetCurrentDirectory());
                LogWriteLine(string.Empty);

                // display help if wanted and quit
                if ((CommandLine.GetProgramCommandLine().Length == 0) || CommandLine.ContainParameter("help"))
                {
                    LogWriteLine(CommandLine.GetCommandLineHelp(typeof(Argument), false));
                    return((int)ExitCode.Success);
                }

                AppDomain.CurrentDomain.AssemblyLoad += AppDomain_AssemblyLoad;

                // Log warnings and errors from builder
                Assembler.EventOutputError   += ErrorWrite;
                Assembler.EventOutputWarning += WarningWrite;

                CommandLine.ExecuteOnObject(parameters);

                if (parameters.Exit)
                {
                    return((int)ExitCode.Success);
                }

                const string  sharpmakeSymbolPrefix = "_SHARPMAKE";
                List <string> invalidSymbols        = parameters.Defines.Where(define => define.StartsWith(sharpmakeSymbolPrefix)).ToList();
                if (invalidSymbols.Any())
                {
                    string invalidSymbolsString = string.Join(", ", invalidSymbols);
                    throw new Error($"Only Sharpmake process can define symbols starting with {sharpmakeSymbolPrefix}. Invalid symbols defined: {invalidSymbolsString}");
                }

                parameters.Defines.Add($"{sharpmakeSymbolPrefix}_{version.Major}_{version.Minor}_X");
                parameters.Defines.Add($"{sharpmakeSymbolPrefix}_{version.Major}_{version.Minor}_{version.Build}");

                parameters.Validate();

                // CommonPlatforms.dll is always loaded by default because those are shipped with
                // the Sharpmake package.
                PlatformRegistry.RegisterExtensionAssembly(typeof(Windows.Win32Platform).Assembly);

                // If any platform declares its own command line options, execute and validate
                // them as well.
                IEnumerable <Platform> platformsCmdLines = PlatformRegistry.GetAvailablePlatforms <ICommandLineInterface>();
                foreach (var platform in platformsCmdLines)
                {
                    var platformCmdLine = PlatformRegistry.Get <ICommandLineInterface>(platform);
                    CommandLine.ExecuteOnObject(platformCmdLine);
                    platformCmdLine.Validate();
                }

                bool   oneInstanceMutexCreated;
                string mutexName = string.Format("SharpmakeSingleInstanceMutex{0}", parameters.MutexSuffix); // Allow custom mutex name suffix. Useful to debug concurrently multiple sharpmake running from different branches
                oneInstanceMutex = new Mutex(true, mutexName, out oneInstanceMutexCreated);

                if (!oneInstanceMutexCreated)
                {
                    try
                    {
                        if (!oneInstanceMutex.WaitOne(0))
                        {
                            LogWriteLine("wait for another instance(s) of sharpmake to terminate...");
                            oneInstanceMutex.WaitOne();
                        }
                    }
                    catch (AbandonedMutexException)
                    {
                        // This occurs if another sharpmake is killed in the debugger
                    }
                    finally
                    {
                        LogWriteLine("waiting done.");
                    }
                }

                switch (parameters.TestOption)
                {
                case TestOptions.Regression:
                {
                    var regressionTest = new BuildContext.RegressionTest(parameters.OutputDirectory, parameters.ReferenceDirectory, parameters.RemapRoot);
                    GenerateAll(regressionTest, parameters);
                    exitCode = ExitCode.Success;

                    var regressions = regressionTest.GetRegressions().ToList();
                    if (regressions.Count > 0)
                    {
                        exitCode = ExitCode.Error;
                        DebugWriteLine($"{regressions.Count} Regressions detected:");
                        List <BuildContext.RegressionTest.OutputInfo> fileChanges = regressions.Where(x => x.FileStatus == BuildContext.RegressionTest.FileStatus.Different).ToList();
                        LogFileChanges(fileChanges, parameters.RegressionDiff);

                        var fileMissing = regressions.Where(x => x.FileStatus == BuildContext.RegressionTest.FileStatus.NotGenerated).Select(x => x.ReferencePath).ToList();
                        if (fileMissing.Count > 0)
                        {
                            fileMissing.Sort();
                            DebugWriteLine($"  {fileMissing.Count} files are missing from the output:");
                            fileMissing.ForEach(x => DebugWriteLine($"    {x}"));
                        }
                    }
                }
                break;

                case TestOptions.QuickConfigure:
                {
                    exitCode = AnalyzeConfigureOrder(parameters, true);
                }
                break;

                case TestOptions.Configure:
                {
                    exitCode = AnalyzeConfigureOrder(parameters, false);
                }
                break;

                case TestOptions.None:
                default:
                {
                    if (parameters.OutputDirectory != null)
                    {
                        // output redirect mode
                        var redirectOutput = new BuildContext.RedirectOutput(parameters.OutputDirectory, parameters.RemapRoot);
                        GenerateAll(redirectOutput, parameters);
                        exitCode = ExitCode.Success;
                    }
                    else
                    {
                        var generateAll = new BuildContext.GenerateAll(parameters.DebugLog, parameters.WriteFiles);
                        GenerateAll(generateAll, parameters);
                        exitCode = ExitCode.Success;

                        Util.ExecuteFilesAutoCleanup();
                    }
                }
                break;
                }

                if (CSproj.AllCsProjSubTypesInfos.Any())
                {
                    Util.SerializeAllCsprojSubTypes(CSproj.AllCsProjSubTypesInfos);
                }
            }
            catch (Error e)
            {
                // Log error message
                Exception innerException = e;
                while (innerException.InnerException != null)
                {
                    innerException = innerException.InnerException;
                }
                ErrorWriteLine(Environment.NewLine + "Error:" + Environment.NewLine + innerException.Message);

                // Then log details
                LogWriteLine(Util.GetCompleteExceptionMessage(e, "\t"));
                exitCode = ExitCode.Error;
            }
            catch (InternalError e)
            {
                ErrorWriteLine(Environment.NewLine + "Internal Error:");
                LogWriteLine(Util.GetCompleteExceptionMessage(e, "\t"));
                exitCode = ExitCode.InternalError;
            }
#if !DEBUG // Use this to catch right away if an exception throw
            catch (Exception e)
            {
                LogWriteLine(Environment.NewLine + "Exception Error:");
                LogWriteLine(Util.GetCompleteExceptionMessage(e, "\t"));
                exitCode = ExitCode.UnknownError;
            }
#endif
            finally
            {
                if (oneInstanceMutex != null)
                {
                    oneInstanceMutex.ReleaseMutex();
                    GC.KeepAlive(oneInstanceMutex);
                }

                if (parameters.Debug)
                {
                    Console.WriteLine("DEBUG Sharpmake.Application: Press any key to exit...");
                    Console.ReadKey();
                }
            }

            LogWriteLine(@"{0} errors, {1} warnings", s_errorCount, s_warningCount);
            if (s_errorCount != 0)
            {
                if (Debugger.IsAttached)
                {
                    LogWriteLine("Please look at the errors.");
                    Debugger.Break();
                }
            }

            // returning exit code and error count separately because they can result in an exit code of 0 if they are added together.
            if (s_errorCount != 0)
            {
                return(s_errorCount);
            }
            return((int)exitCode);
        }
Esempio n. 3
0
        public void Init()
        {
            bool debugLog       = true;
            bool multithreaded  = false;
            bool writeFiles     = false;
            bool dumpDependency = true;

            DependencyTracker.GraphWriteLegend = false;

            Builder = new Builder(
                new Sharpmake.BuildContext.GenerateAll(debugLog, writeFiles),
                multithreaded,
                dumpDependency,
                false,
                false,
                false,
                false,
                GetGeneratorsManager
                );

            // Force the test to load and register CommonPlatforms.dll as a Sharpmake extension
            // because sometimes you get the "no implementation of XX for platform YY."
            var platformDotNetType = typeof(DotNetPlatform);

            PlatformRegistry.RegisterExtensionAssembly(platformDotNetType.Assembly);

            Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);

            // Allow message log from builder.
            Builder.OutputDelegate log = (msg, args) =>
            {
                Console.Write(msg, args);
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Trace.Write(string.Format(msg, args));
                }
            };
            Builder.EventOutputError   += log;
            Builder.EventOutputWarning += log;
            Builder.EventOutputMessage += log;
            Builder.EventOutputDebug   += log;

            ////////////////////////////////////////////////////////////////////
            // Register projects to generate here
            var sharpmakeProjects = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && t.Namespace == _namespace);

            // Also create some random source files
            Util.FakePathPrefix = Directory.GetCurrentDirectory();
            foreach (var sharpmakeProject in sharpmakeProjects)
            {
                Util.AddNewFakeFile(Util.PathMakeStandard(Path.Combine(sharpmakeProject.Name, sharpmakeProject.Name + "_source.cs")), 0);
            }

            foreach (var sharpmakeProject in sharpmakeProjects)
            {
                Builder.Arguments.Generate(sharpmakeProject);
            }
            ////////////////////////////////////////////////////////////////////

            Builder.BuildProjectAndSolution();

            var outputs = Builder.Generate();

            if (dumpDependency)
            {
                DependencyTracker.Instance.DumpGraphs(outputs);
            }
        }