[cfe-commits] r118149 - in /cfe/trunk: include/clang/Driver/Options.td lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp lib/Driver/Tools.h

Rafael Espindola rafael.espindola at gmail.com
Tue Nov 2 21:37:51 PDT 2010


Author: rafael
Date: Tue Nov  2 23:37:51 2010
New Revision: 118149

URL: http://llvm.org/viewvc/llvm-project?rev=118149&view=rev
Log:
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 :-(

Modified:
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Driver/ToolChains.h
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Driver/Tools.h

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=118149&r1=118148&r2=118149&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Tue Nov  2 23:37:51 2010
@@ -610,6 +610,7 @@
 def undef : Flag<"-undef">, Group<u_Group>;
 def unexported__symbols__list : Separate<"-unexported_symbols_list">;
 def u : JoinedOrSeparate<"-u">, Group<u_Group>;
+def use_gold_plugin : Flag<"-use-gold-plugin">;
 def v : Flag<"-v">,
   HelpText<"Show commands to run and use verbose output">;
 def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>;

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=118149&r1=118148&r2=118149&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Tue Nov  2 23:37:51 2010
@@ -23,6 +23,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
 
@@ -1177,28 +1178,338 @@
 
 /// Linux toolchain (very bare-bones at the moment).
 
+enum LinuxDistro {
+  DebianLennyAmd64,
+  DebianLennyi386,
+  DebianSqueezeAmd64,
+  DebianSqueezei386,
+  DebianSqueezeArm,
+  Fedora13X86_64,
+  Fedora13i686,
+  Fedora14X86_64,
+  Fedora14i686,
+  OpenSuse11_3X86_64,
+  OpenSuse11_3i686,
+  UbuntuLucidAmd64,
+  UbuntuLucidi386,
+  UbuntuMaverickAmd64,
+  UbuntuMavericki386,
+  UnknownDistro
+};
+
+static bool IsFedora13(enum LinuxDistro Distro) {
+  return Distro == Fedora13X86_64 || Distro == Fedora13i686;
+}
+
+static bool IsFedora14(enum LinuxDistro Distro) {
+  return Distro == Fedora14X86_64 || Distro == Fedora14i686;
+}
+
+static bool IsFedora(enum LinuxDistro Distro) {
+  return IsFedora13(Distro) || IsFedora14(Distro);
+}
+
+static bool IsOpenSuse(enum LinuxDistro Distro) {
+  return Distro == OpenSuse11_3X86_64 || Distro == OpenSuse11_3i686;
+}
+
+static bool IsUbuntuLucid(enum LinuxDistro Distro) {
+  return Distro == UbuntuLucidi386 || Distro == UbuntuLucidAmd64;
+}
+
+static bool IsUbuntuMaveric(enum LinuxDistro Distro) {
+  return Distro == UbuntuMavericki386 || Distro == UbuntuMaverickAmd64;
+}
+
+static bool IsDebianLenny(enum LinuxDistro Distro) {
+  return Distro == DebianLennyAmd64 || Distro == DebianLennyi386;
+}
+
+static bool IsDebianSqueeze(enum LinuxDistro Distro) {
+  return Distro == DebianSqueezeAmd64 ||
+         Distro == DebianSqueezei386 ||
+         Distro == DebianSqueezeArm;
+}
+
+static bool IsDebian(enum LinuxDistro Distro) {
+  return IsDebianLenny(Distro) || IsDebianSqueeze(Distro);
+}
+
+static bool IsUbuntu(enum LinuxDistro Distro) {
+  return IsUbuntuMaveric(Distro) || IsUbuntuLucid(Distro);
+}
+
+static bool IsDebianBased(enum LinuxDistro Distro) {
+  return IsDebian(Distro) || IsUbuntu(Distro);
+}
+
+static bool IsArm(enum LinuxDistro Distro) {
+  return Distro == DebianSqueezeArm;
+}
+
+static bool IsX86_64(enum LinuxDistro Distro) {
+  switch (Distro) {
+  default:
+    return false;
+  case DebianLennyAmd64:
+  case DebianSqueezeAmd64:
+  case Fedora13X86_64:
+  case Fedora14X86_64:
+  case OpenSuse11_3X86_64:
+  case UbuntuLucidAmd64:
+  case UbuntuMaverickAmd64:
+    return true;
+  }
+}
+
+static bool IsX86(enum LinuxDistro Distro) {
+  return !IsArm(Distro) && !IsX86_64(Distro);
+}
+
+static bool HasMultilib(enum LinuxDistro Distro) {
+  if (IsX86_64(Distro))
+    return true;
+  if (IsArm(Distro))
+    return false;
+  if (IsDebianBased(Distro))
+    return true;
+  return false;
+}
+
+static LinuxDistro DetectLinuxDistro( llvm::Triple::ArchType Arch) {
+  llvm::OwningPtr<const llvm::MemoryBuffer>
+    LsbRelease(llvm::MemoryBuffer::getFile("/etc/lsb-release"));
+  if (LsbRelease) {
+    llvm::StringRef Data = LsbRelease.get()->getBuffer();
+    llvm::SmallVector<llvm::StringRef, 8> Lines;
+    Data.split(Lines, "\n");
+    for (unsigned int i = 0, s = Lines.size(); i < s; ++ i) {
+      if (Lines[i] == "DISTRIB_CODENAME=maverick") {
+        switch (Arch) {
+        default:
+          return UnknownDistro;
+        case llvm::Triple::x86:
+	  return UbuntuMavericki386;
+        case llvm::Triple::x86_64:
+	  return UbuntuMaverickAmd64;
+        }
+      }
+      if (Lines[i] == "DISTRIB_CODENAME=lucid") {
+       switch (Arch) {
+        default:
+          return UnknownDistro;
+        case llvm::Triple::x86:
+	  return UbuntuLucidi386;
+        case llvm::Triple::x86_64:
+	  return UbuntuLucidAmd64;
+        }
+      }
+    }
+    return UnknownDistro;
+  }
+
+  llvm::OwningPtr<const llvm::MemoryBuffer>
+    RHRelease(llvm::MemoryBuffer::getFile("/etc/redhat-release"));
+  if (RHRelease) {
+    llvm::StringRef Data = RHRelease.get()->getBuffer();
+    if (Data.startswith("Fedora release 14 (Laughlin)")) {
+      switch (Arch) {
+      default:
+        return UnknownDistro;
+      case llvm::Triple::x86:
+        return Fedora14i686;
+      case llvm::Triple::x86_64:
+        return Fedora14X86_64;
+      }
+    }
+
+    if (Data.startswith("Fedora release 13 (Goddard)")) {
+      switch (Arch) {
+      default:
+        return UnknownDistro;
+      case llvm::Triple::x86:
+        return Fedora13i686;
+      case llvm::Triple::x86_64:
+        return Fedora13X86_64;
+      }
+    }
+    return UnknownDistro;
+  }
+
+  llvm::OwningPtr<const llvm::MemoryBuffer>
+    DebianVersion(llvm::MemoryBuffer::getFile("/etc/debian_version"));
+  if (DebianVersion) {
+    llvm::StringRef Data = DebianVersion.get()->getBuffer();
+    if (Data[0] == '5') {
+      switch (Arch) {
+      default:
+        return UnknownDistro;
+      case llvm::Triple::x86:
+        return DebianLennyi386;
+      case llvm::Triple::x86_64:
+        return DebianLennyAmd64;
+      }
+    } else if (Data.startswith("squeeze/sid")) {
+      switch (Arch) {
+      default:
+        return UnknownDistro;
+      case llvm::Triple::arm:
+        return DebianSqueezeArm;
+      case llvm::Triple::x86:
+        return DebianSqueezei386;
+      case llvm::Triple::x86_64:
+        return DebianSqueezeAmd64;
+      }
+    }
+    return UnknownDistro;
+  }
+
+  llvm::OwningPtr<const llvm::MemoryBuffer>
+    SuseRelease(llvm::MemoryBuffer::getFile("/etc/SuSE-release"));
+  if (SuseRelease) {
+    llvm::StringRef Data = SuseRelease.get()->getBuffer();
+    if (Data.startswith("openSUSE 11.3")) {
+      switch (Arch) {
+      default:
+        return UnknownDistro;
+      case llvm::Triple::x86:
+        return OpenSuse11_3i686;
+      case llvm::Triple::x86_64:
+        return OpenSuse11_3X86_64;
+      }
+    }
+    return UnknownDistro;
+  }
+
+  return UnknownDistro;
+}
+
 Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
   : Generic_ELF(Host, Triple) {
-  getFilePaths().push_back(getDriver().Dir +
-                           "/../lib/clang/" CLANG_VERSION_STRING "/");
-  getFilePaths().push_back("/lib/");
-  getFilePaths().push_back("/usr/lib/");
-
-  // Depending on the Linux distribution, any combination of lib{,32,64} is
-  // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
-  // openSUSE uses lib and lib64 for the same purpose.
-  getFilePaths().push_back("/lib32/");
-  getFilePaths().push_back("/usr/lib32/");
-  getFilePaths().push_back("/lib64/");
-  getFilePaths().push_back("/usr/lib64/");
-
-  // FIXME: Figure out some way to get gcc's libdir
-  // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
-  // crtbegin.o/crtend.o/etc., and want static versions of various
-  // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
-  // get away with using shared versions in /usr/lib, though.
-  // We could fall back to the approach we used for includes (a massive
-  // list), but that's messy at best.
+
+  std::string Lib32     = "lib";
+  std::string Lib64     = "lib";
+  std::string Suffix32  = "";
+  std::string Suffix64  = "";
+  std::string Base      = "";
+  std::string GccTriple = "";
+
+  llvm::Triple::ArchType Arch =
+    llvm::Triple(getDriver().DefaultHostTriple).getArch();
+  LinuxDistro Distro = DetectLinuxDistro(Arch);
+
+  if (Distro == UnknownDistro)
+    llvm::report_fatal_error("Unknown linux distribution.");
+
+  if (IsUbuntu(Distro))
+    ExtraOpts.push_back("-z relro");
+
+  if (IsArm(Distro))
+    ExtraOpts.push_back("-X");
+
+  if (IsFedora(Distro) || IsUbuntuMaveric(Distro))
+    ExtraOpts.push_back("--hash-style=gnu");
+
+  if (IsDebian(Distro) || IsUbuntuLucid(Distro))
+    ExtraOpts.push_back("--hash-style=both");
+
+  if (IsX86_64(Distro))
+    Suffix32 = "/32";
+
+  if (IsX86(Distro))
+    Suffix64 = "/64";
+
+  if (IsDebianBased(Distro) && IsX86_64(Distro))
+    Lib32 = "lib32";
+
+  if ((IsDebianBased(Distro) && IsX86(Distro)) ||
+      IsFedora(Distro) || IsOpenSuse(Distro))
+    Lib64 = "lib64";
+
+  if (IsFedora(Distro))
+    ExtraOpts.push_back("--no-add-needed");
+
+  if (IsDebianSqueeze(Distro) || IsUbuntu(Distro) || IsOpenSuse(Distro) ||
+      IsFedora(Distro))
+    ExtraOpts.push_back("--build-id");
+
+  if (IsArm(Distro)) {
+    if (IsDebianBased(Distro))
+      GccTriple = "arm-linux-gnueabi";
+  } else if (IsX86_64(Distro)) {
+    if (IsDebianBased(Distro))
+      GccTriple = "x86_64-linux-gnu";
+    else if (IsFedora(Distro))
+      GccTriple = "x86_64-redhat-linux";
+    else if (IsOpenSuse(Distro))
+      GccTriple = "x86_64-suse-linux";
+  } else if (IsX86(Distro)) {
+    if (Distro == UbuntuMavericki386)
+      GccTriple = "i686-linux-gnu";
+    else if (IsDebianBased(Distro))
+      GccTriple = "i486-linux-gnu";
+    if (IsFedora(Distro))
+      GccTriple = "i686-redhat-linux";
+    if (IsOpenSuse(Distro))
+      GccTriple = "i586-suse-linux";
+  }
+
+  if (IsDebianLenny(Distro))
+    Base = "/usr/lib/gcc/" + GccTriple +"/4.3.2";
+  if (IsDebianSqueeze(Distro) || IsUbuntuMaveric(Distro))
+    Base = "/usr/lib/gcc/" + GccTriple +"/4.4.5";
+  if (IsUbuntuLucid(Distro))
+    Base = "/usr/lib/gcc/" + GccTriple +"/4.4.3";
+  if (IsFedora13(Distro))
+    Base = "/usr/lib/gcc/" + GccTriple +"/4.4.4";
+  if (IsFedora14(Distro))
+    Base = "/usr/lib/gcc/" + GccTriple +"/4.5.1";
+  if (IsOpenSuse(Distro) && IsX86_64(Distro))
+    Base = "/usr/lib64/gcc/" + GccTriple + "/4.5";
+  if (IsOpenSuse(Distro) && IsX86(Distro))
+    Base = "/usr/lib/gcc/" + GccTriple + "/4.5";
+
+  path_list &Paths = getFilePaths();
+  bool Is32Bits = getArch() == llvm::Triple::x86;
+
+  std::string Suffix;
+  std::string Lib;
+
+  if (Is32Bits) {
+    Suffix = Suffix32;
+    Lib = Lib32;
+  } else {
+    Suffix = Suffix64;
+    Lib = Lib64;
+  }
+
+  llvm::sys::Path LinkerPath(Base + "/../../../../" + GccTriple + "/bin/ld");
+  if (LinkerPath.exists())
+    Linker = LinkerPath.str();
+  else
+    Linker = GetProgramPath("ld");
+
+  Paths.push_back(Base + Suffix);
+  if (HasMultilib(Distro)) {
+    if (IsOpenSuse(Distro) && Is32Bits)
+      Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib");
+    Paths.push_back(Base + "/../../../../" + Lib);
+    Paths.push_back("/lib/../" + Lib);
+    Paths.push_back("/usr/lib/../" + Lib);
+  }
+  if (!Suffix.empty())
+    Paths.push_back(Base);
+  if (IsOpenSuse(Distro))
+    Paths.push_back(Base + "/../../../../" + GccTriple + "/lib");
+  Paths.push_back(Base + "/../../..");
+  bool IsNative = (Is32Bits && IsX86(Distro)) ||
+                  (!Is32Bits && IsX86_64(Distro));
+  if (IsNative && IsUbuntu(Distro))
+    Paths.push_back("/usr/lib/" + GccTriple);
+}
+
+bool Linux::HasNativeLLVMSupport() const {
+  return true;
 }
 
 Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
@@ -1213,6 +1524,8 @@
     switch (Key) {
     case Action::AssembleJobClass:
       T = new tools::linuxtools::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::linuxtools::Link(*this); break;
     default:
       T = &Generic_GCC::SelectTool(C, JA);
     }

Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=118149&r1=118148&r2=118149&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Tue Nov  2 23:37:51 2010
@@ -317,7 +317,12 @@
 public:
   Linux(const HostInfo &Host, const llvm::Triple& Triple);
 
+  virtual bool HasNativeLLVMSupport() const;
+
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+
+  std::string Linker;
+  std::vector<std::string> ExtraOpts;
 };
 
 

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=118149&r1=118148&r2=118149&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Tue Nov  2 23:37:51 2010
@@ -3134,6 +3134,145 @@
   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,

Modified: cfe/trunk/lib/Driver/Tools.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=118149&r1=118148&r2=118149&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.h (original)
+++ cfe/trunk/lib/Driver/Tools.h Tue Nov  2 23:37:51 2010
@@ -348,6 +348,18 @@
                               const ArgList &TCArgs,
                               const char *LinkingOutput) const;
   };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("linux::Link", "linker", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
 }
   /// minix -- Directly call GNU Binutils assembler and linker
 namespace minix {





More information about the cfe-commits mailing list