Skip to content

Commit dd9eae4

Browse files
authored
Merge pull request #25764 from brentdax/oops-i-linked-it-again-5.1
[5.1] Look up runtime libraries in SDK (#25740)
2 parents b4f072f + d06cfb2 commit dd9eae4

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
@@ -1058,16 +1058,17 @@ ToolChain::constructInvocation(const StaticLinkJobAction &job,
10581058

10591059
void ToolChain::addPathEnvironmentVariableIfNeeded(
10601060
Job::EnvironmentVector &env, const char *name, const char *separator,
1061-
options::ID optionID, const ArgList &args, StringRef extraEntry) const {
1061+
options::ID optionID, const ArgList &args,
1062+
ArrayRef<std::string> extraEntries) const {
10621063
auto linkPathOptions = args.filtered(optionID);
1063-
if (linkPathOptions.begin() == linkPathOptions.end() && extraEntry.empty())
1064+
if (linkPathOptions.begin() == linkPathOptions.end() && extraEntries.empty())
10641065
return;
10651066

10661067
std::string newPaths;
10671068
interleave(linkPathOptions,
10681069
[&](const Arg *arg) { newPaths.append(arg->getValue()); },
10691070
[&] { newPaths.append(separator); });
1070-
if (!extraEntry.empty()) {
1071+
for (auto extraEntry : extraEntries) {
10711072
if (!newPaths.empty())
10721073
newPaths.append(separator);
10731074
newPaths.append(extraEntry.data(), extraEntry.size());
@@ -1091,7 +1092,7 @@ void ToolChain::getClangLibraryPath(const ArgList &Args,
10911092
SmallString<128> &LibPath) const {
10921093
const llvm::Triple &T = getTriple();
10931094

1094-
getRuntimeLibraryPath(LibPath, Args, /*Shared=*/true);
1095+
getResourceDirPath(LibPath, Args, /*Shared=*/true);
10951096
// Remove platform name.
10961097
llvm::sys::path::remove_filename(LibPath);
10971098
llvm::sys::path::append(LibPath, "clang", "lib",
@@ -1101,27 +1102,41 @@ void ToolChain::getClangLibraryPath(const ArgList &Args,
11011102

11021103
/// Get the runtime library link path, which is platform-specific and found
11031104
/// relative to the compiler.
1104-
void ToolChain::getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
1105-
const llvm::opt::ArgList &args,
1106-
bool shared) const {
1105+
void ToolChain::getResourceDirPath(SmallVectorImpl<char> &resourceDirPath,
1106+
const llvm::opt::ArgList &args,
1107+
bool shared) const {
11071108
// FIXME: Duplicated from CompilerInvocation, but in theory the runtime
11081109
// library link path and the standard library module import path don't
11091110
// need to be the same.
11101111
if (const Arg *A = args.getLastArg(options::OPT_resource_dir)) {
11111112
StringRef value = A->getValue();
1112-
runtimeLibPath.append(value.begin(), value.end());
1113+
resourceDirPath.append(value.begin(), value.end());
11131114
} else {
11141115
auto programPath = getDriver().getSwiftProgramPath();
1115-
runtimeLibPath.append(programPath.begin(), programPath.end());
1116-
llvm::sys::path::remove_filename(runtimeLibPath); // remove /swift
1117-
llvm::sys::path::remove_filename(runtimeLibPath); // remove /bin
1118-
llvm::sys::path::append(runtimeLibPath, "lib",
1116+
resourceDirPath.append(programPath.begin(), programPath.end());
1117+
llvm::sys::path::remove_filename(resourceDirPath); // remove /swift
1118+
llvm::sys::path::remove_filename(resourceDirPath); // remove /bin
1119+
llvm::sys::path::append(resourceDirPath, "lib",
11191120
shared ? "swift" : "swift_static");
11201121
}
1121-
llvm::sys::path::append(runtimeLibPath,
1122+
llvm::sys::path::append(resourceDirPath,
11221123
getPlatformNameForTriple(getTriple()));
11231124
}
11241125

1126+
void ToolChain::getRuntimeLibraryPaths(SmallVectorImpl<std::string> &runtimeLibPaths,
1127+
const llvm::opt::ArgList &args,
1128+
StringRef SDKPath, bool shared) const {
1129+
SmallString<128> scratchPath;
1130+
getResourceDirPath(scratchPath, args, shared);
1131+
runtimeLibPaths.push_back(scratchPath.str());
1132+
1133+
if (!SDKPath.empty()) {
1134+
scratchPath = SDKPath;
1135+
llvm::sys::path::append(scratchPath, "usr", "lib", "swift");
1136+
runtimeLibPaths.push_back(scratchPath.str());
1137+
}
1138+
}
1139+
11251140
bool ToolChain::sanitizerRuntimeLibExists(const ArgList &args,
11261141
StringRef sanitizerName,
11271142
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
@@ -100,28 +100,26 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
100100
Arguments.push_back(context.Args.MakeArgString(Target));
101101
}
102102

103-
SmallString<128> SharedRuntimeLibPath;
104-
getRuntimeLibraryPath(SharedRuntimeLibPath, context.Args,
105-
/*Shared=*/true);
106-
107-
// Link the standard library.
108-
Arguments.push_back("-L");
109-
if (context.Args.hasFlag(options::OPT_static_stdlib,
110-
options::OPT_no_static_stdlib, false)) {
111-
SmallString<128> StaticRuntimeLibPath;
112-
getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args,
113-
/*Shared=*/false);
103+
bool wantsStaticStdlib =
104+
context.Args.hasFlag(options::OPT_static_stdlib,
105+
options::OPT_no_static_stdlib, false);
114106

107+
SmallVector<std::string, 4> RuntimeLibPaths;
108+
getRuntimeLibraryPaths(RuntimeLibPaths, context.Args, context.OI.SDKPath,
109+
/*Shared=*/!wantsStaticStdlib);
110+
111+
for (auto path : RuntimeLibPaths) {
112+
Arguments.push_back("-L");
115113
// Since Windows has separate libraries per architecture, link against the
116114
// architecture specific version of the static library.
117-
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath + "/" +
118-
getTriple().getArchName()));
119-
} else {
120-
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath + "/" +
115+
Arguments.push_back(context.Args.MakeArgString(path + "/" +
121116
getTriple().getArchName()));
122117
}
123118

124-
SmallString<128> swiftrtPath = SharedRuntimeLibPath;
119+
SmallString<128> SharedResourceDirPath;
120+
getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);
121+
122+
SmallString<128> swiftrtPath = SharedResourceDirPath;
125123
llvm::sys::path::append(swiftrtPath,
126124
swift::getMajorArchitectureName(getTriple()));
127125
llvm::sys::path::append(swiftrtPath, "swiftrt.obj");
@@ -156,7 +154,7 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
156154
}
157155

158156
if (context.Args.hasArg(options::OPT_profile_generate)) {
159-
SmallString<128> LibProfile(SharedRuntimeLibPath);
157+
SmallString<128> LibProfile(SharedResourceDirPath);
160158
llvm::sys::path::remove_filename(LibProfile); // remove platform name
161159
llvm::sys::path::append(LibProfile, "clang", "lib");
162160

0 commit comments

Comments
 (0)