コード例 #1
0
        private PipData FinishArgumentsAndOverflowArgumentsToResponseFile(DirectoryArtifact defaultDirectory)
        {
            Contract.Requires(defaultDirectory.IsValid);

            PipData arguments        = default;
            var     argumentsBuilder = m_argumentsBuilder.Instance;

            if (!m_responseFileFirstArg.IsDefault)
            {
                bool mkRespFile = m_responseFileForceCreation;
                if (!mkRespFile)
                {
                    // make a response file only if the command-line is too long
                    arguments = argumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules);

                    // Normalize choice to use response file by assuming paths are of length max path with a space. This will
                    // ensure there are no cases where changing the root will change whether a response file is used.
                    int cmdLineLength = arguments.GetMaxPossibleLength(m_pathTable.StringTable);
                    mkRespFile = cmdLineLength > MaxCommandLineLength;
                }

                if (mkRespFile)
                {
                    // create a pip data for the stuff in the response file
                    ResponseFileData = argumentsBuilder.ToPipData("\r\n", PipDataFragmentEscaping.CRuntimeArgumentRules, m_responseFileFirstArg);

                    // generate the file
                    ResponseFile = FileArtifact.CreateSourceFile(defaultDirectory.Path.Combine(m_pathTable, PathAtom.Create(m_pathTable.StringTable, "args.rsp")));

                    argumentsBuilder.TrimEnd(m_responseFileFirstArg);

                    AddUntrackedFile(ResponseFile);
                    if (string.IsNullOrEmpty(m_responseFilePrefix))
                    {
                        argumentsBuilder.Add(ResponseFile);
                    }
                    else
                    {
                        using (argumentsBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, m_pathTable.StringTable.Empty))
                        {
                            argumentsBuilder.Add(m_responseFilePrefix);
                            argumentsBuilder.Add(ResponseFile);
                        }
                    }

                    arguments = argumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules);
                }
            }
            else
            {
                arguments = argumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules);
            }

            return(arguments);
        }
コード例 #2
0
        /// <summary>
        /// Configure the processBuilder's ResponseFile and ResponseFileData according to this specification.
        /// This method mutates the processBuilder, changing its argumentsBuilder, ResponseFile and ResponseFileData accordingly.
        /// We return the arguments to be passed to the process.
        /// </summary>
        internal PipData SplitArgumentsAndCreateResponseFileIfNeeded(ProcessBuilder processBuilder, DirectoryArtifact defaultDirectory, PathTable pathTable)
        {
            PipData arguments        = default; // We'll return the actual arguments to be passed to the process.
            var     argumentsBuilder = processBuilder.ArgumentsBuilder;
            var     cutoffArg        = m_firstArg;

            // We will create a response file in the following cases:
            //  1. If an explicit response file content was specified, either by having m_explicitData or
            //        by having m_forceCreation = true
            //  2. If the argument line is too long (longer than MaxCommandLineLength) and m_firstArg is not the default.
            // An additional argument is added to the process specifying the response file location, prefixed
            // by m_prefix, unless m_requiresArgument was set to false.
            if (!m_firstArg.IsDefault || m_explicitData.IsValid)
            {
                bool argumentLineTooLong = false;
                if (!m_forceCreation)
                {
                    // make a response file only if the command-line is too long
                    arguments = argumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules);

                    // Normalize choice to use response file by assuming paths are of length max path with a space. This will
                    // ensure there are no cases where changing the root will change whether a response file is used.
                    int cmdLineLength = arguments.GetMaxPossibleLength(pathTable.StringTable);
                    argumentLineTooLong = cmdLineLength > ProcessBuilder.MaxCommandLineLength;
                }

                if (m_forceCreation || argumentLineTooLong || m_explicitData.IsValid)
                {
                    // add the explicit contents if we have to
                    if (m_explicitData.IsValid)
                    {
                        if (!argumentLineTooLong)
                        {
                            // If there was no overflow, we mark 'here' as the starting
                            // point for the response file before adding the explicit data as an 'argument'.
                            cutoffArg = argumentsBuilder.CreateCursor();
                        }

                        argumentsBuilder.Add(m_explicitData);
                    }

                    // create a pip data for the stuff in the response file
                    processBuilder.ResponseFileData = argumentsBuilder.ToPipData(Environment.NewLine, PipDataFragmentEscaping.CRuntimeArgumentRules, cutoffArg);

                    // generate the file
                    processBuilder.ResponseFile = FileArtifact.CreateSourceFile(GetResponseFilePath(defaultDirectory, pathTable));

                    argumentsBuilder.TrimEnd(cutoffArg);

                    processBuilder.AddUntrackedFile(processBuilder.ResponseFile);

                    if (m_requiresArgument)
                    {
                        if (string.IsNullOrEmpty(m_prefix))
                        {
                            argumentsBuilder.Add(processBuilder.ResponseFile);
                        }
                        else
                        {
                            using (argumentsBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, pathTable.StringTable.Empty))
                            {
                                argumentsBuilder.Add(m_prefix);
                                argumentsBuilder.Add(processBuilder.ResponseFile);
                            }
                        }
                    }
                    arguments = argumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules);
                }
            }
            else
            {
                arguments = argumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules);
            }

            return(arguments);
        }