public async Task Basic_ProjectTemplateCanBuild() { nuproj.CreateMockContentFiles(); var result = await MSBuild.ExecuteAsync(nuproj.CreateProjectInstance()); result.AssertSuccessfulBuild(); }
private async Task <MSB.Execution.ProjectInstance> BuildProjectAsync( MSB.Evaluation.Project project, string[] targets, DiagnosticLog log, CancellationToken cancellationToken) { // create a project instance to be executed by build engine. // The executed project will hold the final model of the project after execution via msbuild. var projectInstance = project.CreateProjectInstance(); // Verify targets foreach (var target in targets) { if (!projectInstance.Targets.ContainsKey(target)) { log.Add(string.Format(WorkspaceMSBuildResources.Project_does_not_contain_0_target, target), projectInstance.FullPath); return(projectInstance); } } _batchBuildLogger?.SetProjectAndLog(projectInstance.FullPath, log); var buildRequestData = new MSB.Execution.BuildRequestData(projectInstance, targets); var result = await BuildAsync(buildRequestData, cancellationToken).ConfigureAwait(false); if (result.OverallResult == MSB.Execution.BuildResultCode.Failure) { if (result.Exception != null) { log.Add(result.Exception, projectInstance.FullPath); } } return(projectInstance); }
protected async Task <BuildInfo> BuildAsync(string taskName, MSB.Framework.ITaskHost taskHost, CancellationToken cancellationToken) { // create a project instance to be executed by build engine. // The executed project will hold the final model of the project after execution via msbuild. var executedProject = _loadedProject.CreateProjectInstance(); if (!executedProject.Targets.ContainsKey("Compile")) { return(new BuildInfo(executedProject, null)); } var hostServices = new Microsoft.Build.Execution.HostServices(); // connect the host "callback" object with the host services, so we get called back with the exact inputs to the compiler task. hostServices.RegisterHostObject(_loadedProject.FullPath, "CoreCompile", taskName, taskHost); var buildParameters = new MSB.Execution.BuildParameters(_loadedProject.ProjectCollection); var buildRequestData = new MSB.Execution.BuildRequestData(executedProject, new string[] { "Compile" }, hostServices); BuildResult result = await this.BuildAsync(buildParameters, buildRequestData, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (result.OverallResult == BuildResultCode.Failure) { return(new BuildInfo(executedProject, result.Exception?.Message ?? "")); } else { return(new BuildInfo(executedProject, null)); } }
protected async Task <BuildResult> BuildAsync(string taskName, MSB.Framework.ITaskHost taskHost, CancellationToken cancellationToken) { // prepare for building var buildTargets = new BuildTargets(loadedProject, "Compile"); // Don't execute this one. It will build referenced projects. // Even when DesignTimeBuild is defined above, it will still add the referenced project's output to the references list // which we don't want. buildTargets.Remove("ResolveProjectReferences"); // don't execute anything after CoreCompile target, since we've // already done everything we need to compute compiler inputs by then. buildTargets.RemoveAfter("CoreCompile", includeTargetInRemoval: false); // create a project instance to be executed by build engine. // The executed project will hold the final model of the project after execution via msbuild. var executedProject = loadedProject.CreateProjectInstance(); var hostServices = new Microsoft.Build.Execution.HostServices(); // connect the host "callback" object with the host services, so we get called back with the exact inputs to the compiler task. hostServices.RegisterHostObject(this.loadedProject.FullPath, "CoreCompile", taskName, taskHost); var buildParameters = new MSB.Execution.BuildParameters(loadedProject.ProjectCollection); var buildRequestData = new MSB.Execution.BuildRequestData(executedProject, buildTargets.Targets, hostServices); var result = await this.BuildAsync(buildParameters, buildRequestData, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); return(new BuildResult(result, executedProject)); }
IEnumerable <string> ResolveAssemblyReferences(Microsoft.Build.Evaluation.Project project) { // Use MSBuild to figure out the full path of the referenced assemblies var projectInstance = project.CreateProjectInstance(); projectInstance.SetProperty("BuildingProject", "false"); project.SetProperty("DesignTimeBuild", "true"); projectInstance.Build("ResolveAssemblyReferences", new [] { new ConsoleLogger(LoggerVerbosity.Minimal) }); var items = projectInstance.GetItems("_ResolveAssemblyReferenceResolvedFiles"); string baseDirectory = Path.GetDirectoryName(this.FileName); return(items.Select(i => Path.Combine(baseDirectory, i.GetMetadataValue("Identity")))); }
protected async Task <BuildInfo> BuildAsync(string taskName, MSB.Framework.ITaskHost taskHost, CancellationToken cancellationToken) { // create a project instance to be executed by build engine. // The executed project will hold the final model of the project after execution via msbuild. var executedProject = _loadedProject.CreateProjectInstance(); if (!executedProject.Targets.ContainsKey("Compile")) { return(new BuildInfo(executedProject, null)); } var hostServices = new MSB.Execution.HostServices(); // connect the host "callback" object with the host services, so we get called back with the exact inputs to the compiler task. hostServices.RegisterHostObject(_loadedProject.FullPath, "CoreCompile", taskName, taskHost); var buildParameters = new MSB.Execution.BuildParameters(_loadedProject.ProjectCollection); // capture errors that are output in the build log var errorBuilder = new StringWriter(); var errorLogger = new ErrorLogger(errorBuilder) { Verbosity = MSB.Framework.LoggerVerbosity.Normal }; buildParameters.Loggers = new MSB.Framework.ILogger[] { errorLogger }; var buildRequestData = new MSB.Execution.BuildRequestData(executedProject, new string[] { "Compile" }, hostServices); var result = await this.BuildAsync(buildParameters, buildRequestData, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (result.OverallResult == MSB.Execution.BuildResultCode.Failure) { if (result.Exception != null) { return(new BuildInfo(executedProject, result.Exception.Message)); } else { return(new BuildInfo(executedProject, errorBuilder.ToString())); } } else { return(new BuildInfo(executedProject, null)); } }
IEnumerable <string> ResolveAssemblyReferences(Microsoft.Build.Evaluation.Project project) { // Use MSBuild to figure out the full path of the referenced assemblies var projectInstance = project.CreateProjectInstance(); projectInstance.SetProperty("BuildingProject", "false"); project.SetProperty("DesignTimeBuild", "true"); projectInstance.Build("ResolveAssemblyReferences", new [] { new ConsoleLogger(LoggerVerbosity.Minimal) }); var items = projectInstance.GetItems("_ResolveAssemblyReferenceResolvedFiles"); string baseDirectory = Path.GetDirectoryName(this.FileName); var result = items.Select(i => Path.Combine(baseDirectory, i.GetMetadataValue("Identity"))).ToList(); if (!result.Any(t => t.Contains("mscorlib") || t.Contains("System.Runtime"))) { result.Add(typeof(object).Assembly.Location); } return(result); }
protected async Task <ProjectInstance> BuildAsync(string taskName, MSB.Framework.ITaskHost taskHost, CancellationToken cancellationToken) { // prepare for building var buildTargets = new BuildTargets(_loadedProject, "Compile"); // don't execute anything after CoreCompile target, since we've // already done everything we need to compute compiler inputs by then. buildTargets.RemoveAfter("CoreCompile", includeTargetInRemoval: false); // create a project instance to be executed by build engine. // The executed project will hold the final model of the project after execution via msbuild. var executedProject = _loadedProject.CreateProjectInstance(); if (!executedProject.Targets.ContainsKey("Compile")) { return(executedProject); } var hostServices = new Microsoft.Build.Execution.HostServices(); // connect the host "callback" object with the host services, so we get called back with the exact inputs to the compiler task. hostServices.RegisterHostObject(_loadedProject.FullPath, "CoreCompile", taskName, taskHost); var buildParameters = new MSB.Execution.BuildParameters(_loadedProject.ProjectCollection); var buildRequestData = new MSB.Execution.BuildRequestData(executedProject, buildTargets.Targets, hostServices); var result = await this.BuildAsync(buildParameters, buildRequestData, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (result.Exception != null) { throw result.Exception; } return(executedProject); }
public static ProjectDetails LoadProjectDetails(BuildEnvironment environment) { var key = Tuple.Create(environment.ProjectFile, environment.Configuration); ProjectDetails details; if (_allProjects.TryGetValue(key, out details)) { if (!details.HasChanged()) { if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { _log.LogDebug($"Using cached project file details for [{environment.ProjectFile}]"); } return(details); } else { if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { _log.LogDebug($"Reloading project file details [{environment.ProjectFile}] as one of its imports has been modified."); } } } if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { _log.LogDebug($"Loading project file [{environment.ProjectFile}]"); } details = new ProjectDetails(); var properties = new Dictionary <string, string>(ImmutableDictionary <string, string> .Empty) { ["DesignTimeBuild"] = "true", // this will tell msbuild to not build the dependent projects ["BuildingInsideVisualStudio"] = "true", // this will force CoreCompile task to execute even if all inputs and outputs are up to date ["BuildingInsideUnoSourceGenerator"] = "true", // this will force prevent the task to run recursively ["Configuration"] = environment.Configuration, ["UseHostCompilerIfAvailable"] = "true", ["UseSharedCompilation"] = "true", ["VisualStudioVersion"] = environment.VisualStudioVersion, // Force the intermediate path to be different from the VS default path // so that the generated files don't mess up the file count for incremental builds. ["IntermediateOutputPath"] = Path.Combine(environment.OutputPath, "obj") + Path.DirectorySeparatorChar }; // Target framework is required for the MSBuild 15.0 Cross Compilation. // Loading a project without the target framework results in an empty project, which interatively // sets the TargetFramework property. if (environment.TargetFramework.HasValue()) { properties["TargetFramework"] = environment.TargetFramework; } // TargetFrameworkRootPath is used by VS4Mac to determine the // location of frameworks like Xamarin.iOS. if (environment.TargetFrameworkRootPath.HasValue()) { properties["TargetFrameworkRootPath"] = environment.TargetFrameworkRootPath; } // Platform is intentionally kept as not defined, to avoid having // dependent projects being loaded with a platform they don't support. // properties["Platform"] = _platform; var xmlReader = XmlReader.Create(environment.ProjectFile); var collection = new Microsoft.Build.Evaluation.ProjectCollection(); // Change this logger details to troubleshoot project loading details. collection.RegisterLogger(new Microsoft.Build.Logging.ConsoleLogger() { Verbosity = LoggerVerbosity.Minimal }); // Uncomment this to enable file logging for debugging purposes. // collection.RegisterLogger(new Microsoft.Build.BuildEngine.FileLogger() { Verbosity = LoggerVerbosity.Diagnostic, Parameters = $@"logfile=c:\temp\build\MSBuild.{Guid.NewGuid()}.log" }); collection.OnlyLogCriticalEvents = false; var xml = Microsoft.Build.Construction.ProjectRootElement.Create(xmlReader, collection); // When constructing a project from an XmlReader, MSBuild cannot determine the project file path. Setting the // path explicitly is necessary so that the reserved properties like $(MSBuildProjectDirectory) will work. xml.FullPath = Path.GetFullPath(environment.ProjectFile); var loadedProject = new Microsoft.Build.Evaluation.Project( xml, properties, toolsVersion: null, projectCollection: collection ); var buildTargets = new BuildTargets(loadedProject, "Compile"); // don't execute anything after CoreCompile target, since we've // already done everything we need to compute compiler inputs by then. buildTargets.RemoveAfter("CoreCompile", includeTargetInRemoval: true); details.Configuration = environment.Configuration; details.LoadedProject = loadedProject; // create a project instance to be executed by build engine. // The executed project will hold the final model of the project after execution via msbuild. details.ExecutedProject = loadedProject.CreateProjectInstance(); var hostServices = new Microsoft.Build.Execution.HostServices(); // connect the host "callback" object with the host services, so we get called back with the exact inputs to the compiler task. hostServices.RegisterHostObject(loadedProject.FullPath, "CoreCompile", "Csc", null); var buildParameters = new Microsoft.Build.Execution.BuildParameters(loadedProject.ProjectCollection); // This allows for the loggers to buildParameters.Loggers = collection.Loggers; var buildRequestData = new Microsoft.Build.Execution.BuildRequestData(details.ExecutedProject, buildTargets.Targets, hostServices); var result = BuildAsync(buildParameters, buildRequestData); if (result.Exception == null) { ValidateOutputPath(details.ExecutedProject); var projectFilePath = Path.GetFullPath(Path.GetDirectoryName(environment.ProjectFile)); details.References = details.ExecutedProject.GetItems("ReferencePath").Select(r => r.EvaluatedInclude).ToArray(); if (!details.References.Any()) { if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error)) { _log.LogError($"Project has no references."); } LogFailedTargets(environment.ProjectFile, result); details.Generators = new (Type, Func <SourceGenerator>)[0];
public static ProjectDetails LoadProjectDetails(string projectFile, string configuration) { var key = Tuple.Create(projectFile, configuration); ProjectDetails details; if (_allProjects.TryGetValue(key, out details)) { if (!details.HasChanged()) { if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { _log.Debug($"Using cached project file details for [{projectFile}]"); } return(details); } else { if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { _log.Debug($"Reloading project file details [{projectFile}] as one of its imports has been modified."); } } } if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { _log.Debug($"Loading project file [{projectFile}]"); } details = new ProjectDetails(); var properties = new Dictionary <string, string>(ImmutableDictionary <string, string> .Empty); properties["DesignTimeBuild"] = "true"; // this will tell msbuild to not build the dependent projects properties["BuildingInsideVisualStudio"] = "true"; // this will force CoreCompile task to execute even if all inputs and outputs are up to date properties["BuildingInsideUnoSourceGenerator"] = "true"; // this will force prevent the task to run recursively properties["Configuration"] = configuration; properties["UseHostCompilerIfAvailable"] = "true"; properties["UseSharedCompilation"] = "true"; // Platform is intentionally kept as not defined, to avoid having // dependent projects being loaded with a platform they don't support. // properties["Platform"] = _platform; var xmlReader = XmlReader.Create(projectFile); var collection = new Microsoft.Build.Evaluation.ProjectCollection(); collection.RegisterLogger(new Microsoft.Build.Logging.ConsoleLogger() { Verbosity = LoggerVerbosity.Normal }); collection.OnlyLogCriticalEvents = false; var xml = Microsoft.Build.Construction.ProjectRootElement.Create(xmlReader, collection); // When constructing a project from an XmlReader, MSBuild cannot determine the project file path. Setting the // path explicitly is necessary so that the reserved properties like $(MSBuildProjectDirectory) will work. xml.FullPath = Path.GetFullPath(projectFile); var loadedProject = new Microsoft.Build.Evaluation.Project( xml, properties, toolsVersion: null, projectCollection: collection ); var buildTargets = new BuildTargets(loadedProject, "Compile"); // don't execute anything after CoreCompile target, since we've // already done everything we need to compute compiler inputs by then. buildTargets.RemoveAfter("CoreCompile", includeTargetInRemoval: false); details.Configuration = configuration; details.LoadedProject = loadedProject; // create a project instance to be executed by build engine. // The executed project will hold the final model of the project after execution via msbuild. details.ExecutedProject = loadedProject.CreateProjectInstance(); var hostServices = new Microsoft.Build.Execution.HostServices(); // connect the host "callback" object with the host services, so we get called back with the exact inputs to the compiler task. hostServices.RegisterHostObject(loadedProject.FullPath, "CoreCompile", "Csc", null); var buildParameters = new Microsoft.Build.Execution.BuildParameters(loadedProject.ProjectCollection); // This allows for the loggers to buildParameters.Loggers = collection.Loggers; var buildRequestData = new Microsoft.Build.Execution.BuildRequestData(details.ExecutedProject, buildTargets.Targets, hostServices); var result = BuildAsync(buildParameters, buildRequestData); if (result.Exception == null) { ValidateOutputPath(details.ExecutedProject); var projectFilePath = Path.GetFullPath(Path.GetDirectoryName(projectFile)); details.References = details.ExecutedProject.GetItems("ReferencePath").Select(r => r.EvaluatedInclude).ToArray(); if (details.References.None()) { LogFailedTargets(projectFile, result); return(details); } } else { LogFailedTargets(projectFile, result); } _allProjects.TryAdd(key, details); details.BuildImportsMap(); return(details); }