patch-r279302-clang-r211785-add-fuse-ld.diff revision 283015
1Pull in r211785 from upstream clang trunk (by Logan Chien):
2
3  Implement the -fuse-ld= option.
4
5  This commit implements the -fuse-ld= option, so that the user
6  can specify -fuse-ld=bfd to use ld.bfd.
7
8  This commit re-applies r194328 with some test case changes.
9  It seems that r194328 was breaking macosx or mingw build
10  because clang can't find ld.bfd or ld.gold in the given sysroot.
11  We should use -B to specify the executable search path instead.
12
13  Patch originally by David Chisnall.
14
15Pull in r211786 from upstream clang trunk (by Logan Chien):
16
17  Propset the executables for GetProgramPath().
18
19Introduced here: http://svnweb.freebsd.org/changeset/base/279302
20
21Index: tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
22===================================================================
23--- tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
24+++ tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
25@@ -20,6 +20,8 @@ def err_drv_unknown_stdin_type : Error<
26 def err_drv_unknown_language : Error<"language not recognized: '%0'">;
27 def err_drv_invalid_arch_name : Error<
28   "invalid arch name '%0'">;
29+def err_drv_invalid_linker_name : Error<
30+  "invalid linker name in argument '%0'">;
31 def err_drv_invalid_rtlib_name : Error<
32   "invalid runtime library name in argument '%0'">;
33 def err_drv_unsupported_rtlib_for_platform : Error<
34Index: tools/clang/include/clang/Driver/Options.td
35===================================================================
36--- tools/clang/include/clang/Driver/Options.td
37+++ tools/clang/include/clang/Driver/Options.td
38@@ -1453,7 +1453,7 @@ def fprofile_dir : Joined<["-"], "fprofile-dir=">,
39 
40 defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_f_Group>;
41 def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_f_Group>;
42-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<clang_ignored_f_Group>;
43+def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
44 
45 defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_f_Group>;
46 def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_f_Group>;
47Index: tools/clang/include/clang/Driver/ToolChain.h
48===================================================================
49--- tools/clang/include/clang/Driver/ToolChain.h
50+++ tools/clang/include/clang/Driver/ToolChain.h
51@@ -150,6 +150,10 @@ class ToolChain {
52   std::string GetFilePath(const char *Name) const;
53   std::string GetProgramPath(const char *Name) const;
54 
55+  /// Returns the linker path, respecting the -fuse-ld= argument to determine
56+  /// the linker suffix or name.
57+  std::string GetLinkerPath() const;
58+
59   /// \brief Dispatch to the specific toolchain for verbose printing.
60   ///
61   /// This is used when handling the verbose option to print detailed,
62Index: tools/clang/lib/Driver/ToolChain.cpp
63===================================================================
64--- tools/clang/lib/Driver/ToolChain.cpp
65+++ tools/clang/lib/Driver/ToolChain.cpp
66@@ -15,6 +15,7 @@
67 #include "clang/Driver/Options.h"
68 #include "clang/Driver/SanitizerArgs.h"
69 #include "clang/Driver/ToolChain.h"
70+#include "llvm/ADT/SmallString.h"
71 #include "llvm/ADT/StringSwitch.h"
72 #include "llvm/Option/Arg.h"
73 #include "llvm/Option/ArgList.h"
74@@ -146,6 +147,30 @@ std::string ToolChain::GetProgramPath(const char *
75   return D.GetProgramPath(Name, *this);
76 }
77 
78+std::string ToolChain::GetLinkerPath() const {
79+  if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
80+    StringRef Suffix = A->getValue();
81+
82+    // If we're passed -fuse-ld= with no argument, or with the argument ld,
83+    // then use whatever the default system linker is.
84+    if (Suffix.empty() || Suffix == "ld")
85+      return GetProgramPath("ld");
86+
87+    llvm::SmallString<8> LinkerName("ld.");
88+    LinkerName.append(Suffix);
89+
90+    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
91+    if (llvm::sys::fs::exists(LinkerPath))
92+      return LinkerPath;
93+
94+    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
95+    return "";
96+  }
97+
98+  return GetProgramPath("ld");
99+}
100+
101+
102 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
103   return types::lookupTypeForExtension(Ext);
104 }
105Index: tools/clang/lib/Driver/ToolChains.cpp
106===================================================================
107--- tools/clang/lib/Driver/ToolChains.cpp
108+++ tools/clang/lib/Driver/ToolChains.cpp
109@@ -2420,7 +2420,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &
110   PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
111                          GCCInstallation.getTriple().str() + "/bin").str());
112 
113-  Linker = GetProgramPath("ld");
114+  Linker = GetLinkerPath();
115 
116   Distro Distro = DetectDistro(Arch);
117 
118Index: tools/clang/lib/Driver/Tools.cpp
119===================================================================
120--- tools/clang/lib/Driver/Tools.cpp
121+++ tools/clang/lib/Driver/Tools.cpp
122@@ -5088,7 +5088,7 @@ void darwin::Link::ConstructJob(Compilation &C, co
123   Args.AddAllArgs(CmdArgs, options::OPT_F);
124 
125   const char *Exec =
126-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
127+    Args.MakeArgString(getToolChain().GetLinkerPath());
128   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
129 }
130 
131@@ -5285,7 +5285,7 @@ void solaris::Link::ConstructJob(Compilation &C, c
132   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
133 
134   const char *Exec =
135-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
136+    Args.MakeArgString(getToolChain().GetLinkerPath());
137   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
138 }
139 
140@@ -5397,7 +5397,7 @@ void auroraux::Link::ConstructJob(Compilation &C,
141   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
142 
143   const char *Exec =
144-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
145+    Args.MakeArgString(getToolChain().GetLinkerPath());
146   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
147 }
148 
149@@ -5587,7 +5587,7 @@ void openbsd::Link::ConstructJob(Compilation &C, c
150   }
151 
152   const char *Exec =
153-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
154+    Args.MakeArgString(getToolChain().GetLinkerPath());
155   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
156 }
157 
158@@ -5727,7 +5727,7 @@ void bitrig::Link::ConstructJob(Compilation &C, co
159   }
160 
161   const char *Exec =
162-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
163+    Args.MakeArgString(getToolChain().GetLinkerPath());
164   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
165 }
166 
167@@ -6016,7 +6016,7 @@ void freebsd::Link::ConstructJob(Compilation &C, c
168   addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple());
169 
170   const char *Exec =
171-    Args.MakeArgString(ToolChain.GetProgramPath("ld"));
172+    Args.MakeArgString(ToolChain.GetLinkerPath());
173   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
174 }
175 
176@@ -6204,7 +6204,7 @@ void netbsd::Link::ConstructJob(Compilation &C, co
177 
178   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
179 
180-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
181+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
182   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
183 }
184 
185@@ -6749,7 +6749,7 @@ void minix::Link::ConstructJob(Compilation &C, con
186          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
187   }
188 
189-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
190+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
191   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
192 }
193 
194@@ -6933,7 +6933,7 @@ void dragonfly::Link::ConstructJob(Compilation &C,
195   addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
196 
197   const char *Exec =
198-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
199+    Args.MakeArgString(getToolChain().GetLinkerPath());
200   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
201 }
202 
203Index: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
204===================================================================
205
206Property changes on: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
207___________________________________________________________________
208Added: svn:executable
209## -0,0 +1 ##
210+*
211\ No newline at end of property
212Index: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
213===================================================================
214
215Property changes on: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
216___________________________________________________________________
217Added: svn:executable
218## -0,0 +1 ##
219+*
220\ No newline at end of property
221Index: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
222===================================================================
223
224Property changes on: tools/clang/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
225___________________________________________________________________
226Added: svn:executable
227## -0,0 +1 ##
228+*
229\ No newline at end of property
230Index: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
231===================================================================
232
233Property changes on: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
234___________________________________________________________________
235Added: svn:executable
236## -0,0 +1 ##
237+*
238\ No newline at end of property
239Index: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
240===================================================================
241
242Property changes on: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
243___________________________________________________________________
244Added: svn:executable
245## -0,0 +1 ##
246+*
247\ No newline at end of property
248Index: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
249===================================================================
250
251Property changes on: tools/clang/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
252___________________________________________________________________
253Added: svn:executable
254## -0,0 +1 ##
255+*
256\ No newline at end of property
257Index: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
258===================================================================
259
260Property changes on: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
261___________________________________________________________________
262Added: svn:executable
263## -0,0 +1 ##
264+*
265\ No newline at end of property
266Index: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
267===================================================================
268
269Property changes on: tools/clang/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
270___________________________________________________________________
271Added: svn:executable
272## -0,0 +1 ##
273+*
274\ No newline at end of property
275Index: tools/clang/test/Driver/fuse-ld.c
276===================================================================
277--- tools/clang/test/Driver/fuse-ld.c
278+++ tools/clang/test/Driver/fuse-ld.c
279@@ -0,0 +1,63 @@
280+// RUN: %clang %s -### \
281+// RUN:     -target x86_64-unknown-freebsd 2>&1 \
282+// RUN:   | FileCheck %s --check-prefix=CHECK-FREEBSD-LD
283+// CHECK-FREEBSD-LD: ld
284+
285+// RUN: %clang %s -### -fuse-ld=bfd \
286+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
287+// RUN:     -target x86_64-unknown-freebsd \
288+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
289+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-BFD
290+// CHECK-FREEBSD-BFD: Inputs/basic_freebsd_tree/usr/bin/ld.bfd
291+
292+// RUN: %clang %s -### -fuse-ld=gold \
293+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
294+// RUN:     -target x86_64-unknown-freebsd \
295+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
296+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-GOLD
297+// CHECK-FREEBSD-GOLD: Inputs/basic_freebsd_tree/usr/bin/ld.gold
298+
299+// RUN: %clang %s -### -fuse-ld=plib \
300+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
301+// RUN:     -target x86_64-unknown-freebsd \
302+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
303+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-PLIB
304+// CHECK-FREEBSD-PLIB: error: invalid linker name
305+
306+
307+
308+// RUN: %clang %s -### \
309+// RUN:     -target arm-linux-androideabi \
310+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
311+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD
312+// CHECK-ANDROID-ARM-LD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
313+
314+// RUN: %clang %s -### -fuse-ld=bfd \
315+// RUN:     -target arm-linux-androideabi \
316+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
317+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD
318+// CHECK-ANDROID-ARM-BFD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
319+
320+// RUN: %clang %s -### -fuse-ld=gold \
321+// RUN:     -target arm-linux-androideabi \
322+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
323+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD
324+// CHECK-ANDROID-ARM-GOLD: Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
325+
326+// RUN: %clang %s -### \
327+// RUN:     -target arm-linux-androideabi \
328+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
329+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD-TC
330+// CHECK-ANDROID-ARM-LD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld
331+
332+// RUN: %clang %s -### -fuse-ld=bfd \
333+// RUN:     -target arm-linux-androideabi \
334+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
335+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD-TC
336+// CHECK-ANDROID-ARM-BFD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.bfd
337+
338+// RUN: %clang %s -### -fuse-ld=gold \
339+// RUN:     -target arm-linux-androideabi \
340+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
341+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC
342+// CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.gold
343