From 6a1da3be4bf9e5bccd7c0b95a8749c8f85058536 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Mon, 24 Jun 2019 17:23:26 -0700 Subject: [PATCH 1/5] Look up runtime libraries in SDK In #23175, we started looking in the SDK for swiftmodules, but we want to look for the dylibs there too. Fixes . --- include/swift/Driver/ToolChain.h | 14 +++++-- lib/Driver/DarwinToolChains.cpp | 45 +++++++++++++-------- lib/Driver/ToolChains.cpp | 41 +++++++++++++------ lib/Driver/UnixToolChains.cpp | 58 ++++++++++++++++++--------- lib/Driver/WindowsToolChains.cpp | 42 +++++++++++-------- test/Driver/options-interpreter.swift | 4 +- test/Driver/sdk.swift | 4 +- 7 files changed, 135 insertions(+), 73 deletions(-) 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..d883eb28078d1 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. @@ -392,8 +393,8 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job, // 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); + SmallString<128> ResourceDirPath; + getResourceDirPath(ResourceDirPath, context.Args, /*Shared=*/true); // Link compatibility libraries, if we're deploying back to OSes that // have an older Swift runtime. @@ -418,7 +419,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(ResourceDirPath); llvm::sys::path::append(BackDeployLib, "libswiftCompatibility50.a"); if (llvm::sys::fs::exists(BackDeployLib)) { @@ -433,7 +434,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(ResourceDirPath); llvm::sys::path::append(BackDeployLib, "libswiftCompatibilityDynamicReplacements.a"); @@ -445,22 +446,34 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job, } // 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)); + SmallVector StaticRuntimeLibPaths; + getRuntimeLibraryPaths(StaticRuntimeLibPaths, context.Args, + context.OI.SDKPath, /*Shared=*/false); + + for (auto path : StaticRuntimeLibPaths) { + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(path)); + } + 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)); + SmallVector SharedRuntimeLibPaths; + getRuntimeLibraryPaths(SharedRuntimeLibPaths, context.Args, + context.OI.SDKPath, /*Shared=*/true); + + for (auto path : SharedRuntimeLibPaths) { + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(path)); + // 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(path)); + } } if (context.Args.hasArg(options::OPT_profile_generate)) { diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index ad1dc343fc03d..d88f56fa1647b 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -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 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()); @@ -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", @@ -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 &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..310d3166334d0 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,34 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, staticStdlib = true; } - SmallString<128> SharedRuntimeLibPath; - getRuntimeLibraryPath(SharedRuntimeLibPath, context.Args, /*Shared=*/true); + SmallString<128> SharedResourceDirPath; + getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true); - SmallString<128> StaticRuntimeLibPath; - getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args, /*Shared=*/false); + SmallString<128> StaticResourceDirPath; + getResourceDirPath(StaticResourceDirPath, context.Args, /*Shared=*/false); + + SmallVector SharedRuntimeLibPaths; + getRuntimeLibraryPaths(SharedRuntimeLibPaths, context.Args, + context.OI.SDKPath, /*Shared=*/true); + + SmallVector StaticRuntimeLibPaths; + getRuntimeLibraryPaths(StaticRuntimeLibPaths, context.Args, + context.OI.SDKPath, /*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 : SharedRuntimeLibPaths) { + 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> swiftrtPath = SharedResourceDirPath; llvm::sys::path::append(swiftrtPath, swift::getMajorArchitectureName(getTriple())); llvm::sys::path::append(swiftrtPath, "swiftrt.o"); @@ -240,12 +250,14 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, } // Link the standard library. - Arguments.push_back("-L"); if (staticExecutable) { - Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); + for (auto path : StaticRuntimeLibPaths) { + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(path)); + } - SmallString<128> linkFilePath = StaticRuntimeLibPath; + SmallString<128> linkFilePath = StaticResourceDirPath; llvm::sys::path::append(linkFilePath, "static-executable-args.lnk"); auto linkFile = linkFilePath.str(); @@ -256,9 +268,12 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, "-static-executable not supported on this platform"); } } else if (staticStdlib) { - Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); + for (auto path : StaticRuntimeLibPaths) { + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(path)); + } - SmallString<128> linkFilePath = StaticRuntimeLibPath; + SmallString<128> linkFilePath = StaticResourceDirPath; llvm::sys::path::append(linkFilePath, "static-stdlib-args.lnk"); auto linkFile = linkFilePath.str(); if (llvm::sys::fs::is_regular_file(linkFile)) { @@ -267,7 +282,10 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, llvm::report_fatal_error(linkFile + " not found"); } } else { - Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath)); + for (auto path : SharedRuntimeLibPaths) { + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(path)); + } Arguments.push_back("-lswiftCore"); } @@ -289,7 +307,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 cb04e286a273b..d1e50474b39c6 100644 --- a/lib/Driver/WindowsToolChains.cpp +++ b/lib/Driver/WindowsToolChains.cpp @@ -108,28 +108,36 @@ 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); - - // 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())); + SmallVector StaticRuntimeLibPaths; + getRuntimeLibraryPaths(StaticRuntimeLibPaths, context.Args, + context.OI.SDKPath, /*Shared=*/false); + + for (auto path : StaticRuntimeLibPaths) { + 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(path + "/" + + getTriple().getArchName())); + } } else { - Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath + "/" + - getTriple().getArchName())); + SmallVector SharedRuntimeLibPaths; + getRuntimeLibraryPaths(SharedRuntimeLibPaths, context.Args, + context.OI.SDKPath, /*Shared=*/true); + + for (auto path : SharedRuntimeLibPaths) { + Arguments.push_back("-L"); + 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"); @@ -164,7 +172,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..b988872dc81c4 100644 --- a/test/Driver/options-interpreter.swift +++ b/test/Driver/options-interpreter.swift @@ -28,7 +28,7 @@ // 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/$}} +// CHECK-L2-ENV: # DYLD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/macosx:[^:]+\.sdk/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 @@ -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/:[^:]+/lib/swift/macosx($| )}} +// CHECK-COMPLEX-DAG: DYLD_LIBRARY_PATH={{/foo2/:/bar2/:[^:]+/lib/swift/macosx:[^:]+\.sdk/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 From 3c286b8d6985ef22f0b01f90a505cf6d1ffbcc72 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Mon, 24 Jun 2019 19:39:55 -0700 Subject: [PATCH 2/5] Clean up driver linker invocation code Refactor to merge some very similar code in different branches. This ended up slightly changing the order of arguments in Linux linker commands. --- lib/Driver/DarwinToolChains.cpp | 50 +++++++++++------------- lib/Driver/UnixToolChains.cpp | 65 +++++++++++--------------------- lib/Driver/WindowsToolChains.cpp | 38 +++++++------------ test/Driver/linker.swift | 4 +- 4 files changed, 62 insertions(+), 95 deletions(-) diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index d883eb28078d1..92664fbde2184 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -391,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> ResourceDirPath; - getResourceDirPath(ResourceDirPath, 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)) { @@ -419,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(ResourceDirPath); + BackDeployLib.append(SharedResourceDirPath); llvm::sys::path::append(BackDeployLib, "libswiftCompatibility50.a"); if (llvm::sys::fs::exists(BackDeployLib)) { @@ -434,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(ResourceDirPath); + BackDeployLib.append(SharedResourceDirPath); llvm::sys::path::append(BackDeployLib, "libswiftCompatibilityDynamicReplacements.a"); @@ -445,32 +442,31 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job, } } - // Link the standard library. - if (context.Args.hasFlag(options::OPT_static_stdlib, - options::OPT_no_static_stdlib, false)) { - SmallVector StaticRuntimeLibPaths; - getRuntimeLibraryPaths(StaticRuntimeLibPaths, context.Args, - context.OI.SDKPath, /*Shared=*/false); - - for (auto path : StaticRuntimeLibPaths) { - Arguments.push_back("-L"); - Arguments.push_back(context.Args.MakeArgString(path)); - } + 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. + if (wantsStaticStdlib) { Arguments.push_back("-lc++"); Arguments.push_back("-framework"); Arguments.push_back("Foundation"); Arguments.push_back("-force_load_swift_libs"); } else { - SmallVector SharedRuntimeLibPaths; - getRuntimeLibraryPaths(SharedRuntimeLibPaths, context.Args, - context.OI.SDKPath, /*Shared=*/true); - - for (auto path : SharedRuntimeLibPaths) { - Arguments.push_back("-L"); - Arguments.push_back(context.Args.MakeArgString(path)); - // 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 + // 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 + for (auto path : RuntimeLibPaths) { Arguments.push_back("-rpath"); Arguments.push_back(context.Args.MakeArgString(path)); } diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp index 310d3166334d0..3a45302c799c5 100644 --- a/lib/Driver/UnixToolChains.cpp +++ b/lib/Driver/UnixToolChains.cpp @@ -190,26 +190,20 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, staticStdlib = true; } - SmallString<128> SharedResourceDirPath; - getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true); - - SmallString<128> StaticResourceDirPath; - getResourceDirPath(StaticResourceDirPath, context.Args, /*Shared=*/false); - - SmallVector SharedRuntimeLibPaths; - getRuntimeLibraryPaths(SharedRuntimeLibPaths, context.Args, - context.OI.SDKPath, /*Shared=*/true); - - SmallVector StaticRuntimeLibPaths; - getRuntimeLibraryPaths(StaticRuntimeLibPaths, context.Args, - context.OI.SDKPath, /*Shared=*/false); + SmallVector RuntimeLibPaths; + getRuntimeLibraryPaths(RuntimeLibPaths, context.Args, context.OI.SDKPath, + /*Shared=*/!(staticExecutable || staticStdlib)); + + // Add the runtime library link paths. + for (auto path : RuntimeLibPaths) { + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(path)); + } - // 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. - for (auto path : SharedRuntimeLibPaths) { + for (auto path : RuntimeLibPaths) { Arguments.push_back("-Xlinker"); Arguments.push_back("-rpath"); Arguments.push_back("-Xlinker"); @@ -217,6 +211,9 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, } } + SmallString<128> SharedResourceDirPath; + getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true); + SmallString<128> swiftrtPath = SharedResourceDirPath; llvm::sys::path::append(swiftrtPath, swift::getMajorArchitectureName(getTriple())); @@ -251,42 +248,26 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, // Link the standard library. - if (staticExecutable) { - for (auto path : StaticRuntimeLibPaths) { - Arguments.push_back("-L"); - Arguments.push_back(context.Args.MakeArgString(path)); - } + // If we need to use an .lnk file, linkFilePath will contain it. + SmallString<128> linkFilePath; + getResourceDirPath(linkFilePath, context.Args, /*Shared=*/false); - SmallString<128> linkFilePath = StaticResourceDirPath; + 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) { - for (auto path : StaticRuntimeLibPaths) { - Arguments.push_back("-L"); - Arguments.push_back(context.Args.MakeArgString(path)); - } - - SmallString<128> linkFilePath = StaticResourceDirPath; 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 { - for (auto path : SharedRuntimeLibPaths) { - Arguments.push_back("-L"); - Arguments.push_back(context.Args.MakeArgString(path)); - } - Arguments.push_back("-lswiftCore"); } // Explicitly pass the target to the linker diff --git a/lib/Driver/WindowsToolChains.cpp b/lib/Driver/WindowsToolChains.cpp index d1e50474b39c6..402217ec4798f 100644 --- a/lib/Driver/WindowsToolChains.cpp +++ b/lib/Driver/WindowsToolChains.cpp @@ -108,30 +108,20 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job, // driver rather than the `clang-cl` driver. Arguments.push_back("-nostartfiles"); - // Link the standard library. - if (context.Args.hasFlag(options::OPT_static_stdlib, - options::OPT_no_static_stdlib, false)) { - SmallVector StaticRuntimeLibPaths; - getRuntimeLibraryPaths(StaticRuntimeLibPaths, context.Args, - context.OI.SDKPath, /*Shared=*/false); - - for (auto path : StaticRuntimeLibPaths) { - 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(path + "/" + - getTriple().getArchName())); - } - } else { - SmallVector SharedRuntimeLibPaths; - getRuntimeLibraryPaths(SharedRuntimeLibPaths, context.Args, - context.OI.SDKPath, /*Shared=*/true); - - for (auto path : SharedRuntimeLibPaths) { - Arguments.push_back("-L"); - Arguments.push_back(context.Args.MakeArgString(path + "/" + - getTriple().getArchName())); - } + 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(path + "/" + + getTriple().getArchName())); } SmallString<128> SharedResourceDirPath; diff --git a/test/Driver/linker.swift b/test/Driver/linker.swift index f52caf57acdeb..c914211fcf6eb 100644 --- a/test/Driver/linker.swift +++ b/test/Driver/linker.swift @@ -291,11 +291,11 @@ // LINUX_DYNLIB-x86_64-DAG: -shared // LINUX_DYNLIB-x86_64-DAG: -fuse-ld=gold // LINUX_DYNLIB-x86_64-NOT: -pie -// LINUX_DYNLIB-x86_64-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH:[^ ]+(/|\\\\)lib(/|\\\\)swift(/|\\\\)linux]] +// LINUX_DYNLIB-x86_64-DAG: -L [[STDLIB_PATH:[^ ]+(/|\\\\)lib(/|\\\\)swift(/|\\\\)linux]] +// LINUX_DYNLIB-x86_64-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]] // LINUX_DYNLIB-x86_64: [[STDLIB_PATH]]{{/|\\\\}}x86_64{{/|\\\\}}swiftrt.o // LINUX_DYNLIB-x86_64-DAG: [[OBJECTFILE]] // LINUX_DYNLIB-x86_64-DAG: @[[AUTOLINKFILE]] -// LINUX_DYNLIB-x86_64-DAG: [[STDLIB_PATH]] // LINUX_DYNLIB-x86_64-DAG: -lswiftCore // LINUX_DYNLIB-x86_64-DAG: -L bar // LINUX_DYNLIB-x86_64: -o dynlib.out From 6dbe71732dfe35aed1b703ffe3e3108cf49dafba Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Mon, 24 Jun 2019 19:40:20 -0700 Subject: [PATCH 3/5] Explicitly set SDK in interpreter test Gives us consistent results between macOS and Linux. --- test/Driver/options-interpreter.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Driver/options-interpreter.swift b/test/Driver/options-interpreter.swift index b988872dc81c4..0839222d27fda 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:[^:]+\.sdk/usr/lib/swift:/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 From e31ad38443676bb6dbfd8d0f2231b178211b2fe3 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Tue, 25 Jun 2019 13:37:00 -0700 Subject: [PATCH 4/5] Undo Linux linker order changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out the order of the linker flags matters on Linux; see apple/swift#9958. I don’t know if the change I previously made would break something, but it’s not worth risking it. --- lib/Driver/UnixToolChains.cpp | 16 ++++++++-------- test/Driver/linker.swift | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp index 3a45302c799c5..bdc63d1ca72e5 100644 --- a/lib/Driver/UnixToolChains.cpp +++ b/lib/Driver/UnixToolChains.cpp @@ -194,12 +194,6 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, getRuntimeLibraryPaths(RuntimeLibPaths, context.Args, context.OI.SDKPath, /*Shared=*/!(staticExecutable || staticStdlib)); - // Add the runtime library link paths. - for (auto path : RuntimeLibPaths) { - Arguments.push_back("-L"); - Arguments.push_back(context.Args.MakeArgString(path)); - } - 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. @@ -246,9 +240,15 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, Twine("@") + OutputInfo.getPrimaryOutputFilename())); } - // Link the standard library. + // Add the runtime library link paths. + for (auto path : RuntimeLibPaths) { + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(path)); + } - // If we need to use an .lnk file, linkFilePath will contain it. + // 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); diff --git a/test/Driver/linker.swift b/test/Driver/linker.swift index c914211fcf6eb..f52caf57acdeb 100644 --- a/test/Driver/linker.swift +++ b/test/Driver/linker.swift @@ -291,11 +291,11 @@ // LINUX_DYNLIB-x86_64-DAG: -shared // LINUX_DYNLIB-x86_64-DAG: -fuse-ld=gold // LINUX_DYNLIB-x86_64-NOT: -pie -// LINUX_DYNLIB-x86_64-DAG: -L [[STDLIB_PATH:[^ ]+(/|\\\\)lib(/|\\\\)swift(/|\\\\)linux]] -// LINUX_DYNLIB-x86_64-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]] +// LINUX_DYNLIB-x86_64-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH:[^ ]+(/|\\\\)lib(/|\\\\)swift(/|\\\\)linux]] // LINUX_DYNLIB-x86_64: [[STDLIB_PATH]]{{/|\\\\}}x86_64{{/|\\\\}}swiftrt.o // LINUX_DYNLIB-x86_64-DAG: [[OBJECTFILE]] // LINUX_DYNLIB-x86_64-DAG: @[[AUTOLINKFILE]] +// LINUX_DYNLIB-x86_64-DAG: [[STDLIB_PATH]] // LINUX_DYNLIB-x86_64-DAG: -lswiftCore // LINUX_DYNLIB-x86_64-DAG: -L bar // LINUX_DYNLIB-x86_64: -o dynlib.out From 56524c35b0e78990c43822fa08556a20bea9c7b7 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Tue, 25 Jun 2019 14:36:30 -0700 Subject: [PATCH 5/5] Fix a second Linux test --- test/Driver/options-interpreter.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Driver/options-interpreter.swift b/test/Driver/options-interpreter.swift index 0839222d27fda..64e90b6a12c39 100644 --- a/test/Driver/options-interpreter.swift +++ b/test/Driver/options-interpreter.swift @@ -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:[^:]+\.sdk/usr/lib/swift($| )}} +// 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$}}