|
21 | 21 | #include "swift/AST/IRGenOptions.h"
|
22 | 22 | #include "swift/AST/IRGenRequests.h"
|
23 | 23 | #include "swift/AST/Module.h"
|
| 24 | +#include "swift/AST/ModuleDependencies.h" |
24 | 25 | #include "swift/Basic/LLVMExtras.h"
|
25 | 26 | #include "swift/ClangImporter/ClangImporter.h"
|
26 | 27 | #include "swift/Demangling/ManglingMacros.h"
|
@@ -1608,6 +1609,110 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
|
1608 | 1609 | }
|
1609 | 1610 | }
|
1610 | 1611 |
|
| 1612 | +void IRGenModule::addLinkLibraries() { |
| 1613 | + auto registerLinkLibrary = [this](const LinkLibrary &ll) { |
| 1614 | + this->addLinkLibrary(ll); |
| 1615 | + }; |
| 1616 | + |
| 1617 | + getSwiftModule()->collectLinkLibraries( |
| 1618 | + [registerLinkLibrary](LinkLibrary linkLib) { |
| 1619 | + registerLinkLibrary(linkLib); |
| 1620 | + }); |
| 1621 | + |
| 1622 | + if (ObjCInterop) |
| 1623 | + registerLinkLibrary(LinkLibrary("objc", LibraryKind::Library)); |
| 1624 | + |
| 1625 | + // If C++ interop is enabled, add -lc++ on Darwin and -lstdc++ on linux. |
| 1626 | + // Also link with C++ bridging utility module (Cxx) and C++ stdlib overlay |
| 1627 | + // (std) if available. |
| 1628 | + if (Context.LangOpts.EnableCXXInterop) { |
| 1629 | + const llvm::Triple &target = Context.LangOpts.Target; |
| 1630 | + if (target.isOSDarwin()) |
| 1631 | + registerLinkLibrary(LinkLibrary("c++", LibraryKind::Library)); |
| 1632 | + else if (target.isOSLinux()) |
| 1633 | + registerLinkLibrary(LinkLibrary("stdc++", LibraryKind::Library)); |
| 1634 | + |
| 1635 | + // Do not try to link Cxx with itself. |
| 1636 | + if (!getSwiftModule()->getName().is("Cxx")) { |
| 1637 | + bool isStatic = false; |
| 1638 | + if (const auto *M = Context.getModuleByName("Cxx")) |
| 1639 | + isStatic = M->isStaticLibrary(); |
| 1640 | + registerLinkLibrary(LinkLibrary(target.isOSWindows() && isStatic |
| 1641 | + ? "libswiftCxx" |
| 1642 | + : "swiftCxx", |
| 1643 | + LibraryKind::Library)); |
| 1644 | + } |
| 1645 | + |
| 1646 | + // Do not try to link CxxStdlib with the C++ standard library, Cxx or |
| 1647 | + // itself. |
| 1648 | + if (llvm::none_of(llvm::ArrayRef{"Cxx", "CxxStdlib", "std"}, |
| 1649 | + [M = getSwiftModule()->getName().str()](StringRef Name) { |
| 1650 | + return M == Name; |
| 1651 | + })) { |
| 1652 | + // Only link with CxxStdlib on platforms where the overlay is available. |
| 1653 | + switch (target.getOS()) { |
| 1654 | + case llvm::Triple::Linux: |
| 1655 | + if (!target.isAndroid()) |
| 1656 | + registerLinkLibrary(LinkLibrary("swiftCxxStdlib", |
| 1657 | + LibraryKind::Library)); |
| 1658 | + break; |
| 1659 | + case llvm::Triple::Win32: { |
| 1660 | + bool isStatic = Context.getModuleByName("CxxStdlib")->isStaticLibrary(); |
| 1661 | + registerLinkLibrary( |
| 1662 | + LinkLibrary(isStatic ? "libswiftCxxStdlib" : "swiftCxxStdlib", |
| 1663 | + LibraryKind::Library)); |
| 1664 | + break; |
| 1665 | + } |
| 1666 | + default: |
| 1667 | + if (target.isOSDarwin()) |
| 1668 | + registerLinkLibrary(LinkLibrary("swiftCxxStdlib", |
| 1669 | + LibraryKind::Library)); |
| 1670 | + break; |
| 1671 | + } |
| 1672 | + } |
| 1673 | + } |
| 1674 | + |
| 1675 | + // FIXME: It'd be better to have the driver invocation or build system that |
| 1676 | + // executes the linker introduce these compatibility libraries, since at |
| 1677 | + // that point we know whether we're building an executable, which is the only |
| 1678 | + // place where the compatibility libraries take effect. For the benefit of |
| 1679 | + // build systems that build Swift code, but don't use Swift to drive |
| 1680 | + // the linker, we can also use autolinking to pull in the compatibility |
| 1681 | + // libraries. This may however cause the library to get pulled in in |
| 1682 | + // situations where it isn't useful, such as for dylibs, though this is |
| 1683 | + // harmless aside from code size. |
| 1684 | + if (!IRGen.Opts.UseJIT && !Context.LangOpts.hasFeature(Feature::Embedded)) { |
| 1685 | + auto addBackDeployLib = [&](llvm::VersionTuple version, |
| 1686 | + StringRef libraryName, bool forceLoad) { |
| 1687 | + std::optional<llvm::VersionTuple> compatibilityVersion; |
| 1688 | + if (libraryName == "swiftCompatibilityDynamicReplacements") { |
| 1689 | + compatibilityVersion = IRGen.Opts. |
| 1690 | + AutolinkRuntimeCompatibilityDynamicReplacementLibraryVersion; |
| 1691 | + } else if (libraryName == "swiftCompatibilityConcurrency") { |
| 1692 | + compatibilityVersion = |
| 1693 | + IRGen.Opts.AutolinkRuntimeCompatibilityConcurrencyLibraryVersion; |
| 1694 | + } else { |
| 1695 | + compatibilityVersion = IRGen.Opts. |
| 1696 | + AutolinkRuntimeCompatibilityLibraryVersion; |
| 1697 | + } |
| 1698 | + |
| 1699 | + if (!compatibilityVersion) |
| 1700 | + return; |
| 1701 | + |
| 1702 | + if (*compatibilityVersion > version) |
| 1703 | + return; |
| 1704 | + |
| 1705 | + registerLinkLibrary(LinkLibrary(libraryName, |
| 1706 | + LibraryKind::Library, |
| 1707 | + forceLoad)); |
| 1708 | + }; |
| 1709 | + |
| 1710 | +#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \ |
| 1711 | + addBackDeployLib(llvm::VersionTuple Version, LibraryName, ForceLoad); |
| 1712 | + #include "swift/Frontend/BackDeploymentLibs.def" |
| 1713 | + } |
| 1714 | +} |
| 1715 | + |
1611 | 1716 | static bool replaceModuleFlagsEntry(llvm::LLVMContext &Ctx,
|
1612 | 1717 | llvm::Module &Module, StringRef EntryName,
|
1613 | 1718 | llvm::Module::ModFlagBehavior Behavior,
|
|
0 commit comments