From: Daniel Dunbar Date: Fri, 18 Sep 2009 08:15:13 +0000 (+0000) Subject: Split Darwin toolchain into Clang and GCC Darwin toolchains with a common base. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d4612b829500cbe04a2eafca74afac703e34934;p=clang Split Darwin toolchain into Clang and GCC Darwin toolchains with a common base. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82213 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp index e950b4a08e..08c4ef4900 100644 --- a/lib/Driver/HostInfo.cpp +++ b/lib/Driver/HostInfo.cpp @@ -144,14 +144,14 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args, TCTriple.setArch(Arch); // If we recognized the arch, match it to the toolchains we support. - if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) - TC = new toolchains::Darwin(*this, TCTriple, DarwinVersion, GCCVersion, - false); - else if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) - TC = new toolchains::Darwin(*this, TCTriple, DarwinVersion, GCCVersion, - true); + if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) { + // We still use the legacy DarwinGCC toolchain on X86. + TC = new toolchains::DarwinGCC(*this, TCTriple, DarwinVersion, GCCVersion, + false); + } else if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) + TC = new toolchains::DarwinClang(*this, TCTriple, DarwinVersion, true); else - TC = new toolchains::Darwin_GCC(*this, TCTriple); + TC = new toolchains::Darwin_Generic_GCC(*this, TCTriple); } return TC; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 5db58c1691..3d692b0404 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -29,23 +29,31 @@ using namespace clang::driver::toolchains; /// Darwin - Darwin tool chain for i386 and x86_64. Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&_DarwinVersion)[3], - const unsigned (&_GCCVersion)[3], - bool _IsIPhone) - : ToolChain(Host, Triple) { + const unsigned (&_DarwinVersion)[3], bool _IsIPhoneOS) + : ToolChain(Host, Triple), + IsIPhoneOS(_IsIPhoneOS) +{ DarwinVersion[0] = _DarwinVersion[0]; DarwinVersion[1] = _DarwinVersion[1]; DarwinVersion[2] = _DarwinVersion[2]; - GCCVersion[0] = _GCCVersion[0]; - GCCVersion[1] = _GCCVersion[1]; - GCCVersion[2] = _GCCVersion[2]; - IsIPhone = _IsIPhone; llvm::raw_string_ostream(MacosxVersionMin) << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1]; // FIXME: Lift default up. IPhoneOSVersionMin = "3.0"; +} + +DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, + const unsigned (&DarwinVersion)[3], + const unsigned (&_GCCVersion)[3], bool IsIPhoneOS) + : Darwin(Host, Triple, DarwinVersion, IsIPhoneOS) +{ + GCCVersion[0] = _GCCVersion[0]; + GCCVersion[1] = _GCCVersion[1]; + GCCVersion[2] = _GCCVersion[2]; + + // Set up the tool chain paths to match gcc. ToolChainDir = "i686-apple-darwin"; ToolChainDir += llvm::utostr(DarwinVersion[0]); @@ -134,8 +142,8 @@ Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { return *T; } -void Darwin::AddLinkSearchPathArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { +void DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { // FIXME: Derive these correctly. if (getArchName() == "x86_64") { CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + @@ -154,8 +162,8 @@ void Darwin::AddLinkSearchPathArgs(const ArgList &Args, "/../../..")); } -void Darwin::AddLinkRuntimeLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { +void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { unsigned MacosxVersionMin[3]; getMacosxVersionMin(Args, MacosxVersionMin); @@ -167,7 +175,7 @@ void Darwin::AddLinkRuntimeLibArgs(const ArgList &Args, CmdArgs.push_back("-lgcc_eh"); } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { // Derived from darwin_iphoneos_libgcc spec. - if (isIPhone()) { + if (isIPhoneOS()) { CmdArgs.push_back("-lgcc_s.1"); } else { CmdArgs.push_back("-lgcc_s.10.5"); @@ -190,7 +198,7 @@ void Darwin::AddLinkRuntimeLibArgs(const ArgList &Args, CmdArgs.push_back("-lgcc_s.10.5"); } - if (isIPhone() || isMacosxVersionLT(MacosxVersionMin, 10, 6)) { + if (isIPhoneOS() || isMacosxVersionLT(MacosxVersionMin, 10, 6)) { CmdArgs.push_back("-lgcc"); CmdArgs.push_back("-lSystem"); } else { @@ -200,6 +208,46 @@ void Darwin::AddLinkRuntimeLibArgs(const ArgList &Args, } } +DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, + const unsigned (&DarwinVersion)[3], + bool IsIPhoneOS) + : Darwin(Host, Triple, DarwinVersion, IsIPhoneOS) +{ + // We expect 'as', 'ld', etc. to be adjacent to our install dir. + getProgramPaths().push_back(getHost().getDriver().Dir); +} + +void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + // The Clang toolchain uses explicit paths for internal libraries. +} + +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. + 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 + // something like libstdc++, and needs its runtime support routines. + if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { + getHost().getDriver().Diag(clang::diag::err_drv_unsupported_opt) + << A->getAsString(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. + CmdArgs.push_back("-lSystem"); +} + void Darwin::getMacosxVersionMin(const ArgList &Args, unsigned (&Res)[3]) const { if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) { @@ -240,7 +288,7 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args, // // FIXME: Are there iPhone overrides for this? - if (!isIPhone()) { + if (!isIPhoneOS()) { // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version // from the host. const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET"); diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 91e5750dd6..6088d9617c 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -22,9 +22,9 @@ namespace clang { namespace driver { namespace toolchains { - /// Generic_GCC - A tool chain using the 'gcc' command to perform - /// all subcommands; this relies on gcc translating the majority of - /// command line options. +/// Generic_GCC - A tool chain using the 'gcc' command to perform +/// all subcommands; this relies on gcc translating the majority of +/// command line options. class VISIBILITY_HIDDEN Generic_GCC : public ToolChain { protected: mutable llvm::DenseMap Tools; @@ -44,21 +44,18 @@ public: virtual const char *GetForcedPicModel() const; }; -/// Darwin - Darwin tool chain. +/// Darwin - The base Darwin tool chain. class VISIBILITY_HIDDEN Darwin : public ToolChain { mutable llvm::DenseMap Tools; /// Darwin version of tool chain. unsigned DarwinVersion[3]; - /// GCC version to use. - unsigned GCCVersion[3]; - - /// Whether this is this an iPhone toolchain. - bool IsIPhone; - - /// The directory suffix for this tool chain. - std::string ToolChainDir; + /// Whether this is this an iPhoneOS toolchain. + // + // FIXME: This should go away, such differences should be completely + // determined by the target triple. + bool IsIPhoneOS; /// The default macosx-version-min of this tool chain; empty until /// initialized. @@ -71,9 +68,7 @@ class VISIBILITY_HIDDEN Darwin : public ToolChain { public: Darwin(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&DarwinVersion)[3], - const unsigned (&GCCVersion)[3], - bool IsIPhone); + const unsigned (&DarwinVersion)[3], bool IsIPhoneOS); ~Darwin(); /// @name Darwin Specific Toolchain API @@ -122,13 +117,15 @@ public: /// \param Args - The input argument list. /// \param CmdArgs [out] - The command argument list to append the paths /// (prefixed by -L) to. - void AddLinkSearchPathArgs(const ArgList &Args, ArgStringList &CmdArgs) const; + virtual void AddLinkSearchPathArgs(const ArgList &Args, + ArgStringList &CmdArgs) const = 0; /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler /// runtime library. - void AddLinkRuntimeLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const; + virtual void AddLinkRuntimeLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const = 0; - bool isIPhone() const { return IsIPhone; } + bool isIPhoneOS() const { return IsIPhoneOS; } /// } /// @name ToolChain Implementation @@ -147,10 +144,53 @@ public: /// } }; - /// Darwin_GCC - Generic Darwin tool chain using gcc. -class VISIBILITY_HIDDEN Darwin_GCC : public Generic_GCC { +/// DarwinClang - The Darwin toolchain used by Clang. +class VISIBILITY_HIDDEN DarwinClang : public Darwin { +public: + DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, + const unsigned (&DarwinVersion)[3], bool IsIPhoneOS); + + /// @name Darwin ToolChain Implementation + /// { + + virtual void AddLinkSearchPathArgs(const ArgList &Args, + ArgStringList &CmdArgs) const; + + virtual void AddLinkRuntimeLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const; + + /// } +}; + +/// DarwinGCC - The Darwin toolchain used by GCC. +class VISIBILITY_HIDDEN DarwinGCC : public Darwin { + /// GCC version to use. + unsigned GCCVersion[3]; + + /// The directory suffix for this tool chain. + std::string ToolChainDir; + +public: + DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, + const unsigned (&DarwinVersion)[3], const unsigned (&GCCVersion)[3], + bool IsIPhoneOS); + + /// @name Darwin ToolChain Implementation + /// { + + virtual void AddLinkSearchPathArgs(const ArgList &Args, + ArgStringList &CmdArgs) const; + + virtual void AddLinkRuntimeLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const; + + /// } +}; + +/// Darwin_Generic_GCC - Generic Darwin tool chain using gcc. +class VISIBILITY_HIDDEN Darwin_Generic_GCC : public Generic_GCC { public: - Darwin_GCC(const HostInfo &Host, const llvm::Triple& Triple) + Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) {} virtual const char *GetDefaultRelocationModel() const { return "pic"; } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 66053178e1..9472928f40 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1588,7 +1588,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, // Derived from asm spec. AddDarwinArch(Args, CmdArgs); - if (!getDarwinToolChain().isIPhone() || + if (!getDarwinToolChain().isIPhoneOS() || Args.hasArg(options::OPT_force__cpusubtype__ALL)) CmdArgs.push_back("-force_cpusubtype_ALL"); @@ -1792,7 +1792,7 @@ void darwin::Link::AddLinkArgs(const ArgList &Args, Args.AddLastArg(CmdArgs, options::OPT_all__load); Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); - if (getDarwinToolChain().isIPhone()) + if (getDarwinToolChain().isIPhoneOS()) Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); Args.AddLastArg(CmdArgs, options::OPT_dead__strip); Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); @@ -1807,7 +1807,7 @@ void darwin::Link::AddLinkArgs(const ArgList &Args, if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ) && !Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { // Add default version min. - if (!getDarwinToolChain().isIPhone()) { + if (!getDarwinToolChain().isIPhoneOS()) { CmdArgs.push_back("-macosx_version_min"); CmdArgs.push_back(getDarwinToolChain().getMacosxVersionStr()); } else { @@ -1849,7 +1849,7 @@ void darwin::Link::AddLinkArgs(const ArgList &Args, Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot"); - if (getDarwinToolChain().isIPhone()) { + if (getDarwinToolChain().isIPhoneOS()) { if (!Args.hasArg(options::OPT_isysroot)) { CmdArgs.push_back("-syslibroot"); CmdArgs.push_back("/Developer/SDKs/Extra"); @@ -1953,7 +1953,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lcrt0.o"); } else { // Derived from darwin_crt1 spec. - if (getDarwinToolChain().isIPhone()) { + if (getDarwinToolChain().isIPhoneOS()) { CmdArgs.push_back("-lcrt1.o"); } else if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 5))