private bool TryAddMsBuildArguments(ProjectWithPredictions project, PipDataBuilder pipDataBuilder, AbsolutePath logDirectory, AbsolutePath outputResultCacheFile, out string failureDetail) { // Common arguments to all MsBuildExe invocations pipDataBuilder.AddRange(s_commonArgumentsToMsBuildExe.Select(argument => PipDataAtom.FromString(argument))); // Log verbosity if (!TryGetLogVerbosity(m_resolverSettings.LogVerbosity, out string logVerbosity)) { failureDetail = $"Cannot set the MSBuild log verbosity. '{m_resolverSettings.LogVerbosity}' is not a valid option."; return(false); } AddLogArgument(pipDataBuilder, 1, logDirectory.Combine(PathTable, "msbuild.log"), $"Verbosity={logVerbosity}"); AddLogArgument(pipDataBuilder, 2, logDirectory.Combine(PathTable, "msbuild.wrn"), "Verbosity=Quiet;warningsonly"); AddLogArgument(pipDataBuilder, 3, logDirectory.Combine(PathTable, "msbuild.err"), "Verbosity=Quiet;errorsonly"); AddLogArgument(pipDataBuilder, 4, logDirectory.Combine(PathTable, "msbuild.prf"), "PerformanceSummary"); // Global properties on the project are turned into build parameters foreach (var kvp in project.GlobalProperties) { AddMsBuildProperty(pipDataBuilder, kvp.Key, kvp.Value); } // Configure binary logger if specified if (m_resolverSettings.EnableBinLogTracing == true) { using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, string.Empty)) { pipDataBuilder.Add(PipDataAtom.FromString("/binaryLogger:")); pipDataBuilder.Add(PipDataAtom.FromAbsolutePath(logDirectory.Combine(PathTable, "msbuild.binlog"))); } } // Targets to execute. // If the prediction is available, there should be at least one target (otherwise it makes no sense to schedule the project, and we should have caught this earlier) // If the prediction is not available, we fallback to call default targets (which means not passing any specific /t:). A more strict policy would be to bail out // here saying that the project is not complying to the target protocol specification. We leave it relaxed for now, but we log it. // https://github.com/Microsoft/msbuild/blob/master/documentation/specs/static-graph.md if (project.PredictedTargetsToExecute.IsPredictionAvailable) { var targets = project.PredictedTargetsToExecute.Targets; Contract.Assert(targets.Count > 0); foreach (string target in targets) { pipDataBuilder.Add(PipDataAtom.FromString($"/t:{target}")); } } else { // The prediction for the targets to execute is not available. Just log this as a warning for now, defaults targets will be used. Tracing.Logger.Log.ProjectIsNotSpecifyingTheProjectReferenceProtocol( m_context.LoggingContext, Location.FromFile(project.FullPath.ToString(PathTable)), project.FullPath.GetName(m_context.PathTable).ToString(m_context.StringTable)); } // Pass the output result cache file if present if (outputResultCacheFile != AbsolutePath.Invalid) { using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, string.Empty)) { // Flag /orc is the short form of /outputResultsCache, and part of MSBuild 'build in isolation' mode. // By specifying this flag, MSBuild will write the build result at the end of this invocation into the cache file pipDataBuilder.Add(PipDataAtom.FromString("/orc:")); pipDataBuilder.Add(PipDataAtom.FromAbsolutePath(outputResultCacheFile)); } } else { // In legacy (non-isolated) mode, we still have to rely on SDKs honoring this flag pipDataBuilder.Add(PipDataAtom.FromString("/p:buildprojectreferences=false")); } failureDetail = string.Empty; return(true); }
private bool TryAddMsBuildArguments(ProjectWithPredictions project, PipDataBuilder pipDataBuilder, AbsolutePath logDirectory, AbsolutePath outputResultCacheFile, out string failureDetail) { // Common arguments to all MsBuildExe invocations pipDataBuilder.AddRange(s_commonArgumentsToMsBuildExe.Select(argument => PipDataAtom.FromString(argument))); // Log verbosity if (!TryGetLogVerbosity(m_resolverSettings.LogVerbosity, out string logVerbosity)) { failureDetail = $"Cannot set the MSBuild log verbosity. '{m_resolverSettings.LogVerbosity}' is not a valid option."; return(false); } AddLogArgument(pipDataBuilder, 1, logDirectory.Combine(PathTable, "msbuild.log"), $"Verbosity={logVerbosity}"); AddLogArgument(pipDataBuilder, 2, logDirectory.Combine(PathTable, "msbuild.wrn"), "Verbosity=Quiet;warningsonly"); AddLogArgument(pipDataBuilder, 3, logDirectory.Combine(PathTable, "msbuild.err"), "Verbosity=Quiet;errorsonly"); AddLogArgument(pipDataBuilder, 4, logDirectory.Combine(PathTable, "msbuild.prf"), "PerformanceSummary"); // Global properties on the project are turned into build parameters foreach (var kvp in project.GlobalProperties) { AddMsBuildProperty(pipDataBuilder, kvp.Key, kvp.Value); } // Configure binary logger if specified if (m_resolverSettings.EnableBinLogTracing == true) { using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, string.Empty)) { pipDataBuilder.Add(PipDataAtom.FromString("/binaryLogger:")); pipDataBuilder.Add(PipDataAtom.FromAbsolutePath(logDirectory.Combine(PathTable, "msbuild.binlog"))); } } // Targets to execute. var targets = project.PredictedTargetsToExecute.Targets; Contract.Assert(targets.Count > 0); foreach (string target in targets) { pipDataBuilder.Add(PipDataAtom.FromString($"/t:{target}")); } // Pass the output result cache file if present if (outputResultCacheFile != AbsolutePath.Invalid) { using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, string.Empty)) { // Flag /orc is the short form of /outputResultsCache, and part of MSBuild 'build in isolation' mode. // By specifying this flag, MSBuild will write the build result at the end of this invocation into the cache file pipDataBuilder.Add(PipDataAtom.FromString("/orc:")); pipDataBuilder.Add(PipDataAtom.FromAbsolutePath(outputResultCacheFile)); } } else { // In legacy (non-isolated) mode, we still have to rely on SDKs honoring this flag pipDataBuilder.Add(PipDataAtom.FromString("/p:buildprojectreferences=false")); } failureDetail = string.Empty; return(true); }
private bool TryAddMsBuildArguments(ProjectWithPredictions <AbsolutePath> project, Qualifier qualifier, PipDataBuilder pipDataBuilder, AbsolutePath logDirectory, out string failureDetail) { // Common arguments to all MsBuildExe invocations pipDataBuilder.AddRange(s_commonArgumentsToMsBuildExe.Select(argument => PipDataAtom.FromString(argument))); // Log verbosity if (!TryGetLogVerbosity(m_resolverSettings.LogVerbosity, out string logVerbosity)) { failureDetail = $"Cannot set the MSBuild log verbosity. '{m_resolverSettings.LogVerbosity}' is not a valid option."; return(false); } AddLogArgument(pipDataBuilder, 1, logDirectory.Combine(PathTable, "msbuild.log"), $"Verbosity={logVerbosity}"); AddLogArgument(pipDataBuilder, 2, logDirectory.Combine(PathTable, "msbuild.wrn"), "Verbosity=Quiet;warningsonly"); AddLogArgument(pipDataBuilder, 3, logDirectory.Combine(PathTable, "msbuild.err"), "Verbosity=Quiet;errorsonly"); AddLogArgument(pipDataBuilder, 4, logDirectory.Combine(PathTable, "msbuild.prf"), "PerformanceSummary"); // Global properties on the project are turned into build parameters foreach (var kvp in project.GlobalProperties) { AddMsBuildProperty(pipDataBuilder, kvp.Key, kvp.Value); } // The specified qualifier, unless overridden by a global property, is turned into a property as well // This means that: // 1) if the project is not being referenced with a specific property that matters to the qualifier, the requested qualifier is used // 2) if a particular property (e.g. platform) is set when referencing the project, that is honored foreach (StringId key in qualifier.Keys) { string keyAsString = key.ToString(m_context.StringTable); if (!project.GlobalProperties.ContainsKey(keyAsString)) { var success = qualifier.TryGetValue(m_context.StringTable, keyAsString, out string value); Contract.Assert(success); AddMsBuildProperty(pipDataBuilder, keyAsString, value); } } // Configure binary logger if specified if (m_resolverSettings?.EnableBinLogTracing == true) { using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, string.Empty)) { pipDataBuilder.Add(PipDataAtom.FromString("/binaryLogger:")); pipDataBuilder.Add(PipDataAtom.FromAbsolutePath(logDirectory.Combine(PathTable, "msbuild.binlog"))); } } // Targets to execute. // If the prediction is available, there should be at least one target (otherwise it makes no sense to schedule the project, and we should have caught this earlier) // If the prediction is not available, we fallback to call default targets (which means not passing any specific /t:). A more strict policy would be to bail out // here saying that the project is not complying to the target protocol specification. We leave it relaxed for now, but we log it. // https://github.com/Microsoft/msbuild/blob/master/documentation/specs/static-graph.md if (project.PredictedTargetsToExecute.IsPredictionAvailable) { var targets = project.PredictedTargetsToExecute.Targets; Contract.Assert(targets.Count > 0); foreach (string target in targets) { pipDataBuilder.Add(PipDataAtom.FromString($"/t:{target}")); } } else { // The prediction for the targets to execute is not available. Just log this as a warning for now, defaults targets will be used. Tracing.Logger.Log.ProjectIsNotSpecifyingTheProjectReferenceProtocol( m_context.LoggingContext, Location.FromFile(project.FullPath.ToString(PathTable)), project.FullPath.GetName(m_context.PathTable).ToString(m_context.StringTable)); } failureDetail = string.Empty; return(true); }