[ModuleInterface] Look for a prebuilt module by full target name (#24402)

Although the default cache location separates by platform, a
/combined/ cache is still an interesting idea, and in that case we
need to use the full platform names.
This commit is contained in:
Jordan Rose
2019-05-01 13:48:32 -07:00
committed by GitHub
parent f863700bfa
commit 3d16557c7f
2 changed files with 95 additions and 2 deletions

View File

@@ -19,6 +19,7 @@
#include "swift/AST/Module.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/Basic/Lazy.h"
#include "swift/Basic/Platform.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/ParseableInterfaceSupport.h"
@@ -826,7 +827,7 @@ class ParseableInterfaceModuleLoaderImpl {
// Assemble the expected path: $PREBUILT_CACHE/Foo.swiftmodule or
// $PREBUILT_CACHE/Foo.swiftmodule/arch.swiftmodule. Note that there's no
// cache key here.
scratch.append(prebuiltCacheDir);
scratch = prebuiltCacheDir;
// FIXME: Would it be possible to only have architecture-specific names
// here? Then we could skip this check.
@@ -845,6 +846,48 @@ class ParseableInterfaceModuleLoaderImpl {
return scratch.str();
}
/// Hack to deal with build systems (including the Swift standard library, at
/// the time of this comment) that aren't yet using target-specific names for
/// multi-target swiftmodules, in case the prebuilt cache is.
Optional<StringRef>
computeFallbackPrebuiltModulePath(llvm::SmallString<256> &scratch) {
namespace path = llvm::sys::path;
StringRef sdkPath = ctx.SearchPathOpts.SDKPath;
// Check if the interface file comes from the SDK
if (sdkPath.empty() || !hasPrefix(path::begin(interfacePath),
path::end(interfacePath),
path::begin(sdkPath),
path::end(sdkPath)))
return None;
// If the module isn't target-specific, there's no fallback path.
StringRef inParentDirName =
path::filename(path::parent_path(interfacePath));
if (path::extension(inParentDirName) != ".swiftmodule")
return None;
// If the interface is already using the target-specific name, there's
// nothing else to try.
auto normalizedTarget = getTargetSpecificModuleTriple(ctx.LangOpts.Target);
if (path::stem(modulePath) == normalizedTarget.str())
return None;
// Assemble the expected path:
// $PREBUILT_CACHE/Foo.swiftmodule/target.swiftmodule. Note that there's no
// cache key here.
scratch = prebuiltCacheDir;
path::append(scratch, inParentDirName);
path::append(scratch, normalizedTarget.str());
scratch += ".swiftmodule";
// If there isn't a file at this location, skip returning a path.
if (!fs.exists(scratch))
return None;
return scratch.str();
}
bool isInResourceDir(StringRef path) {
StringRef resourceDir = ctx.SearchPathOpts.RuntimeLibraryPath;
if (resourceDir.empty()) return false;
@@ -926,7 +969,12 @@ class ParseableInterfaceModuleLoaderImpl {
if (!prebuiltCacheDir.empty()) {
llvm::SmallString<256> scratch;
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
auto path = computePrebuiltModulePath(scratch);
Optional<StringRef> path = computePrebuiltModulePath(scratch);
if (!path) {
// Hack: deal with prebuilds of modules that still use the target-based
// names.
path = computeFallbackPrebuiltModulePath(scratch);
}
if (path) {
if (swiftModuleIsUpToDate(*path, deps, moduleBuffer)) {
LLVM_DEBUG(llvm::dbgs() << "Found up-to-date prebuilt module at "