Skip to content

Commit 62dddc1

Browse files
committed
ModuleInterface: teach module build action to use fall-back interface if building canonical interface failed.
1 parent de221dd commit 62dddc1

File tree

4 files changed

+46
-23
lines changed

4 files changed

+46
-23
lines changed

include/swift/AST/ModuleLoader.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,6 @@ class ModuleInterfaceChecker {
157157
ArrayRef<std::string> candidates,
158158
StringRef outPath) = 0;
159159
virtual ~ModuleInterfaceChecker() = default;
160-
virtual std::string getBackupPublicModuleInterfacePath(StringRef moduleName,
161-
StringRef interfacePath) = 0;
162160
};
163161

164162
/// Abstract interface to run an action in a sub ASTContext.

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,6 @@ class ModuleInterfaceCheckerImpl: public ModuleInterfaceChecker {
367367
ArrayRef<std::string> candidates,
368368
StringRef outPath) override;
369369
bool isCached(StringRef DepPath);
370-
std::string getBackupPublicModuleInterfacePath(StringRef moduleName,
371-
StringRef interfacePath) override;
372370
};
373371

374372
/// A ModuleLoader that runs a subordinate \c CompilerInvocation and

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,17 @@ class ModuleInterfaceLoaderImpl {
425425
}
426426

427427
std::string getBackupPublicModuleInterfacePath() {
428+
return getBackupPublicModuleInterfacePath(ctx.SourceMgr, backupInterfaceDir,
429+
moduleName, interfacePath);
430+
}
431+
432+
static std::string getBackupPublicModuleInterfacePath(SourceManager &SM,
433+
StringRef backupInterfaceDir,
434+
StringRef moduleName,
435+
StringRef interfacePath) {
428436
if (backupInterfaceDir.empty())
429437
return std::string();
430-
auto &fs = *ctx.SourceMgr.getFileSystem();
438+
auto &fs = *SM.getFileSystem();
431439
auto fileName = llvm::sys::path::filename(interfacePath);
432440
{
433441
llvm::SmallString<256> path(backupInterfaceDir);
@@ -1145,21 +1153,6 @@ ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface(
11451153
return results;
11461154
}
11471155

1148-
std::string
1149-
ModuleInterfaceCheckerImpl::getBackupPublicModuleInterfacePath(StringRef moduleName,
1150-
StringRef interfacePath) {
1151-
// Derive .swiftmodule path from the .swiftinterface path.
1152-
auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
1153-
llvm::SmallString<32> modulePath = interfacePath;
1154-
llvm::sys::path::replace_extension(modulePath, newExt);
1155-
ModuleInterfaceLoaderImpl Impl(Ctx, modulePath, interfacePath, moduleName,
1156-
CacheDir, PrebuiltCacheDir, BackupInterfaceDir,
1157-
SourceLoc(), Opts,
1158-
RequiresOSSAModules, nullptr,
1159-
ModuleLoadingMode::PreferSerialized);
1160-
return Impl.getBackupPublicModuleInterfacePath();
1161-
}
1162-
11631156
bool ModuleInterfaceCheckerImpl::tryEmitForwardingModule(
11641157
StringRef moduleName, StringRef interfacePath,
11651158
ArrayRef<std::string> candidates, StringRef outputPath) {
@@ -1212,9 +1205,29 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
12121205
LoaderOpts.disableInterfaceLock);
12131206
// FIXME: We really only want to serialize 'important' dependencies here, if
12141207
// we want to ship the built swiftmodules to another machine.
1215-
return builder.buildSwiftModule(OutPath, /*shouldSerializeDeps*/true,
1216-
/*ModuleBuffer*/nullptr, nullptr,
1217-
SearchPathOpts.CandidateCompiledModules);
1208+
auto failed = builder.buildSwiftModule(OutPath, /*shouldSerializeDeps*/true,
1209+
/*ModuleBuffer*/nullptr, nullptr,
1210+
SearchPathOpts.CandidateCompiledModules);
1211+
if (!failed)
1212+
return false;
1213+
auto backInPath =
1214+
ModuleInterfaceLoaderImpl::getBackupPublicModuleInterfacePath(SourceMgr,
1215+
BackupInterfaceDir, ModuleName, InPath);
1216+
if (backInPath.empty())
1217+
return true;
1218+
assert(failed);
1219+
assert(!backInPath.empty());
1220+
ModuleInterfaceBuilder backupBuilder(SourceMgr, &Diags, astDelegate, backInPath,
1221+
ModuleName, CacheDir, PrebuiltCacheDir,
1222+
BackupInterfaceDir,
1223+
LoaderOpts.disableInterfaceLock);
1224+
// Ensure we can rebuild module after user changed the original interface file.
1225+
backupBuilder.addExtraDependency(InPath);
1226+
// FIXME: We really only want to serialize 'important' dependencies here, if
1227+
// we want to ship the built swiftmodules to another machine.
1228+
return backupBuilder.buildSwiftModule(OutPath, /*shouldSerializeDeps*/true,
1229+
/*ModuleBuffer*/nullptr, nullptr,
1230+
SearchPathOpts.CandidateCompiledModules);
12181231
}
12191232

12201233
void ModuleInterfaceLoader::collectVisibleTopLevelModuleNames(
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/sources)
3+
// RUN: %empty-directory(%t/inputs)
4+
// RUN: %empty-directory(%t/alternative-inputs)
5+
// RUN: %empty-directory(%t/module-cache)
6+
// RUN: %empty-directory(%t/outputs)
7+
8+
// RUN: echo "public func foo() {}" > %t/sources/Foo.swift
9+
// RUN: %target-swift-frontend-typecheck -emit-module-interface-path %t/inputs/Foo.swiftinterface %t/sources/Foo.swift -module-name Foo -disable-implicit-concurrency-module-import -enable-library-evolution -module-cache-path %t/module-cache -I %t/inputs -swift-version 5
10+
// RUN: cp %t/inputs/Foo.swiftinterface %t/alternative-inputs/Foo.swiftinterface
11+
// RUN: echo "mess_mess_mess" >> %t/inputs/Foo.swiftinterface
12+
// RUN: not %target-swift-frontend -compile-module-from-interface -module-name Foo %t/inputs/Foo.swiftinterface -o %t/outputs/Foo.swiftmodule
13+
14+
// RUN: %target-swift-frontend -compile-module-from-interface -module-name Foo %t/inputs/Foo.swiftinterface -o %t/outputs/Foo.swiftmodule -backup-module-interface-path %t/alternative-inputs

0 commit comments

Comments
 (0)