]> granicus.if.org Git - clang/commitdiff
Implement the -fuse-ld= option.
authorLogan Chien <tzuhsiang.chien@gmail.com>
Thu, 26 Jun 2014 14:23:45 +0000 (14:23 +0000)
committerLogan Chien <tzuhsiang.chien@gmail.com>
Thu, 26 Jun 2014 14:23:45 +0000 (14:23 +0000)
This commit implements the -fuse-ld= option, so that the user
can specify -fuse-ld=bfd to use ld.bfd.

This commit re-applies r194328 with some test case changes.
It seems that r194328 was breaking macosx or mingw build
because clang can't find ld.bfd or ld.gold in the given sysroot.
We should use -B to specify the executable search path instead.

Patch originally by David Chisnall.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211785 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/clang/Basic/DiagnosticDriverKinds.td
include/clang/Driver/Options.td
include/clang/Driver/ToolChain.h
lib/Driver/ToolChain.cpp
lib/Driver/ToolChains.cpp
lib/Driver/Tools.cpp
test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld [new file with mode: 0644]
test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd [new file with mode: 0644]
test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold [new file with mode: 0644]
test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld [new file with mode: 0644]
test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd [new file with mode: 0644]
test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold [new file with mode: 0644]
test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd [new file with mode: 0644]
test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold [new file with mode: 0644]
test/Driver/fuse-ld.c [new file with mode: 0644]

index 7de2250134a04102446968456685114d49d4a56d..957019ee62423f04c6de29f129d4192e13839edc 100644 (file)
@@ -22,6 +22,8 @@ def err_drv_unknown_stdin_type_clang_cl : Error<
 def err_drv_unknown_language : Error<"language not recognized: '%0'">;
 def err_drv_invalid_arch_name : Error<
   "invalid arch name '%0'">;
+def err_drv_invalid_linker_name : Error<
+  "invalid linker name in argument '%0'">;
 def err_drv_invalid_rtlib_name : Error<
   "invalid runtime library name in argument '%0'">;
 def err_drv_unsupported_rtlib_for_platform : Error<
index dd8722e1b4edf15871b4420fd00650b586b50af2..95f13cc384532c0bece9123396c4fc76b392c7aa 100644 (file)
@@ -1542,7 +1542,7 @@ def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_f_Group>;
 
 defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_f_Group>;
 def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_f_Group>;
-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<clang_ignored_f_Group>;
+def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
 
 defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_f_Group>;
 def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_f_Group>;
index f3db2c1c90341720ce3789fbad19f7be8aaec2a1..c9a6c4b57f217a88826f9b5f60065fb8200745be 100644 (file)
@@ -158,6 +158,10 @@ public:
   std::string GetFilePath(const char *Name) const;
   std::string GetProgramPath(const char *Name) const;
 
+  /// Returns the linker path, respecting the -fuse-ld= argument to determine
+  /// the linker suffix or name.
+  std::string GetLinkerPath() const;
+
   /// \brief Dispatch to the specific toolchain for verbose printing.
   ///
   /// This is used when handling the verbose option to print detailed,
index eefe487b3293baad570f9fe5c811374f735b12fc..4f90d083c7dc808fe4ed1d2c2a69d1fdc59cd7d9 100644 (file)
@@ -15,6 +15,7 @@
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -147,6 +148,30 @@ std::string ToolChain::GetProgramPath(const char *Name) const {
   return D.GetProgramPath(Name, *this);
 }
 
+std::string ToolChain::GetLinkerPath() const {
+  if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
+    StringRef Suffix = A->getValue();
+
+    // If we're passed -fuse-ld= with no argument, or with the argument ld,
+    // then use whatever the default system linker is.
+    if (Suffix.empty() || Suffix == "ld")
+      return GetProgramPath("ld");
+
+    llvm::SmallString<8> LinkerName("ld.");
+    LinkerName.append(Suffix);
+
+    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
+    if (llvm::sys::fs::exists(LinkerPath))
+      return LinkerPath;
+
+    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
+    return "";
+  }
+
+  return GetProgramPath("ld");
+}
+
+
 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
   return types::lookupTypeForExtension(Ext);
 }
index 640cb92a93f69d3f0c62fc0b7a1548cb51c03219..d02c84d315bea1d6352dc2a4a3918044cc415d1b 100644 (file)
@@ -3001,7 +3001,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
   PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
                          GCCInstallation.getTriple().str() + "/bin").str());
 
-  Linker = GetProgramPath("ld");
+  Linker = GetLinkerPath();
 
   Distro Distro = DetectDistro(Arch);
 
index 76b9890ec03105907a0b3161320b384f47bdc30d..843177414de0aeeec0d2d1542a460b377a2936cc 100644 (file)
@@ -5614,7 +5614,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
   Args.AddAllArgs(CmdArgs, options::OPT_F);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5804,7 +5804,7 @@ void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
   addProfileRT(getToolChain(), Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5912,7 +5912,7 @@ void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
   addProfileRT(getToolChain(), Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6114,7 +6114,7 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6250,7 +6250,7 @@ void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6514,7 +6514,7 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
   addProfileRT(ToolChain, Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(ToolChain.GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6767,7 +6767,7 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
 
   addProfileRT(getToolChain(), Args, CmdArgs);
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7325,7 +7325,7 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
   }
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7503,7 +7503,7 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
 
   addProfileRT(getToolChain(), Args, CmdArgs);
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
diff --git a/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/fuse-ld.c b/test/Driver/fuse-ld.c
new file mode 100644 (file)
index 0000000..ce7ef18
--- /dev/null
@@ -0,0 +1,63 @@
+// RUN: %clang %s -### \
+// RUN:     -target x86_64-unknown-freebsd 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-FREEBSD-LD
+// CHECK-FREEBSD-LD: ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-BFD
+// CHECK-FREEBSD-BFD: Inputs/basic_freebsd_tree/usr/bin/ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-GOLD
+// CHECK-FREEBSD-GOLD: Inputs/basic_freebsd_tree/usr/bin/ld.gold
+
+// RUN: %clang %s -### -fuse-ld=plib \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-PLIB
+// CHECK-FREEBSD-PLIB: error: invalid linker name
+
+
+
+// RUN: %clang %s -### \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD
+// CHECK-ANDROID-ARM-LD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD
+// CHECK-ANDROID-ARM-BFD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD
+// CHECK-ANDROID-ARM-GOLD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
+
+// RUN: %clang %s -### \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD-TC
+// CHECK-ANDROID-ARM-LD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD-TC
+// CHECK-ANDROID-ARM-BFD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC
+// CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.gold