Skip to content

Commit b818b44

Browse files
authored
Look up runtime libraries in SDK (#25740)
In #23175, we started looking in the SDK for swiftmodules, but we want to look for the dylibs there too. Fixes <rdar://problem/52059706>.
1 parent 9f9f5ea commit b818b44

File tree

7 files changed

+123
-94
lines changed

7 files changed

+123
-94
lines changed

include/swift/Driver/ToolChain.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,17 +194,23 @@ class ToolChain {
194194
file_types::ID InputType,
195195
const char *PrefixArgument = nullptr) const;
196196

197-
/// Get the runtime library link path, which is platform-specific and found
197+
/// Get the resource dir link path, which is platform-specific and found
198198
/// relative to the compiler.
199-
void getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
200-
const llvm::opt::ArgList &args, bool shared) const;
199+
void getResourceDirPath(SmallVectorImpl<char> &runtimeLibPath,
200+
const llvm::opt::ArgList &args, bool shared) const;
201+
202+
/// Get the runtime library link paths, which typically include the resource
203+
/// dir path and the SDK.
204+
void getRuntimeLibraryPaths(SmallVectorImpl<std::string> &runtimeLibPaths,
205+
const llvm::opt::ArgList &args,
206+
StringRef SDKPath, bool shared) const;
201207

202208
void addPathEnvironmentVariableIfNeeded(Job::EnvironmentVector &env,
203209
const char *name,
204210
const char *separator,
205211
options::ID optionID,
206212
const llvm::opt::ArgList &args,
207-
StringRef extraEntry = "") const;
213+
ArrayRef<std::string> extraEntries = {}) const;
208214

209215
/// Specific toolchains should override this to provide additional conditions
210216
/// under which the compiler invocation should be written into debug info. For

lib/Driver/DarwinToolChains.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,13 @@ toolchains::Darwin::constructInvocation(const InterpretJobAction &job,
7272
const JobContext &context) const {
7373
InvocationInfo II = ToolChain::constructInvocation(job, context);
7474

75-
SmallString<128> runtimeLibraryPath;
76-
getRuntimeLibraryPath(runtimeLibraryPath, context.Args, /*Shared=*/true);
75+
SmallVector<std::string, 4> runtimeLibraryPaths;
76+
getRuntimeLibraryPaths(runtimeLibraryPaths, context.Args, context.OI.SDKPath,
77+
/*Shared=*/true);
7778

7879
addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_LIBRARY_PATH",
7980
":", options::OPT_L, context.Args,
80-
runtimeLibraryPath);
81+
runtimeLibraryPaths);
8182
addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_FRAMEWORK_PATH",
8283
":", options::OPT_F, context.Args);
8384
// FIXME: Add options::OPT_Fsystem paths to DYLD_FRAMEWORK_PATH as well.
@@ -390,13 +391,10 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
390391
Arguments.push_back("-arch");
391392
Arguments.push_back(context.Args.MakeArgString(getTriple().getArchName()));
392393

393-
// Add the runtime library link path, which is platform-specific and found
394-
// relative to the compiler.
395-
SmallString<128> RuntimeLibPath;
396-
getRuntimeLibraryPath(RuntimeLibPath, context.Args, /*Shared=*/true);
397-
398394
// Link compatibility libraries, if we're deploying back to OSes that
399395
// have an older Swift runtime.
396+
SmallString<128> SharedResourceDirPath;
397+
getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);
400398
Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
401399

402400
if (context.Args.hasArg(options::OPT_runtime_compatibility_version)) {
@@ -418,7 +416,7 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
418416
if (*runtimeCompatibilityVersion <= llvm::VersionTuple(5, 0)) {
419417
// Swift 5.0 compatibility library
420418
SmallString<128> BackDeployLib;
421-
BackDeployLib.append(RuntimeLibPath);
419+
BackDeployLib.append(SharedResourceDirPath);
422420
llvm::sys::path::append(BackDeployLib, "libswiftCompatibility50.a");
423421

424422
if (llvm::sys::fs::exists(BackDeployLib)) {
@@ -433,7 +431,7 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
433431
if (*runtimeCompatibilityVersion <= llvm::VersionTuple(5, 0)) {
434432
// Swift 5.0 dynamic replacement compatibility library.
435433
SmallString<128> BackDeployLib;
436-
BackDeployLib.append(RuntimeLibPath);
434+
BackDeployLib.append(SharedResourceDirPath);
437435
llvm::sys::path::append(BackDeployLib,
438436
"libswiftCompatibilityDynamicReplacements.a");
439437

@@ -444,23 +442,34 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
444442
}
445443
}
446444

445+
bool wantsStaticStdlib =
446+
context.Args.hasFlag(options::OPT_static_stdlib,
447+
options::OPT_no_static_stdlib, false);
448+
449+
SmallVector<std::string, 4> RuntimeLibPaths;
450+
getRuntimeLibraryPaths(RuntimeLibPaths, context.Args,
451+
context.OI.SDKPath, /*Shared=*/!wantsStaticStdlib);
452+
453+
// Add the runtime library link path, which is platform-specific and found
454+
// relative to the compiler.
455+
for (auto path : RuntimeLibPaths) {
456+
Arguments.push_back("-L");
457+
Arguments.push_back(context.Args.MakeArgString(path));
458+
}
459+
447460
// Link the standard library.
448-
Arguments.push_back("-L");
449-
if (context.Args.hasFlag(options::OPT_static_stdlib,
450-
options::OPT_no_static_stdlib, false)) {
451-
SmallString<128> StaticRuntimeLibPath;
452-
getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args, /*Shared=*/false);
453-
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath));
461+
if (wantsStaticStdlib) {
454462
Arguments.push_back("-lc++");
455463
Arguments.push_back("-framework");
456464
Arguments.push_back("Foundation");
457465
Arguments.push_back("-force_load_swift_libs");
458466
} else {
459-
Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath));
460467
// FIXME: We probably shouldn't be adding an rpath here unless we know ahead
461468
// of time the standard library won't be copied. SR-1967
462-
Arguments.push_back("-rpath");
463-
Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath));
469+
for (auto path : RuntimeLibPaths) {
470+
Arguments.push_back("-rpath");
471+
Arguments.push_back(context.Args.MakeArgString(path));
472+
}
464473
}
465474

466475
if (context.Args.hasArg(options::OPT_profile_generate)) {

lib/Driver/ToolChains.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,16 +1110,17 @@ ToolChain::constructInvocation(const StaticLinkJobAction &job,
11101110

11111111
void ToolChain::addPathEnvironmentVariableIfNeeded(
11121112
Job::EnvironmentVector &env, const char *name, const char *separator,
1113-
options::ID optionID, const ArgList &args, StringRef extraEntry) const {
1113+
options::ID optionID, const ArgList &args,
1114+
ArrayRef<std::string> extraEntries) const {
11141115
auto linkPathOptions = args.filtered(optionID);
1115-
if (linkPathOptions.begin() == linkPathOptions.end() && extraEntry.empty())
1116+
if (linkPathOptions.begin() == linkPathOptions.end() && extraEntries.empty())
11161117
return;
11171118

11181119
std::string newPaths;
11191120
interleave(linkPathOptions,
11201121
[&](const Arg *arg) { newPaths.append(arg->getValue()); },
11211122
[&] { newPaths.append(separator); });
1122-
if (!extraEntry.empty()) {
1123+
for (auto extraEntry : extraEntries) {
11231124
if (!newPaths.empty())
11241125
newPaths.append(separator);
11251126
newPaths.append(extraEntry.data(), extraEntry.size());
@@ -1143,7 +1144,7 @@ void ToolChain::getClangLibraryPath(const ArgList &Args,
11431144
SmallString<128> &LibPath) const {
11441145
const llvm::Triple &T = getTriple();
11451146

1146-
getRuntimeLibraryPath(LibPath, Args, /*Shared=*/true);
1147+
getResourceDirPath(LibPath, Args, /*Shared=*/true);
11471148
// Remove platform name.
11481149
llvm::sys::path::remove_filename(LibPath);
11491150
llvm::sys::path::append(LibPath, "clang", "lib",
@@ -1153,27 +1154,41 @@ void ToolChain::getClangLibraryPath(const ArgList &Args,
11531154

11541155
/// Get the runtime library link path, which is platform-specific and found
11551156
/// relative to the compiler.
1156-
void ToolChain::getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
1157-
const llvm::opt::ArgList &args,
1158-
bool shared) const {
1157+
void ToolChain::getResourceDirPath(SmallVectorImpl<char> &resourceDirPath,
1158+
const llvm::opt::ArgList &args,
1159+
bool shared) const {
11591160
// FIXME: Duplicated from CompilerInvocation, but in theory the runtime
11601161
// library link path and the standard library module import path don't
11611162
// need to be the same.
11621163
if (const Arg *A = args.getLastArg(options::OPT_resource_dir)) {
11631164
StringRef value = A->getValue();
1164-
runtimeLibPath.append(value.begin(), value.end());
1165+
resourceDirPath.append(value.begin(), value.end());
11651166
} else {
11661167
auto programPath = getDriver().getSwiftProgramPath();
1167-
runtimeLibPath.append(programPath.begin(), programPath.end());
1168-
llvm::sys::path::remove_filename(runtimeLibPath); // remove /swift
1169-
llvm::sys::path::remove_filename(runtimeLibPath); // remove /bin
1170-
llvm::sys::path::append(runtimeLibPath, "lib",
1168+
resourceDirPath.append(programPath.begin(), programPath.end());
1169+
llvm::sys::path::remove_filename(resourceDirPath); // remove /swift
1170+
llvm::sys::path::remove_filename(resourceDirPath); // remove /bin
1171+
llvm::sys::path::append(resourceDirPath, "lib",
11711172
shared ? "swift" : "swift_static");
11721173
}
1173-
llvm::sys::path::append(runtimeLibPath,
1174+
llvm::sys::path::append(resourceDirPath,
11741175
getPlatformNameForTriple(getTriple()));
11751176
}
11761177

1178+
void ToolChain::getRuntimeLibraryPaths(SmallVectorImpl<std::string> &runtimeLibPaths,
1179+
const llvm::opt::ArgList &args,
1180+
StringRef SDKPath, bool shared) const {
1181+
SmallString<128> scratchPath;
1182+
getResourceDirPath(scratchPath, args, shared);
1183+
runtimeLibPaths.push_back(scratchPath.str());
1184+
1185+
if (!SDKPath.empty()) {
1186+
scratchPath = SDKPath;
1187+
llvm::sys::path::append(scratchPath, "usr", "lib", "swift");
1188+
runtimeLibPaths.push_back(scratchPath.str());
1189+
}
1190+
}
1191+
11771192
bool ToolChain::sanitizerRuntimeLibExists(const ArgList &args,
11781193
StringRef sanitizerName,
11791194
bool shared) const {

lib/Driver/UnixToolChains.cpp

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ toolchains::GenericUnix::constructInvocation(const InterpretJobAction &job,
5151
const JobContext &context) const {
5252
InvocationInfo II = ToolChain::constructInvocation(job, context);
5353

54-
SmallString<128> runtimeLibraryPath;
55-
getRuntimeLibraryPath(runtimeLibraryPath, context.Args,
56-
/*Shared=*/true);
54+
SmallVector<std::string, 4> runtimeLibraryPaths;
55+
getRuntimeLibraryPaths(runtimeLibraryPaths, context.Args, context.OI.SDKPath,
56+
/*Shared=*/true);
5757

5858
addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "LD_LIBRARY_PATH",
5959
":", options::OPT_L, context.Args,
60-
runtimeLibraryPath);
60+
runtimeLibraryPaths);
6161
return II;
6262
}
6363

@@ -190,24 +190,25 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
190190
staticStdlib = true;
191191
}
192192

193-
SmallString<128> SharedRuntimeLibPath;
194-
getRuntimeLibraryPath(SharedRuntimeLibPath, context.Args, /*Shared=*/true);
193+
SmallVector<std::string, 4> RuntimeLibPaths;
194+
getRuntimeLibraryPaths(RuntimeLibPaths, context.Args, context.OI.SDKPath,
195+
/*Shared=*/!(staticExecutable || staticStdlib));
195196

196-
SmallString<128> StaticRuntimeLibPath;
197-
getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args, /*Shared=*/false);
198-
199-
// Add the runtime library link path, which is platform-specific and found
200-
// relative to the compiler.
201197
if (!(staticExecutable || staticStdlib) && shouldProvideRPathToLinker()) {
202198
// FIXME: We probably shouldn't be adding an rpath here unless we know
203199
// ahead of time the standard library won't be copied.
204-
Arguments.push_back("-Xlinker");
205-
Arguments.push_back("-rpath");
206-
Arguments.push_back("-Xlinker");
207-
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath));
200+
for (auto path : RuntimeLibPaths) {
201+
Arguments.push_back("-Xlinker");
202+
Arguments.push_back("-rpath");
203+
Arguments.push_back("-Xlinker");
204+
Arguments.push_back(context.Args.MakeArgString(path));
205+
}
208206
}
209207

210-
SmallString<128> swiftrtPath = SharedRuntimeLibPath;
208+
SmallString<128> SharedResourceDirPath;
209+
getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);
210+
211+
SmallString<128> swiftrtPath = SharedResourceDirPath;
211212
llvm::sys::path::append(swiftrtPath,
212213
swift::getMajorArchitectureName(getTriple()));
213214
llvm::sys::path::append(swiftrtPath, "swiftrt.o");
@@ -239,36 +240,34 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
239240
Twine("@") + OutputInfo.getPrimaryOutputFilename()));
240241
}
241242

242-
// Link the standard library.
243-
Arguments.push_back("-L");
243+
// Add the runtime library link paths.
244+
for (auto path : RuntimeLibPaths) {
245+
Arguments.push_back("-L");
246+
Arguments.push_back(context.Args.MakeArgString(path));
247+
}
244248

245-
if (staticExecutable) {
246-
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath));
249+
// Link the standard library. In two paths, we do this using a .lnk file;
250+
// if we're going that route, we'll set `linkFilePath` to the path to that
251+
// file.
252+
SmallString<128> linkFilePath;
253+
getResourceDirPath(linkFilePath, context.Args, /*Shared=*/false);
247254

248-
SmallString<128> linkFilePath = StaticRuntimeLibPath;
255+
if (staticExecutable) {
249256
llvm::sys::path::append(linkFilePath, "static-executable-args.lnk");
250-
auto linkFile = linkFilePath.str();
251-
252-
if (llvm::sys::fs::is_regular_file(linkFile)) {
253-
Arguments.push_back(context.Args.MakeArgString(Twine("@") + linkFile));
254-
} else {
255-
llvm::report_fatal_error(
256-
"-static-executable not supported on this platform");
257-
}
258257
} else if (staticStdlib) {
259-
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath));
260-
261-
SmallString<128> linkFilePath = StaticRuntimeLibPath;
262258
llvm::sys::path::append(linkFilePath, "static-stdlib-args.lnk");
259+
} else {
260+
linkFilePath.clear();
261+
Arguments.push_back("-lswiftCore");
262+
}
263+
264+
if (!linkFilePath.empty()) {
263265
auto linkFile = linkFilePath.str();
264266
if (llvm::sys::fs::is_regular_file(linkFile)) {
265267
Arguments.push_back(context.Args.MakeArgString(Twine("@") + linkFile));
266268
} else {
267269
llvm::report_fatal_error(linkFile + " not found");
268270
}
269-
} else {
270-
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath));
271-
Arguments.push_back("-lswiftCore");
272271
}
273272

274273
// Explicitly pass the target to the linker
@@ -289,7 +288,7 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
289288
}
290289

291290
if (context.Args.hasArg(options::OPT_profile_generate)) {
292-
SmallString<128> LibProfile(SharedRuntimeLibPath);
291+
SmallString<128> LibProfile(SharedResourceDirPath);
293292
llvm::sys::path::remove_filename(LibProfile); // remove platform name
294293
llvm::sys::path::append(LibProfile, "clang", "lib");
295294

lib/Driver/WindowsToolChains.cpp

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -108,28 +108,26 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
108108
// driver rather than the `clang-cl` driver.
109109
Arguments.push_back("-nostartfiles");
110110

111-
SmallString<128> SharedRuntimeLibPath;
112-
getRuntimeLibraryPath(SharedRuntimeLibPath, context.Args,
113-
/*Shared=*/true);
114-
115-
// Link the standard library.
116-
Arguments.push_back("-L");
117-
if (context.Args.hasFlag(options::OPT_static_stdlib,
118-
options::OPT_no_static_stdlib, false)) {
119-
SmallString<128> StaticRuntimeLibPath;
120-
getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args,
121-
/*Shared=*/false);
111+
bool wantsStaticStdlib =
112+
context.Args.hasFlag(options::OPT_static_stdlib,
113+
options::OPT_no_static_stdlib, false);
122114

115+
SmallVector<std::string, 4> RuntimeLibPaths;
116+
getRuntimeLibraryPaths(RuntimeLibPaths, context.Args, context.OI.SDKPath,
117+
/*Shared=*/!wantsStaticStdlib);
118+
119+
for (auto path : RuntimeLibPaths) {
120+
Arguments.push_back("-L");
123121
// Since Windows has separate libraries per architecture, link against the
124122
// architecture specific version of the static library.
125-
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath + "/" +
126-
getTriple().getArchName()));
127-
} else {
128-
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath + "/" +
123+
Arguments.push_back(context.Args.MakeArgString(path + "/" +
129124
getTriple().getArchName()));
130125
}
131126

132-
SmallString<128> swiftrtPath = SharedRuntimeLibPath;
127+
SmallString<128> SharedResourceDirPath;
128+
getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);
129+
130+
SmallString<128> swiftrtPath = SharedResourceDirPath;
133131
llvm::sys::path::append(swiftrtPath,
134132
swift::getMajorArchitectureName(getTriple()));
135133
llvm::sys::path::append(swiftrtPath, "swiftrt.obj");
@@ -164,7 +162,7 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
164162
}
165163

166164
if (context.Args.hasArg(options::OPT_profile_generate)) {
167-
SmallString<128> LibProfile(SharedRuntimeLibPath);
165+
SmallString<128> LibProfile(SharedResourceDirPath);
168166
llvm::sys::path::remove_filename(LibProfile); // remove platform name
169167
llvm::sys::path::append(LibProfile, "clang", "lib");
170168

0 commit comments

Comments
 (0)