diff options
Diffstat (limited to 'lib/Driver/ToolChains.cpp')
-rw-r--r-- | lib/Driver/ToolChains.cpp | 145 |
1 files changed, 111 insertions, 34 deletions
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 42657d9..a9c6a68 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -47,6 +47,69 @@ Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple, IPhoneOSVersionMin = "3.0"; } +// FIXME: Can we tablegen this? +static const char *GetArmArchForMArch(llvm::StringRef Value) { + if (Value == "armv6k") + return "armv6"; + + if (Value == "armv5tej") + return "armv5"; + + if (Value == "xscale") + return "xscale"; + + if (Value == "armv4t") + return "armv4t"; + + if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" || + Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" || + Value == "armv7m") + return "armv7"; + + return 0; +} + +// FIXME: Can we tablegen this? +static const char *GetArmArchForMCpu(llvm::StringRef Value) { + if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" || + Value == "arm946e-s" || Value == "arm966e-s" || + Value == "arm968e-s" || Value == "arm10e" || + Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" || + Value == "arm1026ej-s") + return "armv5"; + + if (Value == "xscale") + return "xscale"; + + if (Value == "arm1136j-s" || Value == "arm1136jf-s" || + Value == "arm1176jz-s" || Value == "arm1176jzf-s") + return "armv6"; + + if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3") + return "armv7"; + + return 0; +} + +llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const { + switch (getTriple().getArch()) { + default: + return getArchName(); + + case llvm::Triple::arm: { + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + if (const char *Arch = GetArmArchForMArch(A->getValue(Args))) + return Arch; + + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + if (const char *Arch = GetArmArchForMCpu(A->getValue(Args))) + return Arch; + + return "arm"; + } + } +} + DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, const unsigned (&DarwinVersion)[3], const unsigned (&_GCCVersion)[3], bool IsIPhoneOS) @@ -118,10 +181,6 @@ DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, Path += ToolChainDir; getProgramPaths().push_back(Path); - Path = getDriver().Dir; - Path += "/../libexec"; - getProgramPaths().push_back(Path); - getProgramPaths().push_back(getDriver().Dir); } @@ -235,13 +294,6 @@ DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, bool IsIPhoneOS) : Darwin(Host, Triple, DarwinVersion, IsIPhoneOS) { - // Add the relative libexec dir (for clang-cc). - // - // FIXME: We should sink clang-cc into libexec/clang/<version>/. - std::string Path = getDriver().Dir; - Path += "/../libexec"; - getProgramPaths().push_back(Path); - // We expect 'as', 'ld', etc. to be adjacent to our install dir. getProgramPaths().push_back(getDriver().Dir); } @@ -253,12 +305,10 @@ void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args, void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - // Check for static linking. - if (Args.hasArg(options::OPT_static)) { - // FIXME: We need to have compiler-rt available (perhaps as - // libclang_static.a) to link against. + // Darwin doesn't support real static executables, don't link any runtime + // libraries with -static. + if (Args.hasArg(options::OPT_static)) return; - } // Reject -static-libgcc for now, we can deal with this when and if someone // cares. This is useful in situations where someone wants to statically link @@ -269,12 +319,52 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, return; } - // Otherwise link libSystem, which should have the support routines. - // - // FIXME: This is only true for 10.6 and beyond. Legacy support isn't - // critical, but it should work... we should just link in the static - // compiler-rt library. + // Otherwise link libSystem, then the dynamic runtime library, and finally any + // target specific static runtime library. CmdArgs.push_back("-lSystem"); + + // Select the dynamic runtime library and the target specific static library. + const char *DarwinStaticLib = 0; + if (isIPhoneOS()) { + CmdArgs.push_back("-lgcc_s.1"); + + // We may need some static functions for armv6/thumb which are required to + // be in the same linkage unit as their caller. + if (getDarwinArchName(Args) == "armv6") + DarwinStaticLib = "libclang_rt.armv6.a"; + } else { + unsigned MacosxVersionMin[3]; + getMacosxVersionMin(Args, MacosxVersionMin); + + // The dynamic runtime library was merged with libSystem for 10.6 and + // beyond; only 10.4 and 10.5 need an additional runtime library. + if (isMacosxVersionLT(MacosxVersionMin, 10, 5)) + CmdArgs.push_back("-lgcc_s.10.4"); + else if (isMacosxVersionLT(MacosxVersionMin, 10, 6)) + CmdArgs.push_back("-lgcc_s.10.5"); + + // For OS X, we only need a static runtime library when targetting 10.4, to + // provide versions of the static functions which were omitted from + // 10.4.dylib. + if (isMacosxVersionLT(MacosxVersionMin, 10, 5)) + DarwinStaticLib = "libclang_rt.10.4.a"; + } + + /// Add the target specific static library, if needed. + if (DarwinStaticLib) { + llvm::sys::Path P(getDriver().ResourceDir); + P.appendComponent("lib"); + P.appendComponent("darwin"); + P.appendComponent(DarwinStaticLib); + + // For now, allow missing resource libraries to support developers who may + // not have compiler-rt checked out or integrated into their build. + if (!P.exists()) + getDriver().Diag(clang::diag::warn_drv_missing_resource_library) + << P.str(); + else + CmdArgs.push_back(Args.MakeArgString(P.str())); + } } void Darwin::getMacosxVersionMin(const ArgList &Args, @@ -544,10 +634,6 @@ const char *Darwin::GetForcedPicModel() const { Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) : ToolChain(Host, Triple) { - std::string Path(getDriver().Dir); - Path += "/../libexec"; - getProgramPaths().push_back(Path); - getProgramPaths().push_back(getDriver().Dir); } @@ -684,11 +770,6 @@ Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) { - // Path mangling to find libexec - std::string Path(getDriver().Dir); - - Path += "/../libexec"; - getProgramPaths().push_back(Path); getProgramPaths().push_back(getDriver().Dir); getFilePaths().push_back(getDriver().Dir + "/../lib"); @@ -753,10 +834,6 @@ DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) { // Path mangling to find libexec - std::string Path(getDriver().Dir); - - Path += "/../libexec"; - getProgramPaths().push_back(Path); getProgramPaths().push_back(getDriver().Dir); getFilePaths().push_back(getDriver().Dir + "/../lib"); |