Skip to content

Look up runtime libraries in SDK #25740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions include/swift/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,17 +194,23 @@ class ToolChain {
file_types::ID InputType,
const char *PrefixArgument = nullptr) const;

/// Get the runtime library link path, which is platform-specific and found
/// Get the resource dir link path, which is platform-specific and found
/// relative to the compiler.
void getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
const llvm::opt::ArgList &args, bool shared) const;
void getResourceDirPath(SmallVectorImpl<char> &runtimeLibPath,
const llvm::opt::ArgList &args, bool shared) const;

/// Get the runtime library link paths, which typically include the resource
/// dir path and the SDK.
void getRuntimeLibraryPaths(SmallVectorImpl<std::string> &runtimeLibPaths,
const llvm::opt::ArgList &args,
StringRef SDKPath, bool shared) const;

void addPathEnvironmentVariableIfNeeded(Job::EnvironmentVector &env,
const char *name,
const char *separator,
options::ID optionID,
const llvm::opt::ArgList &args,
StringRef extraEntry = "") const;
ArrayRef<std::string> extraEntries = {}) const;

/// Specific toolchains should override this to provide additional conditions
/// under which the compiler invocation should be written into debug info. For
Expand Down
47 changes: 28 additions & 19 deletions lib/Driver/DarwinToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ toolchains::Darwin::constructInvocation(const InterpretJobAction &job,
const JobContext &context) const {
InvocationInfo II = ToolChain::constructInvocation(job, context);

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

addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_LIBRARY_PATH",
":", options::OPT_L, context.Args,
runtimeLibraryPath);
runtimeLibraryPaths);
addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_FRAMEWORK_PATH",
":", options::OPT_F, context.Args);
// FIXME: Add options::OPT_Fsystem paths to DYLD_FRAMEWORK_PATH as well.
Expand Down Expand Up @@ -390,13 +391,10 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
Arguments.push_back("-arch");
Arguments.push_back(context.Args.MakeArgString(getTriple().getArchName()));

// Add the runtime library link path, which is platform-specific and found
// relative to the compiler.
SmallString<128> RuntimeLibPath;
getRuntimeLibraryPath(RuntimeLibPath, context.Args, /*Shared=*/true);

// Link compatibility libraries, if we're deploying back to OSes that
// have an older Swift runtime.
SmallString<128> SharedResourceDirPath;
getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);
Optional<llvm::VersionTuple> runtimeCompatibilityVersion;

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

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

Expand All @@ -444,23 +442,34 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
}
}

bool wantsStaticStdlib =
context.Args.hasFlag(options::OPT_static_stdlib,
options::OPT_no_static_stdlib, false);

SmallVector<std::string, 4> RuntimeLibPaths;
getRuntimeLibraryPaths(RuntimeLibPaths, context.Args,
context.OI.SDKPath, /*Shared=*/!wantsStaticStdlib);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apple platforms don't support the static stdlib anymore, so you can probably just drop this.

Copy link
Contributor Author

@beccadax beccadax Jun 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this properly (i.e. with good diagnostics) will require a little more work than I want to do right now. I've filed https://bugs.swift.org/browse/SR-11015 to track the idea.


// Add the runtime library link path, which is platform-specific and found
// relative to the compiler.
for (auto path : RuntimeLibPaths) {
Arguments.push_back("-L");
Arguments.push_back(context.Args.MakeArgString(path));
}

// Link the standard library.
Arguments.push_back("-L");
if (context.Args.hasFlag(options::OPT_static_stdlib,
options::OPT_no_static_stdlib, false)) {
SmallString<128> StaticRuntimeLibPath;
getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args, /*Shared=*/false);
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath));
if (wantsStaticStdlib) {
Arguments.push_back("-lc++");
Arguments.push_back("-framework");
Arguments.push_back("Foundation");
Arguments.push_back("-force_load_swift_libs");
} else {
Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath));
// FIXME: We probably shouldn't be adding an rpath here unless we know ahead
// of time the standard library won't be copied. SR-1967
Arguments.push_back("-rpath");
Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath));
for (auto path : RuntimeLibPaths) {
Arguments.push_back("-rpath");
Arguments.push_back(context.Args.MakeArgString(path));
}
}

if (context.Args.hasArg(options::OPT_profile_generate)) {
Expand Down
41 changes: 28 additions & 13 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1110,16 +1110,17 @@ ToolChain::constructInvocation(const StaticLinkJobAction &job,

void ToolChain::addPathEnvironmentVariableIfNeeded(
Job::EnvironmentVector &env, const char *name, const char *separator,
options::ID optionID, const ArgList &args, StringRef extraEntry) const {
options::ID optionID, const ArgList &args,
ArrayRef<std::string> extraEntries) const {
auto linkPathOptions = args.filtered(optionID);
if (linkPathOptions.begin() == linkPathOptions.end() && extraEntry.empty())
if (linkPathOptions.begin() == linkPathOptions.end() && extraEntries.empty())
return;

std::string newPaths;
interleave(linkPathOptions,
[&](const Arg *arg) { newPaths.append(arg->getValue()); },
[&] { newPaths.append(separator); });
if (!extraEntry.empty()) {
for (auto extraEntry : extraEntries) {
if (!newPaths.empty())
newPaths.append(separator);
newPaths.append(extraEntry.data(), extraEntry.size());
Expand All @@ -1143,7 +1144,7 @@ void ToolChain::getClangLibraryPath(const ArgList &Args,
SmallString<128> &LibPath) const {
const llvm::Triple &T = getTriple();

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

/// Get the runtime library link path, which is platform-specific and found
/// relative to the compiler.
void ToolChain::getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
const llvm::opt::ArgList &args,
bool shared) const {
void ToolChain::getResourceDirPath(SmallVectorImpl<char> &resourceDirPath,
const llvm::opt::ArgList &args,
bool shared) const {
// FIXME: Duplicated from CompilerInvocation, but in theory the runtime
// library link path and the standard library module import path don't
// need to be the same.
if (const Arg *A = args.getLastArg(options::OPT_resource_dir)) {
StringRef value = A->getValue();
runtimeLibPath.append(value.begin(), value.end());
resourceDirPath.append(value.begin(), value.end());
} else {
auto programPath = getDriver().getSwiftProgramPath();
runtimeLibPath.append(programPath.begin(), programPath.end());
llvm::sys::path::remove_filename(runtimeLibPath); // remove /swift
llvm::sys::path::remove_filename(runtimeLibPath); // remove /bin
llvm::sys::path::append(runtimeLibPath, "lib",
resourceDirPath.append(programPath.begin(), programPath.end());
llvm::sys::path::remove_filename(resourceDirPath); // remove /swift
llvm::sys::path::remove_filename(resourceDirPath); // remove /bin
llvm::sys::path::append(resourceDirPath, "lib",
shared ? "swift" : "swift_static");
}
llvm::sys::path::append(runtimeLibPath,
llvm::sys::path::append(resourceDirPath,
getPlatformNameForTriple(getTriple()));
}

void ToolChain::getRuntimeLibraryPaths(SmallVectorImpl<std::string> &runtimeLibPaths,
const llvm::opt::ArgList &args,
StringRef SDKPath, bool shared) const {
SmallString<128> scratchPath;
getResourceDirPath(scratchPath, args, shared);
runtimeLibPaths.push_back(scratchPath.str());

if (!SDKPath.empty()) {
scratchPath = SDKPath;
llvm::sys::path::append(scratchPath, "usr", "lib", "swift");
runtimeLibPaths.push_back(scratchPath.str());
}
}

bool ToolChain::sanitizerRuntimeLibExists(const ArgList &args,
StringRef sanitizerName,
bool shared) const {
Expand Down
71 changes: 35 additions & 36 deletions lib/Driver/UnixToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ toolchains::GenericUnix::constructInvocation(const InterpretJobAction &job,
const JobContext &context) const {
InvocationInfo II = ToolChain::constructInvocation(job, context);

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

addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "LD_LIBRARY_PATH",
":", options::OPT_L, context.Args,
runtimeLibraryPath);
runtimeLibraryPaths);
return II;
}

Expand Down Expand Up @@ -190,24 +190,25 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
staticStdlib = true;
}

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

SmallString<128> StaticRuntimeLibPath;
getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args, /*Shared=*/false);

// Add the runtime library link path, which is platform-specific and found
// relative to the compiler.
if (!(staticExecutable || staticStdlib) && shouldProvideRPathToLinker()) {
// FIXME: We probably shouldn't be adding an rpath here unless we know
// ahead of time the standard library won't be copied.
Arguments.push_back("-Xlinker");
Arguments.push_back("-rpath");
Arguments.push_back("-Xlinker");
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath));
for (auto path : RuntimeLibPaths) {
Arguments.push_back("-Xlinker");
Arguments.push_back("-rpath");
Arguments.push_back("-Xlinker");
Arguments.push_back(context.Args.MakeArgString(path));
}
}

SmallString<128> swiftrtPath = SharedRuntimeLibPath;
SmallString<128> SharedResourceDirPath;
getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);

SmallString<128> swiftrtPath = SharedResourceDirPath;
llvm::sys::path::append(swiftrtPath,
swift::getMajorArchitectureName(getTriple()));
llvm::sys::path::append(swiftrtPath, "swiftrt.o");
Expand Down Expand Up @@ -239,36 +240,34 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
Twine("@") + OutputInfo.getPrimaryOutputFilename()));
}

// Link the standard library.
Arguments.push_back("-L");
// Add the runtime library link paths.
for (auto path : RuntimeLibPaths) {
Arguments.push_back("-L");
Arguments.push_back(context.Args.MakeArgString(path));
}

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

SmallString<128> linkFilePath = StaticRuntimeLibPath;
if (staticExecutable) {
llvm::sys::path::append(linkFilePath, "static-executable-args.lnk");
auto linkFile = linkFilePath.str();

if (llvm::sys::fs::is_regular_file(linkFile)) {
Arguments.push_back(context.Args.MakeArgString(Twine("@") + linkFile));
} else {
llvm::report_fatal_error(
"-static-executable not supported on this platform");
}
} else if (staticStdlib) {
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath));

SmallString<128> linkFilePath = StaticRuntimeLibPath;
llvm::sys::path::append(linkFilePath, "static-stdlib-args.lnk");
} else {
linkFilePath.clear();
Arguments.push_back("-lswiftCore");
}

if (!linkFilePath.empty()) {
auto linkFile = linkFilePath.str();
if (llvm::sys::fs::is_regular_file(linkFile)) {
Arguments.push_back(context.Args.MakeArgString(Twine("@") + linkFile));
} else {
llvm::report_fatal_error(linkFile + " not found");
}
} else {
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath));
Arguments.push_back("-lswiftCore");
}

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

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

Expand Down
32 changes: 15 additions & 17 deletions lib/Driver/WindowsToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,28 +108,26 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
// driver rather than the `clang-cl` driver.
Arguments.push_back("-nostartfiles");

SmallString<128> SharedRuntimeLibPath;
getRuntimeLibraryPath(SharedRuntimeLibPath, context.Args,
/*Shared=*/true);

// Link the standard library.
Arguments.push_back("-L");
if (context.Args.hasFlag(options::OPT_static_stdlib,
options::OPT_no_static_stdlib, false)) {
SmallString<128> StaticRuntimeLibPath;
getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args,
/*Shared=*/false);
bool wantsStaticStdlib =
context.Args.hasFlag(options::OPT_static_stdlib,
options::OPT_no_static_stdlib, false);

SmallVector<std::string, 4> RuntimeLibPaths;
getRuntimeLibraryPaths(RuntimeLibPaths, context.Args, context.OI.SDKPath,
/*Shared=*/!wantsStaticStdlib);

for (auto path : RuntimeLibPaths) {
Arguments.push_back("-L");
// Since Windows has separate libraries per architecture, link against the
// architecture specific version of the static library.
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath + "/" +
getTriple().getArchName()));
} else {
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath + "/" +
Arguments.push_back(context.Args.MakeArgString(path + "/" +
getTriple().getArchName()));
}

SmallString<128> swiftrtPath = SharedRuntimeLibPath;
SmallString<128> SharedResourceDirPath;
getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);

SmallString<128> swiftrtPath = SharedResourceDirPath;
llvm::sys::path::append(swiftrtPath,
swift::getMajorArchitectureName(getTriple()));
llvm::sys::path::append(swiftrtPath, "swiftrt.obj");
Expand Down Expand Up @@ -164,7 +162,7 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
}

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

Expand Down
Loading