public void ExecutionProcessReadingStdIn() { FileArtifact stdOut = CreateOutputFileArtifact(); ProcessBuilder builder = CreatePipBuilder(new[] { Operation.ReadStdIn() }); PipDataBuilder dataBuilder = new PipDataBuilder(Context.PathTable.StringTable); dataBuilder.Add("Data0"); dataBuilder.Add("Data1"); dataBuilder.Add("Data2"); builder.StandardInput = global::BuildXL.Pips.StandardInput.CreateFromData(dataBuilder.ToPipData(Environment.NewLine, PipDataFragmentEscaping.NoEscaping)); builder.SetStandardOutputFile(stdOut.Path); builder.Options |= Process.Options.RequiresAdmin; ProcessWithOutputs process = SchedulePipBuilder(builder); RunScheduler().AssertSuccess(); string[] output = File.ReadAllLines(ArtifactToString(stdOut)); string actualContent = string.Join(Environment.NewLine, output); XAssert.AreEqual(3, output.Length, "Actual content: {0}{1}", Environment.NewLine, string.Join(Environment.NewLine, output)); for (int i = 0; i < 3; ++i) { XAssert.AreEqual("Data" + i, output[i], "Actual content: {0}", output[i]); } }
public PipDataTests(ITestOutputHelper output) : base(output) { m_pathTable = new PathTable(); m_expectedStringId0 = StringId.Create(m_pathTable.StringTable, ExpectedString0); m_pipDataBuilder = new PipDataBuilder(m_pathTable.StringTable); m_expectedStringId0 = StringId.Create(m_pathTable.StringTable, ExpectedString0); m_uniqueEntry0 = AbsolutePath.Create(m_pathTable, A("c", "unique to fragment 0")); // BEGIN ADDING ARGUMENTS m_cursorStart = m_pipDataBuilder.CreateCursor(); AddStandardBlock(m_pipDataBuilder); m_cursor0 = m_pipDataBuilder.CreateCursor(); using (m_pipDataBuilder.StartFragment(Escaping0, m_separator0)) { m_pipDataBuilder.Add(m_uniqueEntry0); AddStandardBlock(m_pipDataBuilder); } m_cursor1 = m_pipDataBuilder.CreateCursor(); using (m_pipDataBuilder.StartFragment(Escaping1, Separator1)) { AddStandardBlock(m_pipDataBuilder); m_pipDataBuilder.Add(UniqueEntry1); } m_cursorEnd = m_pipDataBuilder.CreateCursor(); // END ADDING ARGUMENTS }
private void SetProcessEnvironmentVariables(IReadOnlyDictionary <string, string> environment, ProcessBuilder processBuilder) { foreach (KeyValuePair <string, string> kvp in environment) { if (kvp.Value != null) { var envPipData = new PipDataBuilder(m_context.StringTable); // Casing for paths is not stable as reported by BuildPrediction. So here we try to guess if the value // represents a path, and normalize it string value = kvp.Value; if (!string.IsNullOrEmpty(value) && AbsolutePath.TryCreate(PathTable, value, out var absolutePath)) { envPipData.Add(absolutePath); } else { envPipData.Add(value); } processBuilder.SetEnvironmentVariable( StringId.Create(m_context.StringTable, kvp.Key), envPipData.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping)); } } if (m_userDefinedPassthroughVariables != null) { foreach (string passThroughVariable in m_userDefinedPassthroughVariables) { processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(m_context.StringTable, passThroughVariable)); } } }
/// <summary> /// Creates an instance of <see cref="ArgumentsDataBuilder"/> /// </summary> public ArgumentsDataBuilder(PipDataBuilder builder) { Contract.Requires(builder != null); m_builder = builder; m_finished = false; }
private PipProvenance CreatePipProvenance(string description) { var usage = string.IsNullOrEmpty(description) ? PipData.Invalid : PipDataBuilder.CreatePipData(Context.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping, description); return(CreatePipProvenance(usage)); }
/// <summary> /// Creates arguments. /// </summary> protected PipData CreateArguments( IEnumerable <Operation> processOperations, StringTable stringTable) { var pipDataBuilder = new PipDataBuilder(stringTable); CreateArguments(pipDataBuilder, processOperations, stringTable); return(pipDataBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules)); }
/// <nodoc /> public void SetEnvironmentVariable(StringId key, PipDataAtom value) { Contract.Requires(key.IsValid); Contract.Requires(value.IsValid); var pipData = PipDataBuilder.CreatePipData(m_pathTable.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping, value); SetEnvironmentVariable(key, pipData); }
private static void AddLogArgument(PipDataBuilder pipDataBuilder, int loggerNumber, AbsolutePath logFile, string verbosity) { using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, string.Empty)) { pipDataBuilder.Add(PipDataAtom.FromString(I($"/flp{loggerNumber}:logfile="))); pipDataBuilder.Add((PipDataAtom.FromAbsolutePath(logFile))); pipDataBuilder.Add(PipDataAtom.FromString(I($";{verbosity}"))); } }
/// <summary> /// Creates arguments. /// </summary> protected void CreateArguments( PipDataBuilder pipDataBuilder, IEnumerable <Operation> processOperations, StringTable stringTable) { foreach (var op in processOperations) { pipDataBuilder.Add(op.ToCommandLine(Context.PathTable)); } }
private TransformerExecuteArgumentsProcessor(Context context, ProcessBuilder processBuilder) { Contract.Requires(processBuilder != null); Contract.Requires(context != null); ArgumentsBuilder = processBuilder.ArgumentsBuilder; m_processBuilder = processBuilder; m_context = context; EmptyStringId = context.StringTable.Empty; }
private static Pip CreateCmdPip(BuildXLContext context, string tempDirectory, string outFile, bool is64Bit) { Contract.Requires(context != null); Contract.Requires(tempDirectory != null); Contract.Requires(!string.IsNullOrEmpty(outFile)); var pathTable = context.PathTable; string executable = is64Bit ? CmdHelper.CmdX64 : CmdHelper.CmdX86; FileArtifact executableArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, executable)); string workingDirectory = AssemblyDirectory; AbsolutePath workingDirectoryAbsolutePath = AbsolutePath.Create(pathTable, workingDirectory); AbsolutePath outFilePath = AbsolutePath.Create(pathTable, outFile); FileArtifact outFileArtifact = FileArtifact.CreateSourceFile(outFilePath).CreateNextWrittenVersion(); var pip = new BuildXL.Pips.Operations.Process( executableArtifact, workingDirectoryAbsolutePath, PipDataBuilder.CreatePipData( context.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "/d", "/c", "echo", "hello", ">", outFileArtifact), FileArtifact.Invalid, PipData.Invalid, ReadOnlyArray <EnvironmentVariable> .Empty, FileArtifact.Invalid, FileArtifact.Invalid, FileArtifact.Invalid, AbsolutePath.Create(pathTable, tempDirectory), null, null, ReadOnlyArray <FileArtifact> .FromWithoutCopy(executableArtifact), ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(outFileArtifact.WithAttributes()), ReadOnlyArray <DirectoryArtifact> .Empty, ReadOnlyArray <DirectoryArtifact> .Empty, ReadOnlyArray <PipId> .Empty, ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencies(pathTable)), ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencyScopes(pathTable)), ReadOnlyArray <StringId> .Empty, ReadOnlyArray <int> .Empty, ReadOnlyArray <ProcessSemaphoreInfo> .Empty, provenance: PipProvenance.CreateDummy(context), toolDescription: StringId.Invalid, additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty); return(pip); }
private void SetEnvironmentVariables(ProcessBuilder processBuilder, NinjaNode node) { foreach (KeyValuePair <string, string> kvp in m_environmentVariables.Value) { if (kvp.Value != null) { var envPipData = new PipDataBuilder(m_context.StringTable); if (SpecialEnvironmentVariables.PassThroughPrefixes.All(prefix => !kvp.Key.StartsWith(prefix))) { envPipData.Add(kvp.Value); processBuilder.SetEnvironmentVariable(StringId.Create(m_context.StringTable, kvp.Key), envPipData.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping)); } } } foreach (var kvp in m_passThroughEnvironmentVariables.Value) { processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(m_context.StringTable, kvp.Key)); } foreach (var envVar in SpecialEnvironmentVariables.CloudBuildEnvironment) { processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(m_context.StringTable, envVar)); } // GlobalUnsafePassthroughEnvironmentVariables processBuilder.SetGlobalPassthroughEnvironmentVariable(m_frontEndHost.Configuration.FrontEnd.GlobalUnsafePassthroughEnvironmentVariables, m_context.StringTable); // We will specify a different MSPDBSRV endpoint for every pip. // This means every pip that needs to communicate to MSPDBSRV will // spawn a different child process. // This is because if two pips use the same endpoint at the same time // then second one will fail after the first one finishes, because the // first one was the one that spawned MSPDBSRV.EXE as a child // (which gets killed). // // IMPORTANT: This will cause the build to fail if two pips target the same PDB file. // Both LINK.EXE and CL.EXE can use MSPDBSRV.EXE: // - If all linkers specify a different /pdb argument (or don't specify this argument and // are linking programs with different names // [https://docs.microsoft.com/en-us/cpp/build/reference/debug-generate-debug-info]) // then this won't happen // // - We're forcing the compiler to not output to PDBs (/Z7) // // so this should work in the normal cases. var mspdbsrvPipDataBuilder = new PipDataBuilder(m_context.StringTable); mspdbsrvPipDataBuilder.Add(PipConstructionUtilities.ComputeSha256(node.Command)); // Unique value for each pip processBuilder.SetEnvironmentVariable( StringId.Create(m_context.StringTable, SpecialEnvironmentVariables.MsPdvSrvEndpoint), mspdbsrvPipDataBuilder.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping)); }
private const int NumStandardBlockFragments = 8; // this number must match the number of fragments added in AddStandardBlock private void AddStandardBlock(PipDataBuilder pipDataBuilder) { pipDataBuilder.Add(Path1); pipDataBuilder.Add(Path2); pipDataBuilder.Add(CaseVaryingString); pipDataBuilder.Add(m_expectedStringId0); pipDataBuilder.AddVsoHash(SourceFile); pipDataBuilder.AddVsoHash(OutputFile); pipDataBuilder.AddVsoHash(RewrittenFile); pipDataBuilder.AddVsoHash(RewrittenFile2); // if you add more fragments here, update // (1) NumStandardBlockFragments constant above // (2) VerifyStandardBlock method below }
/// <summary> /// Adds a fake write file pip that produces to the given destination path. /// </summary> public WriteFile AddWriteFilePip(AbsolutePath destinationPath) { Contract.Requires(destinationPath != null); FileArtifact destinationArtifact = FileArtifact.CreateSourceFile(destinationPath).CreateNextWrittenVersion(); PipData contents = PipDataBuilder.CreatePipData(m_context.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "content"); var writeFile = new WriteFile(destinationArtifact, contents, WriteFileEncoding.Utf8, ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(m_context)); writeFile.PipId = AllocateNextPipId(); m_pips.Add(writeFile.PipId, writeFile); m_pathProducers.Add(destinationArtifact, writeFile); return(writeFile); }
/// <nodoc /> public bool TrySealDirectory( AbsolutePath directoryRoot, SortedReadOnlyArray <FileArtifact, OrdinalFileArtifactComparer> contents, SortedReadOnlyArray <DirectoryArtifact, OrdinalDirectoryArtifactComparer> outputDirectorycontents, SealDirectoryKind kind, string[] tags, string description, string[] patterns, out DirectoryArtifact sealedDirectory, bool scrub = false) { Contract.Requires(directoryRoot.IsValid); Contract.Requires(contents.IsValid); Contract.Requires(outputDirectorycontents.IsValid); PipData usage = PipDataBuilder.CreatePipData(Context.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping, description != null ? new PipDataAtom[] { description } : new PipDataAtom[] { "'", directoryRoot, "' [", contents.Length.ToString(CultureInfo.InvariantCulture), " files - ", outputDirectorycontents.Length.ToString(CultureInfo.InvariantCulture), " output directories]" }); var pip = new SealDirectory( directoryRoot, contents, outputDirectorycontents, kind, CreatePipProvenance(usage), ToStringIds(tags), ToStringIds(patterns), scrub); if (PipGraph != null) { sealedDirectory = PipGraph.AddSealDirectory(pip, GetValuePipId()); if (!sealedDirectory.IsValid) { return(false); } } else { sealedDirectory = DirectoryArtifact.CreateWithZeroPartialSealId(directoryRoot); } return(true); }
public static void Add(this PipDataBuilder @this, string prefix, RelativePath value) { var escaping = PipDataFragmentEscaping.CRuntimeArgumentRules; var separator = System.IO.Path.DirectorySeparatorChar.ToString(); using (@this.StartFragment(escaping, separator)) { if (!string.IsNullOrEmpty(prefix)) { @this.Add(prefix); } foreach (var atom in value.GetAtoms()) { @this.Add(atom); } } }
/// <nodoc/> public bool TryComposeSharedOpaqueDirectory( AbsolutePath directoryRoot, IReadOnlyList <DirectoryArtifact> contents, SealDirectoryContentFilter?contentFilter, [CanBeNull] string description, [CanBeNull] string[] tags, out DirectoryArtifact sharedOpaqueDirectory) { Contract.Requires(directoryRoot.IsValid); Contract.Requires(contents != null); if (PipGraph == null) { sharedOpaqueDirectory = DirectoryArtifact.CreateWithZeroPartialSealId(directoryRoot); return(true); } PipData usage = PipDataBuilder.CreatePipData(Context.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping, description != null ? new PipDataAtom[] { description } : new PipDataAtom[] { "'", directoryRoot, "' [", contents.Count.ToString(CultureInfo.InvariantCulture), " shared opaque directories, filter: ", contentFilter.HasValue ? $"'{contentFilter.Value.Regex}' (kind: {Enum.GetName(typeof(SealDirectoryContentFilter.ContentFilterKind), contentFilter.Value.Kind)})" : "''", "]" }); sharedOpaqueDirectory = PipGraph.ReserveSharedOpaqueDirectory(directoryRoot); var pip = new CompositeSharedOpaqueSealDirectory( directoryRoot, contents, CreatePipProvenance(usage), ToStringIds(tags), contentFilter); // The seal directory is ready to be initialized, since the directory artifact has been reserved already pip.SetDirectoryArtifact(sharedOpaqueDirectory); sharedOpaqueDirectory = PipGraph.AddSealDirectory(pip, GetValuePipId()); if (!sharedOpaqueDirectory.IsValid) { return(false); } return(true); }
private static void AddMsBuildProperty(PipDataBuilder pipDataBuilder, string key, string value) { // Make sure properties are always quoted, since MSBuild doesn't handle semicolon separated // properties without quotes using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, string.Empty)) { pipDataBuilder.Add(PipDataAtom.FromString("/p:")); using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, string.Empty)) { pipDataBuilder.Add(PipDataAtom.FromString(key)); } pipDataBuilder.Add(PipDataAtom.FromString("=\"")); using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, string.Empty)) { pipDataBuilder.Add(PipDataAtom.FromString(value)); } pipDataBuilder.Add(PipDataAtom.FromString("\"")); } }
public FileArtifact WriteFile(AbsolutePath destination, PipDataAtom content, WriteFileEncoding?encoding = null) { PipDataBuilder pipDataBuilder = new PipDataBuilder(Context.StringTable); pipDataBuilder.Add(content); if (!PipConstructionHelper.TryWriteFile( destination, pipDataBuilder.ToPipData(Context.StringTable.Empty, PipDataFragmentEscaping.NoEscaping), encoding ?? WriteFileEncoding.Utf8, null, null, out var result)) { throw new BuildXLTestException("Failed to add writefile pip"); } return(result); }
/// <summary> /// Schedules a pip to produce a file at the specified path under the given output directory. /// </summary> private static bool TryScheduleWriteOutputFileUnderDirectory( TestEnv env, AbsolutePath directory, string relativePath, out FileArtifact target) { Contract.Requires(env != null); Contract.Requires(directory.IsValid); Contract.Requires(!string.IsNullOrEmpty(relativePath)); target = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directory, env.Paths.CreateRelativePath(relativePath))).CreateNextWrittenVersion(); var pip = new WriteFile( target, PipDataBuilder.CreatePipData(env.PathTable.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping, "content"), WriteFileEncoding.Utf8, ReadOnlyArray <StringId> .Empty, env.CreatePipProvenance(StringId.Invalid)); return(env.PipGraph.AddWriteFile(pip, PipId.Invalid)); }
public void PipFragmentEquality() { var pathTable = new PathTable(); StructTester.TestEquality( baseValue: PipFragment.FromString("mystring", pathTable.StringTable), equalValue: PipFragment.FromString("mystring", pathTable.StringTable), notEqualValues: new[] { PipFragment.FromString("MyString", pathTable.StringTable), PipFragment.FromAbsolutePathForTesting( FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, A("t", "file1.txt")))), PipFragment.FromAbsolutePathForTesting( FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, A("t", "file1.txt"))).CreateNextWrittenVersion()), PipFragment.CreateNestedFragment( PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules)) }, eq: (left, right) => left == right, neq: (left, right) => left != right); }
/// <summary> /// Adds a fake process pip that produces only the given path. /// </summary> public Process AddProcess(AbsolutePath producedPath, DoubleWritePolicy doubleWritePolicy = DoubleWritePolicy.DoubleWritesAreErrors) { Contract.Assume(!m_pathProducers.ContainsKey(producedPath), "Each path may have only one producer (no rewrites)"); AbsolutePath workingDirectory = AbsolutePath.Create(m_context.PathTable, PathGeneratorUtilities.GetAbsolutePath("X", "")); AbsolutePath exe = AbsolutePath.Create(m_context.PathTable, PathGeneratorUtilities.GetAbsolutePath("X", "fake.exe")); var process = new Process( executable: FileArtifact.CreateSourceFile(exe), workingDirectory: workingDirectory, arguments: PipDataBuilder.CreatePipData(m_context.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping), responseFile: FileArtifact.Invalid, responseFileData: PipData.Invalid, environmentVariables: ReadOnlyArray <EnvironmentVariable> .Empty, standardInput: FileArtifact.Invalid, standardOutput: FileArtifact.Invalid, standardError: FileArtifact.Invalid, standardDirectory: workingDirectory, warningTimeout: null, timeout: null, dependencies: ReadOnlyArray <FileArtifact> .FromWithoutCopy(FileArtifact.CreateSourceFile(exe)), outputs: ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(FileArtifact.CreateSourceFile(producedPath).CreateNextWrittenVersion().WithAttributes()), directoryDependencies: ReadOnlyArray <DirectoryArtifact> .Empty, directoryOutputs: ReadOnlyArray <DirectoryArtifact> .Empty, orderDependencies: ReadOnlyArray <PipId> .Empty, untrackedPaths: ReadOnlyArray <AbsolutePath> .Empty, untrackedScopes: ReadOnlyArray <AbsolutePath> .Empty, tags: ReadOnlyArray <StringId> .Empty, successExitCodes: ReadOnlyArray <int> .Empty, semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty, provenance: PipProvenance.CreateDummy(m_context), toolDescription: StringId.Invalid, additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty, doubleWritePolicy: doubleWritePolicy); process.PipId = AllocateNextPipId(); m_pips.Add(process.PipId, process); m_pathProducers.Add(producedPath, process); return(process); }
/// <summary> /// Configure the environment for a process /// </summary> public static void SetProcessEnvironmentVariables( IReadOnlyDictionary <string, string> userDefinedEnvironment, [CanBeNull] IEnumerable <string> userDefinedPassthroughVariables, ProcessBuilder processBuilder, PathTable pathTable) { Contract.RequiresNotNull(userDefinedEnvironment); Contract.RequiresNotNull(processBuilder); foreach (KeyValuePair <string, string> kvp in userDefinedEnvironment) { if (kvp.Value != null) { var envPipData = new PipDataBuilder(pathTable.StringTable); // Casing for paths is not stable as reported by BuildPrediction. So here we try to guess if the value // represents a path, and normalize it string value = kvp.Value; if (!string.IsNullOrEmpty(value) && AbsolutePath.TryCreate(pathTable, value, out var absolutePath)) { envPipData.Add(absolutePath); } else { envPipData.Add(value); } processBuilder.SetEnvironmentVariable( StringId.Create(pathTable.StringTable, kvp.Key), envPipData.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping)); } } if (userDefinedPassthroughVariables != null) { foreach (string passThroughVariable in userDefinedPassthroughVariables) { processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(pathTable.StringTable, passThroughVariable)); } } }
private PerProcessPipPerformanceInformation CreateSamplePip(int index) { Func <RunnablePip, Task <PipResult> > taskFactory = async(runnablePip) => { PipResult result; var operationTracker = new OperationTracker(runnablePip.LoggingContext); var pip = runnablePip.Pip; using (var operationContext = operationTracker.StartOperation(PipExecutorCounter.PipRunningStateDuration, pip.PipId, pip.PipType, runnablePip.LoggingContext)) { result = await TestPipExecutor.ExecuteAsync(operationContext, m_executionEnvironment, pip); } return(result); }; var pathTable = m_context.PathTable; var executable = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, X("/x/pkgs/tool.exe"))); var dependencies = new HashSet <FileArtifact> { executable }; var processBuilder = new ProcessBuilder() .WithExecutable(executable) .WithWorkingDirectory(AbsolutePath.Create(pathTable, X("/x/obj/working"))) .WithArguments(PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "-loadargs")) .WithStandardDirectory(AbsolutePath.Create(pathTable, X("/x/obj/working.std"))) .WithDependencies(dependencies) .WithContext(m_context); var dataBuilder = new PipDataBuilder(m_context.PathTable.StringTable); var pipData = dataBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping); var pip = processBuilder.WithArguments(pipData).Build(); var pipId = m_executionEnvironment.PipTable.Add((uint)(index + 1), pip); var runnableProcessPip = (ProcessRunnablePip)(RunnablePip.Create(m_loggingContext, m_executionEnvironment, pipId, PipType.Process, 0, taskFactory, 0)); m_runnablePips.Add(index, runnableProcessPip); // For verification return(GeneratePipInfoWithRunnablePipAndIndex(ref runnableProcessPip, index)); }
/// <summary> /// Gets the command line arguments for the process. /// </summary> public PipData GetArgumentsDataFromProcess(Process process) { PipData arguments = process.Arguments; if (process.ResponseFile.IsValid) { var responseFileData = process.ResponseFileData; PipDataBuilder pipDataBuilder = new PipDataBuilder(StringTable); // Add all the arguments from the command line excluding the response file (the last fragment) foreach (var fragment in process.Arguments.Take(process.Arguments.FragmentCount - 1).Concat(responseFileData)) { Contract.Assume(fragment.FragmentType != PipFragmentType.Invalid); pipDataBuilder.Add(fragment); } arguments = pipDataBuilder.ToPipData(arguments.FragmentSeparator, arguments.FragmentEscaping); } return(arguments); }
private void AddJavaScriptArgumentToBuilder(PipDataBuilder argumentsBuilder, JavaScriptArgument value) { switch (value.GetValue()) { case string s: using (argumentsBuilder.StartFragment(PipDataFragmentEscaping.NoEscaping, m_context.StringTable.Empty)) { argumentsBuilder.Add(s); } break; case AbsolutePath absolutePath: using (argumentsBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, m_context.StringTable.Empty)) { argumentsBuilder.Add(absolutePath); } break; case RelativePath relativePath: using (argumentsBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, m_context.StringTable.Empty)) { argumentsBuilder.Add(relativePath); } break; case PathAtom pathAtom: using (argumentsBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, m_context.StringTable.Empty)) { argumentsBuilder.Add(pathAtom); } break; default: Contract.Assert(false, $"Unexpected argument '{value.GetType()}'"); break; } }
public static Process CreateDummyProcessWithInputs(IEnumerable <FileArtifact> inputs, BuildXLContext context) { FileArtifact output = FileArtifact.CreateSourceFile(AbsolutePath.Create(context.PathTable, @"\\FAKEPATH\output" + s_procCounter + ".txt")).CreateNextWrittenVersion(); s_procCounter++; FileArtifact exe = FileArtifact.CreateSourceFile(AbsolutePath.Create(context.PathTable, @"\\FAKEPATH\tool.exe")); var pipDataBuilder = new PipDataBuilder(context.StringTable); return(new Process( executable: exe, workingDirectory: AbsolutePath.Create(context.PathTable, @"\\FAKEPATH\"), arguments: pipDataBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping), responseFile: FileArtifact.Invalid, responseFileData: PipData.Invalid, environmentVariables: ReadOnlyArray <EnvironmentVariable> .Empty, standardInput: FileArtifact.Invalid, standardOutput: FileArtifact.Invalid, standardError: FileArtifact.Invalid, standardDirectory: output.Path.GetParent(context.PathTable), warningTimeout: null, timeout: null, dependencies: ReadOnlyArray <FileArtifact> .From(inputs.Union(new[] { exe })), outputs: ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(output.WithAttributes()), directoryDependencies: ReadOnlyArray <DirectoryArtifact> .Empty, directoryOutputs: ReadOnlyArray <DirectoryArtifact> .Empty, orderDependencies: ReadOnlyArray <PipId> .Empty, untrackedPaths: ReadOnlyArray <AbsolutePath> .Empty, untrackedScopes: ReadOnlyArray <AbsolutePath> .Empty, tags: ReadOnlyArray <StringId> .Empty, successExitCodes: ReadOnlyArray <int> .Empty, semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty, provenance: PipProvenance.CreateDummy(context), toolDescription: StringId.Invalid, additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty)); }
private static Process CreateConsoleProcessInContainer( BuildXLContext context, TempFileStorage tempFiles, PathTable pt, string arguments, ReadOnlyArray <FileArtifactWithAttributes> outputFiles, ReadOnlyArray <DirectoryArtifact> directoryOutputs, ContainerIsolationLevel containerIsolationLevel = ContainerIsolationLevel.IsolateAllOutputs) { var executableFileArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(context.PathTable, CmdHelper.CmdX64)); var argumentBuilder = new PipDataBuilder(context.PathTable.StringTable); argumentBuilder.Add("/d"); argumentBuilder.Add("/c"); using (argumentBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, " ")) { foreach (var arg in arguments.Split(new[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries)) { argumentBuilder.Add(arg); } } string workingDirectory = tempFiles.GetUniqueDirectory(); var workingDirectoryAbsolutePath = AbsolutePath.Create(context.PathTable, workingDirectory); string uniqueOutputDirectory = tempFiles.GetUniqueDirectory(); var uniqueOutputDirectoryPath = AbsolutePath.Create(context.PathTable, uniqueOutputDirectory); string uniqueRedirectedOutputDirectory = tempFiles.GetUniqueDirectory("redirected"); var uniqueRedirectedOutputDirectoryPath = AbsolutePath.Create(context.PathTable, uniqueRedirectedOutputDirectory); var pip = new Process( executableFileArtifact, workingDirectoryAbsolutePath, argumentBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping), FileArtifact.Invalid, PipData.Invalid, ReadOnlyArray <EnvironmentVariable> .FromWithoutCopy(), FileArtifact.Invalid, FileArtifact.Invalid, FileArtifact.Invalid, tempFiles.GetUniqueDirectory(pt), null, null, dependencies: ReadOnlyArray <FileArtifact> .FromWithoutCopy(new[] { executableFileArtifact }), outputs: outputFiles, directoryDependencies: ReadOnlyArray <DirectoryArtifact> .Empty, directoryOutputs: directoryOutputs, orderDependencies: ReadOnlyArray <PipId> .Empty, untrackedPaths: ReadOnlyArray <AbsolutePath> .Empty, untrackedScopes: ReadOnlyArray <AbsolutePath> .Empty, tags: ReadOnlyArray <StringId> .Empty, successExitCodes: ReadOnlyArray <int> .Empty, semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty, provenance: PipProvenance.CreateDummy(context), toolDescription: StringId.Invalid, additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty, options: Process.Options.NeedsToRunInContainer, uniqueOutputDirectory: uniqueOutputDirectoryPath, uniqueRedirectedDirectoryRoot: uniqueRedirectedOutputDirectoryPath, containerIsolationLevel: containerIsolationLevel); return(pip); }
internal FragmentScope(PipDataBuilder pipDataBuilder) { m_pipDataBuilder = pipDataBuilder; }
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); }