diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-11-03 04:37:51 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-11-03 04:37:51 +0000 |
commit | 29a88f441fb9d82cfa898774cf6711e54bcba2ff (patch) | |
tree | d293805dcfc3cefb20c2ca7c33d364c72c61e412 /lib/Driver/Tools.cpp | |
parent | 79ca1ee4b637c01458584bb571f1b309180c780d (diff) |
Switch clang to run ld directly on linux. I tested this on all the linux
distros listed by running
gcc main.o -o main
g++ main.o -o main
gcc main.o -o main -static
g++ main.o -o main -static
gcc f.o -o f.so -shared
g++ f.o -o f.so -shared
and comparing the ld line with the one created by clang. I also added
-m32/m64 in distros that support it.
While I tested many distros, there will always be more. If you are hit by this
it should be somewhat easy to add your distro. If you are in a hurry, do
revert this, but please inform how to detect you distro and the ld command
lines produced by the above gcc invocations. Most distros have some patches
on gcc :-(
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118149 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r-- | lib/Driver/Tools.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 7ba1dc8be7..1fcae40076 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -3134,6 +3134,145 @@ void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } +void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const toolchains::Linux& ToolChain = + static_cast<const toolchains::Linux&>(getToolChain()); + const Driver &D = ToolChain.getDriver(); + ArgStringList CmdArgs; + + for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(), + e = ToolChain.ExtraOpts.end(); + i != e; ++i) + CmdArgs.push_back(i->c_str()); + + if (!Args.hasArg(options::OPT_static)) { + CmdArgs.push_back("--eh-frame-hdr"); + } + + CmdArgs.push_back("-m"); + if (ToolChain.getArch() == llvm::Triple::x86) + CmdArgs.push_back("elf_i386"); + else if (ToolChain.getArch() == llvm::Triple::arm) + CmdArgs.push_back("armelf_linux_eabi"); + else + CmdArgs.push_back("elf_x86_64"); + + if (Args.hasArg(options::OPT_static)) { + if (ToolChain.getArch() == llvm::Triple::arm) + CmdArgs.push_back("-Bstatic"); + else + CmdArgs.push_back("-static"); + } else if (Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back("-shared"); + } + + if (ToolChain.getArch() == llvm::Triple::arm || + (!Args.hasArg(options::OPT_static) && + !Args.hasArg(options::OPT_shared))) { + CmdArgs.push_back("-dynamic-linker"); + if (ToolChain.getArch() == llvm::Triple::x86) + CmdArgs.push_back("/lib/ld-linux.so.2"); + else if (ToolChain.getArch() == llvm::Triple::arm) + CmdArgs.push_back("/lib/ld-linux.so.3"); + else + CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2"); + } + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + if (!Args.hasArg(options::OPT_shared)) + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o"))); + + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); + + const char *crtbegin; + if (Args.hasArg(options::OPT_static)) + crtbegin = "crtbeginT.o"; + else if (Args.hasArg(options::OPT_shared)) + crtbegin = "crtbeginS.o"; + else + crtbegin = "crtbegin.o"; + + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); + + Args.AddAllArgs(CmdArgs, options::OPT_L); + + const ToolChain::path_list Paths = ToolChain.getFilePaths(); + + for (ToolChain::path_list::const_iterator i = Paths.begin(), + e = Paths.end(); + i != e; ++i) { + const std::string &s = *i; + CmdArgs.push_back(Args.MakeArgString(std::string("-L") + s)); + } + + AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); + + if (D.CCCIsCXX) { + ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); + CmdArgs.push_back("-lm"); + } + + if (Args.hasArg(options::OPT_static)) + CmdArgs.push_back("--start-group"); + + if (!D.CCCIsCXX) + CmdArgs.push_back("-lgcc"); + + if (Args.hasArg(options::OPT_static)) { + if (D.CCCIsCXX) + CmdArgs.push_back("-lgcc"); + } else { + if (!D.CCCIsCXX) + CmdArgs.push_back("--as-needed"); + CmdArgs.push_back("-lgcc_s"); + if (!D.CCCIsCXX) + CmdArgs.push_back("--no-as-needed"); + } + + if (Args.hasArg(options::OPT_static)) + CmdArgs.push_back("-lgcc_eh"); + else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX) + CmdArgs.push_back("-lgcc"); + + CmdArgs.push_back("-lc"); + + if (Args.hasArg(options::OPT_static)) + CmdArgs.push_back("--end-group"); + else { + if (!D.CCCIsCXX) + CmdArgs.push_back("-lgcc"); + + if (!D.CCCIsCXX) + CmdArgs.push_back("--as-needed"); + CmdArgs.push_back("-lgcc_s"); + if (!D.CCCIsCXX) + CmdArgs.push_back("--no-as-needed"); + + if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX) + CmdArgs.push_back("-lgcc"); + } + + if (Args.hasArg(options::OPT_shared)) + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o"))); + else + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); + + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); + + if (Args.hasArg(options::OPT_use_gold_plugin)) { + CmdArgs.push_back("-plugin"); + std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so"; + CmdArgs.push_back(Args.MakeArgString(Plugin)); + } + + C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs)); +} void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, |