diff --git a/include/swift/Driver/ToolChain.h b/include/swift/Driver/ToolChain.h index f85e0a0b821fa..4cf7bd18a04ec 100644 --- a/include/swift/Driver/ToolChain.h +++ b/include/swift/Driver/ToolChain.h @@ -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 &runtimeLibPath, - const llvm::opt::ArgList &args, bool shared) const; + void getResourceDirPath(SmallVectorImpl &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 &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 extraEntries = {}) const; /// Specific toolchains should override this to provide additional conditions /// under which the compiler invocation should be written into debug info. For diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index c2b1d14bb5300..92664fbde2184 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -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 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. @@ -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 runtimeCompatibilityVersion; if (context.Args.hasArg(options::OPT_runtime_compatibility_version)) { @@ -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)) { @@ -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"); @@ -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 RuntimeLibPaths; + getRuntimeLibraryPaths(RuntimeLibPaths, context.Args, + context.OI.SDKPath, /*Shared=*/!wantsStaticStdlib); + + // 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)) { diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 538b6e3d49ba0..7db8f0d713075 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1058,16 +1058,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 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()); @@ -1091,7 +1092,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", @@ -1101,27 +1102,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 &runtimeLibPath, - const llvm::opt::ArgList &args, - bool shared) const { +void ToolChain::getResourceDirPath(SmallVectorImpl &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 &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 { diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp index e1afb709a5afb..bdc63d1ca72e5 100644 --- a/lib/Driver/UnixToolChains.cpp +++ b/lib/Driver/UnixToolChains.cpp @@ -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 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; } @@ -190,24 +190,25 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, staticStdlib = true; } - SmallString<128> SharedRuntimeLibPath; - getRuntimeLibraryPath(SharedRuntimeLibPath, context.Args, /*Shared=*/true); + SmallVector 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"); @@ -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 @@ -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"); diff --git a/lib/Driver/WindowsToolChains.cpp b/lib/Driver/WindowsToolChains.cpp index e155a795ee0fd..42948bb115931 100644 --- a/lib/Driver/WindowsToolChains.cpp +++ b/lib/Driver/WindowsToolChains.cpp @@ -100,28 +100,26 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job, Arguments.push_back(context.Args.MakeArgString(Target)); } - 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 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"); @@ -156,7 +154,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"); diff --git a/test/Driver/options-interpreter.swift b/test/Driver/options-interpreter.swift index 3a7bd0e94eb3b..64e90b6a12c39 100644 --- a/test/Driver/options-interpreter.swift +++ b/test/Driver/options-interpreter.swift @@ -27,8 +27,8 @@ // 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/:[^:]+/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/:[^:]+/lib/swift/macosx:/abc/$}} +// RUN: env DYLD_LIBRARY_PATH=/abc/ SDKROOT=/sdkroot %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/:[^:]+/lib/swift/macosx:/sdkroot/usr/lib/swift:/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 @@ -51,12 +51,12 @@ // CHECK-F2-ENV: # // CHECK-F2-ENV: DYLD_FRAMEWORK_PATH=/foo/:/bar/:/abc/{{$}} -// RUN: env DYLD_FRAMEWORK_PATH=/abc/ %swift_driver_plain -### -target x86_64-apple-macosx10.9 -F/foo/ -F/bar/ -L/foo2/ -L/bar2/ %s | %FileCheck -check-prefix=CHECK-COMPLEX %s +// RUN: env DYLD_FRAMEWORK_PATH=/abc/ SDKROOT=/sdkroot %swift_driver_plain -### -target x86_64-apple-macosx10.9 -F/foo/ -F/bar/ -L/foo2/ -L/bar2/ %s | %FileCheck -check-prefix=CHECK-COMPLEX %s // CHECK-COMPLEX: -F /foo/ // CHECK-COMPLEX: -F /bar/ // CHECK-COMPLEX: # // CHECK-COMPLEX-DAG: DYLD_FRAMEWORK_PATH=/foo/:/bar/:/abc/{{$| }} -// CHECK-COMPLEX-DAG: DYLD_LIBRARY_PATH={{/foo2/:/bar2/:[^:]+/lib/swift/macosx($| )}} +// CHECK-COMPLEX-DAG: DYLD_LIBRARY_PATH={{/foo2/:/bar2/:[^:]+/lib/swift/macosx:/sdkroot/usr/lib/swift($| )}} // 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$}} diff --git a/test/Driver/sdk.swift b/test/Driver/sdk.swift index e077a38704c77..10e70906fe35d 100644 --- a/test/Driver/sdk.swift +++ b/test/Driver/sdk.swift @@ -14,7 +14,9 @@ // OSX-NEXT: bin{{/|\\\\}}swift // OSX: -sdk {{.*}}/Inputs/clang-importer-sdk // OSX: {{.*}}.o{{[ "]}} -// OSX: {{-syslibroot|--sysroot}} {{.*}}/Inputs/clang-importer-sdk +// OSX: {{-syslibroot|--sysroot}} {{[^ ]*}}/Inputs/clang-importer-sdk +// OSX: -L {{[^ ]*}}/Inputs/clang-importer-sdk/usr/lib/swift +// OSX: -rpath {{[^ ]*}}/Inputs/clang-importer-sdk/usr/lib/swift // LINUX-NOT: warning: no such SDK: // LINUX: bin{{/|\\\\}}swift