Skip to content

Commit 21b96d4

Browse files
authored
Merge pull request #23175 from brentdax/theres-a-path-for-everyone
Look for runtime library modules in the SDK, too
2 parents d36af3b + c177674 commit 21b96d4

File tree

6 files changed

+108
-30
lines changed

6 files changed

+108
-30
lines changed

include/swift/AST/SearchPathOptions.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ class SearchPathOptions {
6767
/// Path to search for compiler-relative stdlib dylibs.
6868
std::string RuntimeLibraryPath;
6969

70-
/// Path to search for compiler-relative stdlib modules.
71-
std::string RuntimeLibraryImportPath;
70+
/// Paths to search for stdlib modules. One of these will be compiler-relative.
71+
std::vector<std::string> RuntimeLibraryImportPaths;
7272

7373
/// Don't look in for compiler-provided modules.
74-
bool SkipRuntimeLibraryImportPath = false;
74+
bool SkipRuntimeLibraryImportPaths = false;
7575

7676
/// Return a hash code of any components from these options that should
7777
/// contribute to a Swift Bridging PCH hash.
@@ -92,7 +92,9 @@ class SearchPathOptions {
9292
Code = hash_combine(Code, LibraryPath);
9393
}
9494
Code = hash_combine(Code, RuntimeResourcePath);
95-
Code = hash_combine(Code, RuntimeLibraryImportPath);
95+
for (auto RuntimeLibraryImportPath : RuntimeLibraryImportPaths) {
96+
Code = hash_combine(Code, RuntimeLibraryImportPath);
97+
}
9698
return Code;
9799
}
98100
};

include/swift/Frontend/Frontend.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,7 @@ class CompilerInvocation {
184184

185185
void setRuntimeResourcePath(StringRef Path);
186186

187-
void setSDKPath(const std::string &Path) {
188-
SearchPathOpts.SDKPath = Path;
189-
}
187+
void setSDKPath(const std::string &Path);
190188

191189
StringRef getSDKPath() const {
192190
return SearchPathOpts.SDKPath;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,35 @@ void CompilerInvocation::setMainExecutablePath(StringRef Path) {
4242
setRuntimeResourcePath(LibPath.str());
4343
}
4444

45-
static void updateRuntimeLibraryPath(SearchPathOptions &SearchPathOpts,
46-
llvm::Triple &Triple) {
45+
static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
46+
llvm::Triple &Triple) {
4747
llvm::SmallString<128> LibPath(SearchPathOpts.RuntimeResourcePath);
4848

4949
llvm::sys::path::append(LibPath, getPlatformNameForTriple(Triple));
5050
SearchPathOpts.RuntimeLibraryPath = LibPath.str();
5151

52+
// Set up the import paths containing the swiftmodules for the libraries in
53+
// RuntimeLibraryPath.
54+
SearchPathOpts.RuntimeLibraryImportPaths.clear();
55+
56+
// If this is set, we don't want any runtime import paths.
57+
if (SearchPathOpts.SkipRuntimeLibraryImportPaths)
58+
return;
59+
5260
if (!Triple.isOSDarwin())
5361
llvm::sys::path::append(LibPath, swift::getMajorArchitectureName(Triple));
54-
SearchPathOpts.RuntimeLibraryImportPath = LibPath.str();
62+
SearchPathOpts.RuntimeLibraryImportPaths.push_back(LibPath.str());
63+
64+
if (!SearchPathOpts.SDKPath.empty()) {
65+
LibPath = SearchPathOpts.SDKPath;
66+
llvm::sys::path::append(LibPath, "usr", "lib", "swift");
67+
SearchPathOpts.RuntimeLibraryImportPaths.push_back(LibPath.str());
68+
}
5569
}
5670

5771
void CompilerInvocation::setRuntimeResourcePath(StringRef Path) {
5872
SearchPathOpts.RuntimeResourcePath = Path;
59-
updateRuntimeLibraryPath(SearchPathOpts, LangOpts.Target);
73+
updateRuntimeLibraryPaths(SearchPathOpts, LangOpts.Target);
6074
}
6175

6276
void CompilerInvocation::setTargetTriple(StringRef Triple) {
@@ -65,7 +79,12 @@ void CompilerInvocation::setTargetTriple(StringRef Triple) {
6579

6680
void CompilerInvocation::setTargetTriple(const llvm::Triple &Triple) {
6781
LangOpts.setTarget(Triple);
68-
updateRuntimeLibraryPath(SearchPathOpts, LangOpts.Target);
82+
updateRuntimeLibraryPaths(SearchPathOpts, LangOpts.Target);
83+
}
84+
85+
void CompilerInvocation::setSDKPath(const std::string &Path) {
86+
SearchPathOpts.SDKPath = Path;
87+
updateRuntimeLibraryPaths(SearchPathOpts, LangOpts.Target);
6988
}
7089

7190
SourceFileKind CompilerInvocation::getSourceFileKind() const {
@@ -562,7 +581,7 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts,
562581
if (const Arg *A = Args.getLastArg(OPT_resource_dir))
563582
Opts.RuntimeResourcePath = A->getValue();
564583

565-
Opts.SkipRuntimeLibraryImportPath |= Args.hasArg(OPT_nostdimport);
584+
Opts.SkipRuntimeLibraryImportPaths |= Args.hasArg(OPT_nostdimport);
566585

567586
// Opts.RuntimeIncludePath is set by calls to
568587
// setRuntimeIncludePath() or setMainExecutablePath().
@@ -1279,7 +1298,7 @@ bool CompilerInvocation::parseArgs(
12791298
return true;
12801299
}
12811300

1282-
updateRuntimeLibraryPath(SearchPathOpts, LangOpts.Target);
1301+
updateRuntimeLibraryPaths(SearchPathOpts, LangOpts.Target);
12831302

12841303
return false;
12851304
}

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -278,24 +278,35 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
278278
}
279279
}
280280

281-
// If we're not allowed to look in the runtime library import path, stop.
282-
if (Ctx.SearchPathOpts.SkipRuntimeLibraryImportPath)
283-
return false;
284-
285-
// Search the runtime import path.
281+
// Search the runtime import paths.
286282
isFramework = false;
287-
currPath = Ctx.SearchPathOpts.RuntimeLibraryImportPath;
288-
if (Ctx.LangOpts.Target.isOSDarwin()) {
289-
// Apple platforms always use architecture-specific files within a
290-
// .swiftmodule directory for the stdlib.
291-
llvm::sys::path::append(currPath, fileNames.module.str());
292-
return findTargetSpecificModuleFiles().getValueOr(false);
283+
284+
// Apple platforms always use target-specific files within a
285+
// .swiftmodule directory for the stdlib; non-Apple platforms
286+
// always use single-architecture swiftmodules.
287+
// We could move the `if` outside of the `for` instead of inside,
288+
// but I/O will be so slow that we won't notice the difference,
289+
// so it's not worth the code duplication.
290+
bool hasTargetSpecificRuntimeModules = Ctx.LangOpts.Target.isOSDarwin();
291+
292+
for (auto RuntimeLibraryImportPath :
293+
Ctx.SearchPathOpts.RuntimeLibraryImportPaths) {
294+
currPath = RuntimeLibraryImportPath;
295+
if (hasTargetSpecificRuntimeModules) {
296+
llvm::sys::path::append(currPath, fileNames.module.str());
297+
if (auto outcome = findTargetSpecificModuleFiles())
298+
return *outcome;
299+
} else {
300+
auto result = findModuleFilesInDirectory(moduleID, currPath,
301+
fileNames.module.str(),
302+
fileNames.moduleDoc.str(),
303+
moduleBuffer, moduleDocBuffer);
304+
if (!result)
305+
return true;
306+
}
293307
}
294-
// Non-Apple platforms always use single-architecture swiftmodules.
295-
return !findModuleFilesInDirectory(moduleID, currPath,
296-
fileNames.module.str(),
297-
fileNames.moduleDoc.str(),
298-
moduleBuffer, moduleDocBuffer);
308+
309+
return false;
299310
}
300311

301312
static std::pair<StringRef, clang::VersionTuple>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/// Tests the fallback behavior for runtime library import paths. These should
2+
/// prefer the resource directory, but fall back to the SDK.
3+
4+
// Assumption: We build the standard library with the compiler, so the default
5+
// resource directory will contain a swiftmodule for the standard library.
6+
7+
// %t/good-sdk contains a loadable standard library.
8+
// RUN: %empty-directory(%t/good-sdk/usr/lib/swift)
9+
// RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/good-sdk/usr/lib/swift/Swift.swiftmodule
10+
11+
// %t/bad-sdk contains an invalid standard library that cannot be loaded.
12+
// RUN: %empty-directory(%t/bad-sdk/usr/lib/swift/Swift.swiftmodule)
13+
// RUN: touch %t/bad-sdk/usr/lib/swift/Swift.swiftmodule/garbage-garbage-garbage.swiftmodule
14+
15+
// %t/empty-toolchain does not contain a standard library.
16+
// RUN: %empty-directory(%t/empty-toolchain/usr/lib/swift)
17+
18+
// FIXME: Until we have private imports, we need SwiftShims in the toolchain.
19+
// RUN: cp -r %test-resource-dir/shims %t/empty-toolchain/usr/lib/swift/shims
20+
21+
// If the compiler's resource directory does not contain a runtime swiftmodule,
22+
// we should fall back to the SDK.
23+
24+
// RUN: %empty-directory(%t/mcp)
25+
// RUN: %target-swift-frontend(mock-sdk: -sdk %t/good-sdk) -resource-dir %t/empty-toolchain/usr/lib/swift -module-cache-path %t/mcp -typecheck -verify %s
26+
27+
// If the compiler's resource directory *does* contain a runtime swiftmodule, we
28+
// should *not* use the one in the SDK. (We assume that the resource directory
29+
// built with this compiler does contain a standard library.)
30+
31+
// RUN: %empty-directory(%t/mcp)
32+
// RUN: %target-swift-frontend(mock-sdk: -sdk %t/bad-sdk) -module-cache-path %t/mcp -typecheck -verify %s
33+
34+
// If neither the resource directory nor the SDK contains a runtime swiftmodule,
35+
// loading should fail. This just proves that we aren't getting runtime imports
36+
// some other way.
37+
38+
// FIXME: We can't properly test this on a non-Darwin platform because we'll get
39+
// the same error message for "unloadable standard library" and "no standard
40+
// library". (SR-10097)
41+
// REQUIRES: objc_interop
42+
43+
// RUN: %empty-directory(%t/mcp)
44+
// RUN: not %target-swift-frontend(mock-sdk: -sdk %t/bad-sdk) -resource-dir %t/empty-toolchain/usr/lib/swift -module-cache-path %t/mcp -typecheck %s 2>&1 | %FileCheck %s
45+
// CHECK: error: could not find module 'Swift' for target '{{.*}}'; found: garbage-garbage-garbage
46+
47+
let x: Int = 1

test/lit.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ else:
310310
resource_dir_opt = ""
311311
stdlib_resource_dir_opt = resource_dir_opt
312312
sourcekitd_framework_dir = config.swift_lib_dir
313+
config.substitutions.append( ('%test-resource-dir', test_resource_dir) )
313314
lit_config.note('Using resource dir: ' + test_resource_dir)
314315

315316
# Parse the variant triple.

0 commit comments

Comments
 (0)