public void TestMSBuildForwardPropertiesFromChild() { Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", null); Engine childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); string[] propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsNull(propertiesToSerialize, "Expected propertiesToSerialize to be null"); childEngine.Shutdown(); Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", string.Empty); childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsNull(propertiesToSerialize, "Expected propertiesToSerialize to be null"); childEngine.Shutdown(); Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform;Configuration"); childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0); Assert.IsTrue(string.Compare(propertiesToSerialize[1], "Configuration") == 0); Assert.IsTrue(propertiesToSerialize.Length == 2); childEngine.Shutdown(); Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform;;;;;;;;;;Configuration"); childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0); Assert.IsTrue(string.Compare(propertiesToSerialize[1], "Configuration") == 0); Assert.IsTrue(propertiesToSerialize.Length == 2); childEngine.Shutdown(); Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform;"); childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0); Assert.IsTrue(propertiesToSerialize.Length == 1); childEngine.Shutdown(); Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform"); childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0); Assert.IsTrue(propertiesToSerialize.Length == 1); childEngine.Shutdown(); Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", ";Platform"); childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0); Assert.IsTrue(propertiesToSerialize.Length == 1); childEngine.Shutdown(); Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", ";Platform;"); childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty); propertiesToSerialize = childEngine.PropertyListToSerialize; Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0); Assert.IsTrue(propertiesToSerialize.Length == 1); childEngine.Shutdown(); }
static void Main(string[] args) { // We need to tell MSBuild where msbuild.exe is, so it can launch child nodes string parameters = @"MSBUILDLOCATION=" + System.Environment.GetFolderPath(System.Environment.SpecialFolder.System) + @"\..\Microsoft.NET\Framework\v3.5"; // We need to tell MSBuild whether nodes should hang around for 60 seconds after the build is done in case they are needed again bool nodeReuse = true; // e.g. if (!nodeReuse) { parameters += ";NODEREUSE=false"; } // We need to tell MSBuild the maximum number of nodes to use. It is usually fastest to pick about the same number as you have CPU cores int maxNodeCount = 3; // e.g. // Create the engine with this information Engine buildEngine = new Engine(null, ToolsetDefinitionLocations.Registry | ToolsetDefinitionLocations.ConfigurationFile, maxNodeCount, parameters); // Create a file logger with a matching forwarding logger, e.g. FileLogger fileLogger = new FileLogger(); fileLogger.Verbosity = LoggerVerbosity.Detailed; Assembly engineAssembly = Assembly.GetAssembly(typeof(Engine)); string loggerAssemblyName = engineAssembly.GetName().FullName; LoggerDescription fileLoggerForwardingLoggerDescription = new LoggerDescription("Microsoft.Build.BuildEngine.ConfigurableForwardingLogger", loggerAssemblyName, null, String.Empty, LoggerVerbosity.Detailed); // Create a regular console logger too, e.g. ConsoleLogger logger = new ConsoleLogger(); logger.Verbosity = LoggerVerbosity.Normal; // Register all of these loggers buildEngine.RegisterDistributedLogger(fileLogger, fileLoggerForwardingLoggerDescription); buildEngine.RegisterLogger(logger); // Do a build buildEngine.BuildProjectFile("root.proj"); // Finish cleanly buildEngine.Shutdown(); }
private void NodeLocalEngineLoop() { buildInProgress = true; // Create a logging service for this build request localEngine = new Engine(parentGlobalProperties, toolsetSearchLocations, 1 /* cpus */, true /* child node */, this.nodeId, parentStartupDirectory, null); localEngine.Router.ChildMode = true; localEngine.Router.ParentNode = this; this.outProcLoggingService = new EngineLoggingServicesOutProc(this, localEngine.FlushRequestEvent); if (nodeLoggers.Length != 0) { foreach (LoggerDescription loggerDescription in nodeLoggers) { IForwardingLogger newLogger = null; bool exitedDueToError = true; try { newLogger = loggerDescription.CreateForwardingLogger(); // Check if the class was not found in the assembly if (newLogger == null) { InternalLoggerException.Throw(null, null, "FatalErrorWhileInitializingLogger", true, loggerDescription.Name); } newLogger.Verbosity = loggerDescription.Verbosity; newLogger.Parameters = loggerDescription.LoggerSwitchParameters; newLogger.NodeId = nodeId; EventRedirector newRedirector = new EventRedirector(loggerDescription.LoggerId, outProcLoggingService); newLogger.BuildEventRedirector = newRedirector; exitedDueToError = false; } // Polite logger failure catch (LoggerException e) { ReportUnhandledError(e); } // Logger class was not found catch (InternalLoggerException e) { ReportUnhandledError(e); } catch (Exception e) { // Wrap the exception in a InternalLoggerException and send it to the parent node string errorCode; string helpKeyword; string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "FatalErrorWhileInitializingLogger", loggerDescription.Name); ReportUnhandledError(new InternalLoggerException(message, e, null, errorCode, helpKeyword, true)); } // If there was a failure registering loggers, null out the engine pointer if (exitedDueToError) { localEngine = null; return; } localEngine.RegisterLogger(newLogger); } localEngine.ExternalLoggingServices = outProcLoggingService; } // Hook up logging service to forward all events to the central engine if necessary if (centralizedLogging) { if (nodeLoggers.Length != 0) { localEngine.LoggingServices.ForwardingService = outProcLoggingService; localEngine.ExternalLoggingServices = outProcLoggingService; } else { localEngine.LoggingServices = outProcLoggingService; } } localEngine.LoggingServices.OnlyLogCriticalEvents = this.logOnlyCriticalEvents; if (!useBreadthFirstTraversal) { localEngine.PostEngineCommand(new ChangeTraversalTypeCommand(useBreadthFirstTraversal, true)); } // Post all the requests that passed in while the engine was being constructed // into the engine queue lock (buildRequests) { while (buildRequests.Count != 0) { BuildRequest buildRequest = buildRequests.Dequeue(); localEngine.PostBuildRequest(buildRequest); } } try { // If there are forwarding loggers registered - generate a custom build started if (nodeLoggers.Length > 0) { localEngine.LoggingServices.LogBuildStarted(EngineLoggingServicesInProc.CENTRAL_ENGINE_EVENTSOURCE); localEngine.LoggingServices.ProcessPostedLoggingEvents(); } // Trigger the actual build if shutdown was not called while the engine was being initialized if (!nodeShutdown) { localEngine.EngineBuildLoop(null); } } catch (Exception e) { // Unhandled exception during execution. The node has to be shutdown. ReportUnhandledError(e); } finally { if (localEngine != null) { // Flush all the messages associated before shutting down localEngine.LoggingServices.ProcessPostedLoggingEvents(); NodeManager nodeManager = localEngine.NodeManager; // If the local engine is already shutting down, the TEM will be nulled out if (nodeManager.TaskExecutionModule != null && nodeManager.TaskExecutionModule.TaskExecutionTime != 0) { TimeSpan taskTimeSpan = new TimeSpan(localEngine.NodeManager.TaskExecutionModule.TaskExecutionTime); totalTaskTime = (int)taskTimeSpan.TotalMilliseconds; } localEngine.Shutdown(); } // Flush all the events to the parent engine outProcLoggingService.ProcessPostedLoggingEvents(); // Indicate that the node logger thread should exit exitNodeEvent.Set(); } }
public void BuildProjectFilesInParallel2() { string[] fileNames = new string[10]; string[] fileNames2 = new string[10]; string[] fileNamesLeafs = new string[10]; string[] childTraversals = new string[10]; string parentTraversal = TraversalProjectFile("CTrav"); string traversalProject = TraversalProjectFile("ABC"); string[][] targetNamesPerProject = new string[fileNames.Length][]; IDictionary[] targetOutPutsPerProject = new IDictionary[fileNames.Length]; BuildPropertyGroup[] globalPropertiesPerProject = new BuildPropertyGroup[fileNames.Length]; string[] tempfilesToDelete = new string[fileNames.Length]; string[] tempfilesToDelete2 = new string[fileNames.Length]; string[] tempfilesToDelete3 = new string[fileNames.Length]; string[] tempfilesToDelete4 = new string[fileNames.Length]; Engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); try { for (int i = 0; i < fileNames.Length; i++) { string[] ProjectFiles1 = CreateGlobalPropertyProjectFileWithExtension("ABC"); string[] ProjectFiles2 = CreateGlobalPropertyProjectFileWithExtension("DEF"); string[] FileNamesLeafs = CreateGlobalPropertyProjectFileWithExtension("LEAF"); string[] ChildTraversals = CreateSingleProjectTraversalFileWithExtension(FileNamesLeafs[0],"CTrav"); fileNames[i] = ProjectFiles1[0]; fileNames2[i] = ProjectFiles2[0]; fileNamesLeafs[i] = FileNamesLeafs[0]; childTraversals[i] = ChildTraversals[0]; tempfilesToDelete[i] = ProjectFiles1[1]; tempfilesToDelete2[i] = ProjectFiles2[1]; tempfilesToDelete3[i] = FileNamesLeafs[1]; tempfilesToDelete4[i] = ChildTraversals[1]; targetNamesPerProject[i] = new string[] { "Build" }; } // Try building a traversal project that had other traversals engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFile(parentTraversal, new string[] { "Build" }, new BuildPropertyGroup(), null, BuildSettings.None, "3.5"); engine.Shutdown(); engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); // Try building the same traversal project on the same engine one after another engine.BuildProjectFile(traversalProject); engine.BuildProjectFile(traversalProject); engine.Shutdown(); // Try building the same set of project files on the same engine one after another engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.Shutdown(); // Try building a set of project files, then the same set as a traversal on the same engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.BuildProjectFile(traversalProject); engine.Shutdown(); // Try building a traversal, then the same files which are in the traversal in parallel on the same engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFile(traversalProject); engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.Shutdown(); /* Do the same as above using single proc */ // Try building the same traversal project on the same engine one after another engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFile(traversalProject); engine.BuildProjectFile(traversalProject); engine.Shutdown(); // Try building the same set of project files on the same engine one after another engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.Shutdown(); // Try building a set of project files, then the same set as a traversal on the same engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.BuildProjectFile(traversalProject); engine.Shutdown(); // Try building a traversal, then the same files which are in the traversal in parallel on the same engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFile(traversalProject); engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); } finally { engine.Shutdown(); for (int i = 0; i < fileNames.Length; i++) { File.Delete(fileNames[i]); File.Delete(fileNames2[i]); File.Delete(fileNamesLeafs[i]); File.Delete(childTraversals[i]); File.Delete(tempfilesToDelete[i]); File.Delete(tempfilesToDelete2[i]); File.Delete(tempfilesToDelete3[i]); File.Delete(tempfilesToDelete4[i]); } File.Delete(traversalProject); } }
public void BuildProjectFilesInParallel() { //Gets the currently loaded assembly in which the specified class is defined Assembly engineAssembly = Assembly.GetAssembly(typeof(Engine)); string loggerClassName = "Microsoft.Build.BuildEngine.ConfigurableForwardingLogger"; string loggerAssemblyName = engineAssembly.GetName().FullName; LoggerDescription forwardingLoggerDescription = new LoggerDescription(loggerClassName, loggerAssemblyName, null, null, LoggerVerbosity.Normal); string[] fileNames = new string[10]; string traversalProject = TraversalProjectFile("ABC"); string[][] targetNamesPerProject = new string[fileNames.Length][]; IDictionary[] targetOutPutsPerProject = new IDictionary[fileNames.Length]; BuildPropertyGroup[] globalPropertiesPerProject = new BuildPropertyGroup[fileNames.Length]; string[] tempfilesToDelete = new string[fileNames.Length]; Engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); try { for (int i = 0; i < fileNames.Length; i++) { string[] ProjectFiles1 = CreateGlobalPropertyProjectFileWithExtension("ABC"); fileNames[i] = ProjectFiles1[0]; tempfilesToDelete[i] = ProjectFiles1[1]; targetNamesPerProject[i] = new string[] { "Build" }; } // Test building a traversal engine.BuildProjectFile(traversalProject); engine.Shutdown(); // Test building the same set of files in parallel Console.Out.WriteLine("1:"+Process.GetCurrentProcess().MainModule.FileName); Console.Out.WriteLine("2:" + AppDomain.CurrentDomain.BaseDirectory); engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterDistributedLogger(new ConsoleLogger(LoggerVerbosity.Normal), forwardingLoggerDescription); engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); engine.Shutdown(); // Do the same using singleproc engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFile(traversalProject); engine.Shutdown(); engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory); engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal)); engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]); } finally { engine.Shutdown(); for (int i = 0; i < fileNames.Length; i++) { File.Delete(fileNames[i]); File.Delete(tempfilesToDelete[i]); } File.Delete(traversalProject); } }