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; }
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); }
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); } }