Skip to content

[5.1][Interpreter] Fall back to loading Swift dylibs from /usr/lib/swift on Apple platforms. #24839

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
8 changes: 3 additions & 5 deletions include/swift/AST/SearchPathOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,15 @@ class SearchPathOptions {
/// Path to search for compiler-relative header files.
std::string RuntimeResourcePath;

/// Path to search for compiler-relative stdlib dylibs.
std::string RuntimeLibraryPath;
/// Paths to search for compiler-relative stdlib dylibs, in order of
/// preference.
std::vector<std::string> RuntimeLibraryPaths;

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

/// Don't look in for compiler-provided modules.
bool SkipRuntimeLibraryImportPaths = false;

/// Whether the runtime library path is set to the compiler-relative default.
bool RuntimeLibraryPathIsDefault = true;

/// Return a hash code of any components from these options that should
/// contribute to a Swift Bridging PCH hash.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class CompilerInvocation {

void setMainExecutablePath(StringRef Path);

void setRuntimeResourcePath(StringRef Path, bool IsDefault = false);
void setRuntimeResourcePath(StringRef Path);

void setSDKPath(const std::string &Path);

Expand Down
9 changes: 1 addition & 8 deletions lib/Driver/DarwinToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ using namespace swift;
using namespace swift::driver;
using namespace llvm::opt;

/// The path for Swift libraries in the OS. (Duplicated from Immediate.cpp.
/// Eventually we should consolidate this.)
#define OS_LIBRARY_PATH "/usr/lib/swift"

std::string
toolchains::Darwin::findProgramRelativeToSwiftImpl(StringRef name) const {
StringRef swiftPath = getDriver().getSwiftProgramPath();
Expand Down Expand Up @@ -76,15 +72,12 @@ toolchains::Darwin::constructInvocation(const InterpretJobAction &job,
const JobContext &context) const {
InvocationInfo II = ToolChain::constructInvocation(job, context);

SmallString<128> envValue(OS_LIBRARY_PATH ":");

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

addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_LIBRARY_PATH",
":", options::OPT_L, context.Args,
envValue);
runtimeLibraryPath);
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
14 changes: 9 additions & 5 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
using namespace swift;
using namespace llvm::opt;

/// The path for Swift libraries in the OS on Darwin.
#define DARWIN_OS_LIBRARY_PATH "/usr/lib/swift"

swift::CompilerInvocation::CompilerInvocation() {
setTargetTriple(llvm::sys::getDefaultTargetTriple());
}
Expand All @@ -39,7 +42,7 @@ void CompilerInvocation::setMainExecutablePath(StringRef Path) {
llvm::sys::path::remove_filename(LibPath); // Remove /swift
llvm::sys::path::remove_filename(LibPath); // Remove /bin
llvm::sys::path::append(LibPath, "lib", "swift");
setRuntimeResourcePath(LibPath.str(), /*IsDefault=*/true);
setRuntimeResourcePath(LibPath.str());
}

/// If we haven't explicitly passed -prebuilt-module-cache-path, set it to
Expand All @@ -66,7 +69,10 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
llvm::SmallString<128> LibPath(SearchPathOpts.RuntimeResourcePath);

llvm::sys::path::append(LibPath, getPlatformNameForTriple(Triple));
SearchPathOpts.RuntimeLibraryPath = LibPath.str();
SearchPathOpts.RuntimeLibraryPaths.clear();
SearchPathOpts.RuntimeLibraryPaths.push_back(LibPath.str());
if (Triple.isOSDarwin())
SearchPathOpts.RuntimeLibraryPaths.push_back(DARWIN_OS_LIBRARY_PATH);

// Set up the import paths containing the swiftmodules for the libraries in
// RuntimeLibraryPath.
Expand All @@ -87,11 +93,9 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
}
}

void CompilerInvocation::setRuntimeResourcePath(StringRef Path,
bool IsDefault) {
void CompilerInvocation::setRuntimeResourcePath(StringRef Path) {
SearchPathOpts.RuntimeResourcePath = Path;
updateRuntimeLibraryPaths(SearchPathOpts, LangOpts.Target);
SearchPathOpts.RuntimeLibraryPathIsDefault = IsDefault;
}

void CompilerInvocation::setTargetTriple(StringRef Triple) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Frontend/ParseableInterfaceModuleLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ class ParseableInterfaceModuleLoaderImpl {
}

bool isInResourceDir(StringRef path) {
StringRef resourceDir = ctx.SearchPathOpts.RuntimeLibraryPath;
StringRef resourceDir = ctx.SearchPathOpts.RuntimeResourcePath;
if (resourceDir.empty()) return false;
return path.startswith(resourceDir);
}
Expand Down
18 changes: 17 additions & 1 deletion lib/IRGen/GenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,23 @@ TypeConverter::TypeConverter(IRGenModule &IGM)
if (!doesPlatformUseLegacyLayouts(platformName, archName))
return;

defaultPath.append(IGM.Context.SearchPathOpts.RuntimeLibraryPath);
// Find the first runtime library path that exists.
bool found = false;
for (auto &RuntimeLibraryPath
: IGM.Context.SearchPathOpts.RuntimeLibraryPaths) {
if (llvm::sys::fs::exists(RuntimeLibraryPath)) {
defaultPath.append(RuntimeLibraryPath);
found = true;
break;
}
}
if (!found) {
auto joined = llvm::join(IGM.Context.SearchPathOpts.RuntimeLibraryPaths,
"', '");
llvm::report_fatal_error("Unable to find a runtime library path at '"
+ joined + "'");
}

llvm::sys::path::append(defaultPath, "layouts-");
defaultPath.append(archName);
defaultPath.append(".yaml");
Expand Down
43 changes: 16 additions & 27 deletions lib/Immediate/Immediate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,43 +51,34 @@
using namespace swift;
using namespace swift::immediate;

/// The path for Swift libraries in the OS.
#define OS_LIBRARY_PATH "/usr/lib/swift"

static void *loadRuntimeLib(StringRef runtimeLibPathWithName) {
#if defined(_WIN32)
return LoadLibraryA(runtimeLibPathWithName.str().c_str());
#else
#if defined(__APPLE__) && defined(__MACH__)
if (!llvm::sys::path::is_absolute(runtimeLibPathWithName)) {
// Try an absolute path search for Swift in the OS first.
llvm::SmallString<128> absolutePath(OS_LIBRARY_PATH);
llvm::sys::path::append(absolutePath, runtimeLibPathWithName);
auto result = dlopen(absolutePath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (result) return result;
}
#endif
return dlopen(runtimeLibPathWithName.str().c_str(), RTLD_LAZY | RTLD_GLOBAL);
#endif
}

static void *loadRuntimeLib(StringRef sharedLibName, StringRef runtimeLibPath) {
static void *loadRuntimeLibAtPath(StringRef sharedLibName,
StringRef runtimeLibPath) {
// FIXME: Need error-checking.
llvm::SmallString<128> Path = runtimeLibPath;
llvm::sys::path::append(Path, sharedLibName);
return loadRuntimeLib(Path);
}

void *swift::immediate::loadSwiftRuntime(StringRef runtimeLibPath,
bool IsDefault) {
StringRef LibName = "libswiftCore" LTDL_SHLIB_EXT;
#if defined(__APPLE__) && defined(__MACH__)
if (IsDefault) {
auto result = loadRuntimeLib(LibName);
if (result) return result;
static void *loadRuntimeLib(StringRef sharedLibName,
ArrayRef<std::string> runtimeLibPaths) {
for (auto &runtimeLibPath : runtimeLibPaths) {
if (void *handle = loadRuntimeLibAtPath(sharedLibName, runtimeLibPath))
return handle;
}
#endif
return loadRuntimeLib(LibName, runtimeLibPath);
return nullptr;
}

void *swift::immediate::loadSwiftRuntime(ArrayRef<std::string>
runtimeLibPaths) {
return loadRuntimeLib("libswiftCore" LTDL_SHLIB_EXT, runtimeLibPaths);
}

static bool tryLoadLibrary(LinkLibrary linkLib,
Expand Down Expand Up @@ -125,9 +116,9 @@ static bool tryLoadLibrary(LinkLibrary linkLib,
if (!success)
success = loadRuntimeLib(stem);

// If that fails, try our runtime library path.
// If that fails, try our runtime library paths.
if (!success)
success = loadRuntimeLib(stem, searchPathOpts.RuntimeLibraryPath);
success = loadRuntimeLib(stem, searchPathOpts.RuntimeLibraryPaths);
break;
}
case LibraryKind::Framework: {
Expand Down Expand Up @@ -260,9 +251,7 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
//
// This must be done here, before any library loading has been done, to avoid
// racing with the static initializers in user code.
auto stdlib = loadSwiftRuntime(
Context.SearchPathOpts.RuntimeLibraryPath,
Context.SearchPathOpts.RuntimeLibraryPathIsDefault);
auto stdlib = loadSwiftRuntime(Context.SearchPathOpts.RuntimeLibraryPaths);
if (!stdlib) {
CI.getDiags().diagnose(SourceLoc(),
diag::error_immediate_mode_missing_stdlib);
Expand Down
5 changes: 2 additions & 3 deletions lib/Immediate/ImmediateImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ namespace immediate {
/// Returns a handle to the runtime suitable for other \c dlsym or \c dlclose
/// calls or \c null if an error occurred.
///
/// \param runtimeLibPath Path to search for compiler-relative stdlib dylibs.
/// \param IsDefault If true, the path is the default compiler-relative path.
void *loadSwiftRuntime(StringRef runtimeLibPath, bool IsDefault);
/// \param runtimeLibPaths Paths to search for stdlib dylibs.
void *loadSwiftRuntime(ArrayRef<std::string> runtimeLibPaths);
bool tryLoadLibraries(ArrayRef<LinkLibrary> LinkLibraries,
SearchPathOptions SearchPathOpts,
DiagnosticEngine &Diags);
Expand Down
3 changes: 1 addition & 2 deletions lib/Immediate/REPL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,8 +969,7 @@ class REPLEnvironment {
ASTContext &Ctx = CI.getASTContext();
Ctx.LangOpts.EnableAccessControl = false;
if (!ParseStdlib) {
if (!loadSwiftRuntime(Ctx.SearchPathOpts.RuntimeLibraryPath,
Ctx.SearchPathOpts.RuntimeLibraryPathIsDefault)) {
if (!loadSwiftRuntime(Ctx.SearchPathOpts.RuntimeLibraryPaths)) {
CI.getDiags().diagnose(SourceLoc(),
diag::error_immediate_mode_missing_stdlib);
return;
Expand Down
2 changes: 1 addition & 1 deletion test/Driver/Inputs/print-var.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
last_arg=${@: -1}
echo ${!last_arg:-NO_VALUE}
echo ${!last_arg}
8 changes: 0 additions & 8 deletions test/Driver/environment-mac.swift

This file was deleted.

10 changes: 5 additions & 5 deletions test/Driver/options-interpreter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@


// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -resource-dir /RSRC/ %s | %FileCheck -check-prefix=CHECK-RESOURCE-DIR-ONLY %s
// CHECK-RESOURCE-DIR-ONLY: # DYLD_LIBRARY_PATH={{(/usr/lib/swift:)?}}/RSRC/macosx{{$}}
// CHECK-RESOURCE-DIR-ONLY: # DYLD_LIBRARY_PATH=/RSRC/macosx{{$}}

// RUN: %swift_driver -### -target x86_64-unknown-linux-gnu -resource-dir /RSRC/ %s | %FileCheck -check-prefix=CHECK-RESOURCE-DIR-ONLY-LINUX${LD_LIBRARY_PATH+_LAX} %s
// CHECK-RESOURCE-DIR-ONLY-LINUX: # LD_LIBRARY_PATH=/RSRC/linux{{$}}
// CHECK-RESOURCE-DIR-ONLY-LINUX_LAX: # LD_LIBRARY_PATH=/RSRC/linux{{$|:}}

// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -L/foo/ %s | %FileCheck -check-prefix=CHECK-L %s
// CHECK-L: # DYLD_LIBRARY_PATH={{/foo/:(/usr/lib/swift:)?[^:]+/lib/swift/macosx$}}
// CHECK-L: # DYLD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/macosx$}}

// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -L/foo/ -L/bar/ %s | %FileCheck -check-prefix=CHECK-L2 %s
// CHECK-L2: # DYLD_LIBRARY_PATH={{/foo/:/bar/:(/usr/lib/swift:)?[^:]+/lib/swift/macosx$}}
// CHECK-L2: # DYLD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/macosx$}}

// RUN: env DYLD_LIBRARY_PATH=/abc/ %swift_driver_plain -### -target x86_64-apple-macosx10.9 -L/foo/ -L/bar/ %s | %FileCheck -check-prefix=CHECK-L2-ENV %s
// CHECK-L2-ENV: # DYLD_LIBRARY_PATH={{/foo/:/bar/:(/usr/lib/swift:)?[^:]+/lib/swift/macosx:/abc/$}}
// CHECK-L2-ENV: # DYLD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/macosx:/abc/$}}

// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=CHECK-NO-FRAMEWORKS %s
// RUN: env DYLD_FRAMEWORK_PATH=/abc/ %swift_driver_plain -### -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=CHECK-NO-FRAMEWORKS %s
Expand Down Expand Up @@ -56,7 +56,7 @@
// CHECK-COMPLEX: -F /bar/
// CHECK-COMPLEX: #
// CHECK-COMPLEX-DAG: DYLD_FRAMEWORK_PATH=/foo/:/bar/:/abc/{{$| }}
// CHECK-COMPLEX-DAG: DYLD_LIBRARY_PATH={{/foo2/:/bar2/:(/usr/lib/swift:)?[^:]+/lib/swift/macosx($| )}}
// CHECK-COMPLEX-DAG: DYLD_LIBRARY_PATH={{/foo2/:/bar2/:[^:]+/lib/swift/macosx($| )}}

// RUN: %swift_driver -### -target x86_64-unknown-linux-gnu -L/foo/ %s | %FileCheck -check-prefix=CHECK-L-LINUX${LD_LIBRARY_PATH+_LAX} %s
// CHECK-L-LINUX: # LD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/linux$}}
Expand Down
5 changes: 1 addition & 4 deletions test/Interpreter/repl_autolinking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
// RUN: sed -n -e '/REPL_START$/,/REPL_END$/ p' %s > %t/repl.swift
// RUN: %target-swiftc_driver -emit-library %t/a.swift -I %t -L %t -emit-module-path %t/ModuleA.swiftmodule -autolink-force-load -module-link-name ModuleA -module-name ModuleA -o %t/libModuleA.dylib
// RUN: %target-swiftc_driver -emit-library %t/b.swift -I %t -L %t -emit-module-path %t/ModuleB.swiftmodule -autolink-force-load -module-link-name ModuleB -module-name ModuleB -o %t/libModuleB.dylib
// RUN: DYLD_LIBRARY_PATH=/usr/lib/swift %swift -repl -I %t -L %t < %t/repl.swift 2>&1 | %FileCheck %s

// FIXME: remove DYLD_LIBRARY_PATH from the last command when we fix the
// interpreter's runtime library lookup.
// RUN: %swift -repl -I %t -L %t < %t/repl.swift 2>&1 | %FileCheck %s

// REQUIRES: swift_repl
// UNSUPPORTED: OS=linux-gnu
Expand Down