Any objections to submitting this patch? Matthew Curtis.
On 9/6/2012 4:24 PM, Matthew Curtis wrote:
Hello all, This patch updates the Hexagon ToolChain: - reimplement hexagon::Link::ConstructJob to call linker directly rather than going through gcc - add/improve support for small data threshold, pic, and other args - add overrides for include paths, et. al. - minor refactoring Please let me know if there are any problems or concerns. Thanks. Cheers, Matthew Curtis. _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
>From 4f440d78a7af2cd7edf83649d8baaa22ae8ec708 Mon Sep 17 00:00:00 2001 From: Matthew Curtis <[email protected]> Date: Thu, 30 Aug 2012 11:46:24 -0500 Subject: [PATCH] Update Hexagon ToolChain (call linker directly, addl args, etc) - reimplement hexagon::Link::ConstructJob to call linker directly rather than going through gcc - add/improve support for small data threshold, pic, and other args - add overrides for include paths et. al. - minor refactoring --- include/clang/Driver/Options.td | 5 +- lib/Driver/Driver.cpp | 2 +- lib/Driver/ToolChains.cpp | 206 +++++++++++++++++++++++++- lib/Driver/ToolChains.h | 45 ++++-- lib/Driver/Tools.cpp | 305 ++++++++++++++++++++++++++------------- 5 files changed, 437 insertions(+), 126 deletions(-) diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index c7698a2..6f2f98a 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -158,7 +158,8 @@ def E : Flag<"-E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>, HelpText<"Only run the preprocessor">; def F : JoinedOrSeparate<"-F">, Flags<[RenderJoined,CC1Option]>, HelpText<"Add directory to framework include search path">; -def G : Separate<"-G">, Flags<[DriverOption]>; +def G : JoinedOrSeparate<"-G">, Flags<[DriverOption]>; +def G_EQ : Joined<"-G=">, Flags<[DriverOption]>; def H : Flag<"-H">, Flags<[CC1Option]>, HelpText<"Show header includes and nesting depth">; def I_ : Flag<"-I-">, Group<I_Group>; @@ -830,6 +831,7 @@ def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Gr def mno_omit_leaf_frame_pointer : Flag<"-mno-omit-leaf-frame-pointer">, Group<f_Group>; def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">, Group<f_Group>, HelpText<"Omit frame pointer setup for leaf functions.">, Flags<[CC1Option]>; +def moslib_EQ : Joined<"-moslib=">, Group<m_Group>; def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>; def mred_zone : Flag<"-mred-zone">, Group<m_Group>; def mregparm_EQ : Joined<"-mregparm=">, Group<m_Group>; @@ -994,6 +996,7 @@ def undef : Flag<"-undef">, Group<u_Group>, Flags<[CC1Option]>, def unexported__symbols__list : Separate<"-unexported_symbols_list">; def u : JoinedOrSeparate<"-u">, Group<u_Group>; def use_gold_plugin : Flag<"-use-gold-plugin">; +def use_collect2 : Flag<"-use-collect2">; def v : Flag<"-v">, Flags<[CC1Option]>, HelpText<"Show commands to run and use verbose output">; def verify : Flag<"-verify">, Flags<[DriverOption,CC1Option]>, diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 240d66f..48ecd0b 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1790,7 +1790,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, break; case llvm::Triple::Linux: if (Target.getArch() == llvm::Triple::hexagon) - TC = new toolchains::Hexagon_TC(*this, Target); + TC = new toolchains::Hexagon_TC(*this, Target, Args); else TC = new toolchains::Linux(*this, Target, Args); break; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 8876d95..e03fad7 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1422,11 +1422,112 @@ const char *Generic_GCC::GetForcedPicModel() const { } /// Hexagon Toolchain -Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple) - : ToolChain(D, Triple) { - getProgramPaths().push_back(getDriver().getInstalledDir()); - if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) - getProgramPaths().push_back(getDriver().Dir); +std::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) +{ + std::string InstallRelDir; + std::string PrefixRelDir; + + // Locate the rest of the toolchain ... + if (strlen(GCC_INSTALL_PREFIX)) + return std::string(GCC_INSTALL_PREFIX); + else if (llvm::sys::fs::exists(InstallRelDir = InstalledDir + "/../../gnu")) + return InstallRelDir; + else if (llvm::sys::fs::exists( + PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu")) + return PrefixRelDir; + else + return InstallRelDir; +} + +static void GetHexagonLibraryPaths( + const ArgList &Args, + const std::string Ver, + const std::string MarchString, + const std::string &InstalledDir, + ToolChain::path_list *LibPaths) +{ + bool buildingLib = Args.hasArg(options::OPT_shared); + + //---------------------------------------------------------------------------- + // -L Args + //---------------------------------------------------------------------------- + for (arg_iterator + it = Args.filtered_begin(options::OPT_L), + ie = Args.filtered_end(); + it != ie; + ++it) { + for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) + LibPaths->push_back((*it)->getValue(Args, i)); + } + + //---------------------------------------------------------------------------- + // Other standard paths + //---------------------------------------------------------------------------- + const std::string MarchSuffix = "/" + MarchString; + const std::string G0Suffix = "/G0"; + const std::string MarchG0Suffix = MarchSuffix + G0Suffix; + const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/"; + + // lib/gcc/hexagon/... + std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/"; + if (buildingLib) { + LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix); + LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix); + } + LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix); + LibPaths->push_back(LibGCCHexagonDir + Ver); + + // lib/gcc/... + LibPaths->push_back(RootDir + "lib/gcc"); + + // hexagon/lib/... + std::string HexagonLibDir = RootDir + "hexagon/lib"; + if (buildingLib) { + LibPaths->push_back(HexagonLibDir + MarchG0Suffix); + LibPaths->push_back(HexagonLibDir + G0Suffix); + } + LibPaths->push_back(HexagonLibDir + MarchSuffix); + LibPaths->push_back(HexagonLibDir); +} + +Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple, + const ArgList &Args) + : Linux(D, Triple, Args) { + const std::string InstalledDir(getDriver().getInstalledDir()); + + // Note: Generic_GCC::Generic_GCC adds InstalledDir and DriverDir + + const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir); + + const std::string BinDir(GnuDir + "/bin"); + if (llvm::sys::fs::exists(BinDir)) + getProgramPaths().push_back(BinDir); + + // Determine version of GCC Libraries and Headers to use + const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); + llvm::error_code ec; + GCCVersion MaxVersion= GCCVersion::Parse("0.0.0"); + for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de; + !ec && di != de; di = di.increment(ec)) { + GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path())); + if (MaxVersion < cv) + MaxVersion = cv; + } + GCCLibAndIncVersion= MaxVersion; + + ToolChain::path_list *LibPaths= &getFilePaths(); + + // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets + // 'elf' OS type, so the Linux paths are not appropriate. When we actually + // support 'linux' we'll need to fix this up + LibPaths->clear(); + + GetHexagonLibraryPaths( + Args, + GetGCCLibAndIncVersion(), + GetTargetCPU(Args), + InstalledDir, + LibPaths); } Hexagon_TC::~Hexagon_TC() { @@ -1485,7 +1586,100 @@ const char *Hexagon_TC::GetDefaultRelocationModel() const { const char *Hexagon_TC::GetForcedPicModel() const { return 0; -} // End Hexagon +} + +void Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + llvm::sys::Path InstallDir(D.InstalledDir); + std::string Ver(GetGCCLibAndIncVersion()); + std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir); + std::string HexagonDir(GnuDir + + "/lib/gcc/hexagon/" + + Ver); + addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include"); + addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed"); + addExternCSystemInclude(DriverArgs, CC1Args, + GnuDir + + "/hexagon/include"); +} + +void Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + const Driver &D = getDriver(); + llvm::sys::Path IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir)); + + IncludeDir.appendComponent ("hexagon/include/c++/4.4.0/"); + addSystemInclude (DriverArgs, CC1Args, IncludeDir.str()); +} + +ToolChain::CXXStdlibType +Hexagon_TC::GetCXXStdlibType(const ArgList &Args) const { + Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); + if (!A) + return ToolChain::CST_Libstdcxx; + + StringRef Value = A->getValue(Args); + if (Value != "libstdc++") { + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); + } + + return ToolChain::CST_Libstdcxx; +} + +static Arg* GetLastHexagonArchArg (const ArgList &Args) +{ + Arg * A = NULL; + + for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); + it != ie; ++it) { + if ((*it)->getOption().matches(options::OPT_march_EQ) || + (*it)->getOption().matches(options::OPT_mcpu_EQ)) { + A = *it; + A->claim(); + } + else if ((*it)->getOption().matches(options::OPT_m_Joined)){ + StringRef Value = (*it)->getValue(Args,0); + if (Value.startswith("v")) { + A = *it; + A->claim(); + } + } + } + return A; +} + +StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) +{ + Arg *A; + llvm::StringRef WhichHexagon; + + // Select the default CPU (v4) if none was given or detection failed. + if ((A = GetLastHexagonArchArg (Args))) { + WhichHexagon = A->getValue(Args); + if (WhichHexagon == "") + return "v4"; + else if (WhichHexagon.startswith("hexagon")) + return WhichHexagon.substr(sizeof("hexagon") - 1); + else + return WhichHexagon; + } + else + return "v4"; +} +// End Hexagon /// TCEToolChain - A tool chain using the llvm bitcode tools to perform diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 752cdfd..6110695 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -144,22 +144,6 @@ protected: /// @} }; -class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public ToolChain { -protected: - mutable llvm::DenseMap<unsigned, Tool*> Tools; - -public: - Hexagon_TC(const Driver &D, const llvm::Triple& Triple); - ~Hexagon_TC(); - - virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, - const ActionList &Inputs) const; - - virtual bool IsUnwindTablesDefault() const; - virtual const char *GetDefaultRelocationModel() const; - virtual const char *GetForcedPicModel() const; -}; - /// Darwin - The base Darwin tool chain. class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { public: @@ -529,6 +513,35 @@ private: ArgStringList &CC1Args); }; +class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public Linux { +protected: + mutable llvm::DenseMap<unsigned, Tool*> Tools; + + GCCVersion GCCLibAndIncVersion; + +public: + Hexagon_TC(const Driver &D, const llvm::Triple& Triple, + const ArgList &Args); + ~Hexagon_TC(); + + virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, + const ActionList &Inputs) const; + + virtual bool IsUnwindTablesDefault() const; + virtual const char *GetDefaultRelocationModel() const; + virtual const char *GetForcedPicModel() const; + virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const; + virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const; + virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const; + + StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; } + + static std::string GetGnuDir(const std::string &InstalledDir); + + static StringRef GetTargetCPU(const ArgList &Args); +}; /// TCEToolChain - A tool chain using the llvm bitcode tools to perform /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index c0ce504..7431587 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1151,61 +1151,31 @@ void Clang::AddX86TargetArgs(const ArgList &Args, } } -static Arg* getLastHexagonArchArg (const ArgList &Args) -{ - Arg * A = NULL; - - for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); - it != ie; ++it) { - if ((*it)->getOption().matches(options::OPT_march_EQ) || - (*it)->getOption().matches(options::OPT_mcpu_EQ)) { - A = *it; - A->claim(); - } - else if ((*it)->getOption().matches(options::OPT_m_Joined)){ - StringRef Value = (*it)->getValue(Args,0); - if (Value.startswith("v")) { - A = *it; - A->claim(); - } - } - } - return A; -} - -static StringRef getHexagonTargetCPU(const ArgList &Args) -{ - Arg *A; - llvm::StringRef WhichHexagon; - - // Select the default CPU (v4) if none was given or detection failed. - if ((A = getLastHexagonArchArg (Args))) { - WhichHexagon = A->getValue(Args); - if (WhichHexagon == "") - return "v4"; - else - return WhichHexagon; - } - else - return "v4"; -} - void Clang::AddHexagonTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { llvm::Triple Triple = getToolChain().getTriple(); CmdArgs.push_back("-target-cpu"); - CmdArgs.push_back(Args.MakeArgString("hexagon" + getHexagonTargetCPU(Args))); + CmdArgs.push_back(Args.MakeArgString( + "hexagon" + + toolchains::Hexagon_TC::GetTargetCPU(Args))); CmdArgs.push_back("-fno-signed-char"); - CmdArgs.push_back("-nobuiltininc"); - - if (Args.hasArg(options::OPT_mqdsp6_compat)) - CmdArgs.push_back("-mqdsp6-compat"); - + CmdArgs.push_back("-mqdsp6-compat"); + CmdArgs.push_back("-Wreturn-type"); + bool PICEnabled = (Args.hasArg(options::OPT_fPIC) || + Args.hasArg(options::OPT_fpic)); if (Arg *A = Args.getLastArg(options::OPT_G, + options::OPT_G_EQ, + options::OPT_fpic, + options::OPT_fPIC, options::OPT_msmall_data_threshold_EQ)) { - std::string SmallDataThreshold="-small-data-threshold="; - SmallDataThreshold += A->getValue(Args); + // "-G0", "-G 0", and "-G=0" are the same driver flags. + // They are mapped to llvm flag "-hexagon-small-data-threshold=0". + std::string SmallDataThreshold="-hexagon-small-data-threshold="; + if(PICEnabled) + SmallDataThreshold += "0"; + else + SmallDataThreshold += A->getValue(Args); CmdArgs.push_back ("-mllvm"); CmdArgs.push_back(Args.MakeArgString(SmallDataThreshold)); A->claim(); @@ -3280,9 +3250,10 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; - + bool PICEnabled = (Args.hasArg(options::OPT_fPIC) || + Args.hasArg(options::OPT_fpic)); std::string MarchString = "-march="; - MarchString += getHexagonTargetCPU(Args); + MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args); CmdArgs.push_back(Args.MakeArgString(MarchString)); RenderExtraToolArgs(JA, CmdArgs); @@ -3295,6 +3266,21 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsyntax-only"); } + if (Arg *A = Args.getLastArg(options::OPT_G, + options::OPT_G_EQ, + options::OPT_fpic, + options::OPT_fPIC, + options::OPT_msmall_data_threshold_EQ)) { + if(PICEnabled) + CmdArgs.push_back(Args.MakeArgString(std::string("-G0"))); + else + CmdArgs.push_back(Args.MakeArgString(std::string("-G") + + A->getValue(Args))); + } + + Args.AddAllArgs(CmdArgs, options::OPT_g_Group); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, + options::OPT_Xassembler); // Only pass -x if gcc will understand it; otherwise hope gcc // understands the suffix correctly. The main use case this would go @@ -3341,77 +3327,192 @@ void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA, const ArgList &Args, const char *LinkingOutput) const { - const Driver &D = getToolChain().getDriver(); + const toolchains::Hexagon_TC& ToolChain = + static_cast<const toolchains::Hexagon_TC&>(getToolChain()); + const Driver &D = ToolChain.getDriver(); + ArgStringList CmdArgs; - for (ArgList::const_iterator - it = Args.begin(), ie = Args.end(); it != ie; ++it) { - Arg *A = *it; - if (A->getOption().hasForwardToGCC()) { - // Don't forward any -g arguments to assembly steps. - if (isa<AssembleJobAction>(JA) && - A->getOption().matches(options::OPT_g_Group)) - continue; + //---------------------------------------------------------------------------- + // + //---------------------------------------------------------------------------- + bool hasStaticArg = Args.hasArg(options::OPT_static); + bool buildingLib = Args.hasArg(options::OPT_shared); + bool buildPIE = Args.hasArg(options::OPT_pie); + bool PICEnabled = (Args.hasArg(options::OPT_fPIC) || + Args.hasArg(options::OPT_fpic)); + bool incStdLib = !Args.hasArg(options::OPT_nostdlib); + bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles); + bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs); + bool useShared = buildingLib && !hasStaticArg; + + //---------------------------------------------------------------------------- + // Silence warnings for various options + //---------------------------------------------------------------------------- - // It is unfortunate that we have to claim here, as this means - // we will basically never report anything interesting for - // platforms using a generic gcc, even if we are just using gcc - // to get to the assembler. - A->claim(); - A->render(Args, CmdArgs); - } + Args.ClaimAllArgs(options::OPT_g_Group); + Args.ClaimAllArgs(options::OPT_emit_llvm); + Args.ClaimAllArgs(options::OPT_w); // Other warning options are already + // handled somewhere else. + Args.ClaimAllArgs(options::OPT_static_libgcc); + + //---------------------------------------------------------------------------- + // + //---------------------------------------------------------------------------- + if (Args.hasArg(options::OPT_s)) + CmdArgs.push_back("-s"); + + for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(), + e = ToolChain.ExtraOpts.end(); + i != e; ++i) + CmdArgs.push_back(i->c_str()); + + std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args); + CmdArgs.push_back(Args.MakeArgString("-m" + MarchString)); + + if (buildingLib) { + CmdArgs.push_back("-shared"); + CmdArgs.push_back("-call_shared"); // should be the default, but doing as + // hexagon-gcc does } - RenderExtraToolArgs(JA, CmdArgs); + if (hasStaticArg) + CmdArgs.push_back("-static"); - // Add Arch Information - Arg *A; - if ((A = getLastHexagonArchArg(Args))) { - if (A->getOption().matches(options::OPT_m_Joined)) - A->render(Args, CmdArgs); + if (buildPIE && !buildingLib) + CmdArgs.push_back("-pie"); + + if (Arg *A = Args.getLastArg(options::OPT_G, + options::OPT_G_EQ, + options::OPT_fPIC, + options::OPT_fpic, + options::OPT_msmall_data_threshold_EQ)) { + if(PICEnabled) + CmdArgs.push_back(Args.MakeArgString(std::string("-G0"))); else - CmdArgs.push_back (Args.MakeArgString("-m" + getHexagonTargetCPU(Args))); + CmdArgs.push_back(Args.MakeArgString(std::string("-G") + + A->getValue(Args))); } - else { - CmdArgs.push_back (Args.MakeArgString("-m" + getHexagonTargetCPU(Args))); + + //---------------------------------------------------------------------------- + // + //---------------------------------------------------------------------------- + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + const std::string MarchSuffix = "/" + MarchString; + const std::string G0Suffix = "/G0"; + const std::string MarchG0Suffix = MarchSuffix + G0Suffix; + const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir) + + "/"; + const std::string StartFilesDir = RootDir + + "hexagon/lib" + + (buildingLib + ? MarchG0Suffix : MarchSuffix); + + //---------------------------------------------------------------------------- + // moslib + //---------------------------------------------------------------------------- + std::vector<std::string> oslibs; + bool hasStandalone= false; + + for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ), + ie = Args.filtered_end(); it != ie; ++it) { + (*it)->claim(); + oslibs.push_back((*it)->getValue(Args)); + hasStandalone = hasStandalone || (oslibs.back() == "standalone"); + } + if (oslibs.empty()) { + oslibs.push_back("standalone"); + hasStandalone = true; } - CmdArgs.push_back("-mqdsp6-compat"); + //---------------------------------------------------------------------------- + // Start Files + //---------------------------------------------------------------------------- + if (incStdLib && incStartFiles) { - const char *GCCName; - if (C.getDriver().CCCIsCXX) - GCCName = "hexagon-g++"; - else - GCCName = "hexagon-gcc"; - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); + if (!buildingLib) { + if (hasStandalone) { + CmdArgs.push_back( + Args.MakeArgString(StartFilesDir + "/crt0_standalone.o")); + } + CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o")); + } + if (useShared) + CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/initS.o")); + else + CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/init.o")); + } + + //---------------------------------------------------------------------------- + // Library Search Paths + //---------------------------------------------------------------------------- + const ToolChain::path_list &LibPaths = ToolChain.getFilePaths(); + for (ToolChain::path_list::const_iterator + i = LibPaths.begin(), + e = LibPaths.end(); + i != e; + ++i) + CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i)); - if (Output.isFilename()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back(Output.getFilename()); - } + //---------------------------------------------------------------------------- + // + //---------------------------------------------------------------------------- + Args.AddAllArgs(CmdArgs, options::OPT_T_Group); + Args.AddAllArgs(CmdArgs, options::OPT_e); + Args.AddAllArgs(CmdArgs, options::OPT_s); + Args.AddAllArgs(CmdArgs, options::OPT_t); + Args.AddAllArgs(CmdArgs, options::OPT_u_Group); - for (InputInfoList::const_iterator - it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { - const InputInfo &II = *it; + AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); - // Don't try to pass LLVM or AST inputs to a generic gcc. - if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || - II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) - D.Diag(clang::diag::err_drv_no_linker_llvm_support) - << getToolChain().getTripleString(); - else if (II.getType() == types::TY_AST) - D.Diag(clang::diag::err_drv_no_ast_support) - << getToolChain().getTripleString(); + //---------------------------------------------------------------------------- + // Libraries + //---------------------------------------------------------------------------- + if (incStdLib && incDefLibs) { + if (D.CCCIsCXX) { + ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); + CmdArgs.push_back("-lm"); + } - if (II.isFilename()) - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back("--start-group"); + + if (!buildingLib) { + for(std::vector<std::string>::iterator i = oslibs.begin(), + e = oslibs.end(); i != e; ++i) + CmdArgs.push_back(Args.MakeArgString("-l" + *i)); + CmdArgs.push_back("-lc"); + } + CmdArgs.push_back("-lgcc"); + + CmdArgs.push_back("--end-group"); + } + + //---------------------------------------------------------------------------- + // End files + //---------------------------------------------------------------------------- + if (incStdLib && incStartFiles) { + if (useShared) + CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/finiS.o")); else - // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ? - II.getInputArg().render(Args, CmdArgs); + CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/fini.o")); } - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + std::string Linker; + std::string Ver(ToolChain.GetGCCLibAndIncVersion()); + + // allow users to override the linker with 'collect2' in case 'hexagon-ld' + // isn't sufficient. + if (Args.hasArg(options::OPT_use_collect2)) + Linker= RootDir + "libexec/gcc/hexagon/" + Ver + "/collect2"; + else + Linker= ToolChain.GetProgramPath("hexagon-ld"); + + C.addCommand( + new Command( + JA, *this, + Args.MakeArgString(Linker), CmdArgs)); } // Hexagon tools end. -- 1.7.6.4
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
