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