mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix response file support for batch jobs.
This commit is contained in:
committed by
Tony Allevato
parent
9a6fa09729
commit
6d7223023d
@@ -62,6 +62,27 @@ ToolChain::JobContext::getTemporaryFilePath(const llvm::Twine &name,
|
||||
return C.getArgs().MakeArgString(buffer.str());
|
||||
}
|
||||
|
||||
Optional<Job::ResponseFileInfo>
|
||||
ToolChain::getResponseFileInfo(const Compilation &C, const char *executablePath,
|
||||
const ToolChain::InvocationInfo &invocationInfo,
|
||||
const ToolChain::JobContext &context) const {
|
||||
const bool forceResponseFiles =
|
||||
C.getArgs().hasArg(options::OPT_driver_force_response_files);
|
||||
assert((invocationInfo.allowsResponseFiles || !forceResponseFiles) &&
|
||||
"Cannot force response file if platform does not allow it");
|
||||
|
||||
if (forceResponseFiles || (invocationInfo.allowsResponseFiles &&
|
||||
!llvm::sys::commandLineFitsWithinSystemLimits(
|
||||
executablePath, invocationInfo.Arguments))) {
|
||||
const char *responseFilePath =
|
||||
context.getTemporaryFilePath("arguments", "resp");
|
||||
const char *responseFileArg =
|
||||
C.getArgs().MakeArgString(Twine("@") + responseFilePath);
|
||||
return {{responseFilePath, responseFileArg}};
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
std::unique_ptr<Job> ToolChain::constructJob(
|
||||
const JobAction &JA, Compilation &C, SmallVectorImpl<const Job *> &&inputs,
|
||||
ArrayRef<const Action *> inputActions,
|
||||
@@ -114,28 +135,16 @@ std::unique_ptr<Job> ToolChain::constructJob(
|
||||
}
|
||||
}
|
||||
|
||||
const char *responseFilePath = nullptr;
|
||||
const char *responseFileArg = nullptr;
|
||||
// Determine if the argument list is so long that it needs to be written into
|
||||
// a response file.
|
||||
auto responseFileInfo =
|
||||
getResponseFileInfo(C, executablePath, invocationInfo, context);
|
||||
|
||||
const bool forceResponseFiles =
|
||||
C.getArgs().hasArg(options::OPT_driver_force_response_files);
|
||||
assert((invocationInfo.allowsResponseFiles || !forceResponseFiles) &&
|
||||
"Cannot force response file if platform does not allow it");
|
||||
|
||||
if (forceResponseFiles || (invocationInfo.allowsResponseFiles &&
|
||||
!llvm::sys::commandLineFitsWithinSystemLimits(
|
||||
executablePath, invocationInfo.Arguments))) {
|
||||
responseFilePath = context.getTemporaryFilePath("arguments", "resp");
|
||||
responseFileArg = C.getArgs().MakeArgString(Twine("@") + responseFilePath);
|
||||
}
|
||||
|
||||
return llvm::make_unique<Job>(JA, std::move(inputs), std::move(output),
|
||||
executablePath,
|
||||
std::move(invocationInfo.Arguments),
|
||||
std::move(invocationInfo.ExtraEnvironment),
|
||||
std::move(invocationInfo.FilelistInfos),
|
||||
responseFilePath,
|
||||
responseFileArg);
|
||||
return llvm::make_unique<Job>(
|
||||
JA, std::move(inputs), std::move(output), executablePath,
|
||||
std::move(invocationInfo.Arguments),
|
||||
std::move(invocationInfo.ExtraEnvironment),
|
||||
std::move(invocationInfo.FilelistInfos), responseFileInfo);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -345,10 +354,12 @@ ToolChain::constructBatchJob(ArrayRef<const Job *> unsortedJobs,
|
||||
*output, OI};
|
||||
auto invocationInfo = constructInvocation(*batchCJA, context);
|
||||
// Batch mode can produce quite long command lines; in almost every case these
|
||||
// will trigger use of supplementary output file maps, but in some rare corner
|
||||
// cases (very few files, very long paths) they might not. However, in those
|
||||
// cases we _should_ degrade to using response files to pass arguments to the
|
||||
// frontend, which is done automatically by code elsewhere.
|
||||
// will trigger use of supplementary output file maps. However, if the driver
|
||||
// command line is long for reasons unrelated to the number of input files,
|
||||
// such as passing a large number of flags, then the individual batch jobs are
|
||||
// also likely to overflow. We have to check for that explicitly here, because
|
||||
// the BatchJob created here does not go through the same code path in
|
||||
// constructJob above.
|
||||
//
|
||||
// The `allowsResponseFiles` flag on the `invocationInfo` we have here exists
|
||||
// only to model external tools that don't know about response files, such as
|
||||
@@ -356,9 +367,13 @@ ToolChain::constructBatchJob(ArrayRef<const Job *> unsortedJobs,
|
||||
// should always be true. But double check with an assert here in case someone
|
||||
// failed to set it in `constructInvocation`.
|
||||
assert(invocationInfo.allowsResponseFiles);
|
||||
auto responseFileInfo =
|
||||
getResponseFileInfo(C, executablePath, invocationInfo, context);
|
||||
|
||||
return llvm::make_unique<BatchJob>(
|
||||
*batchCJA, inputJobs.takeVector(), std::move(output), executablePath,
|
||||
std::move(invocationInfo.Arguments),
|
||||
std::move(invocationInfo.ExtraEnvironment),
|
||||
std::move(invocationInfo.FilelistInfos), sortedJobs, NextQuasiPID);
|
||||
std::move(invocationInfo.FilelistInfos), sortedJobs, NextQuasiPID,
|
||||
responseFileInfo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user