diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -534,21 +534,24 @@ const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ); StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER; + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") + return GetProgramPath(getDefaultLinker()); if (llvm::sys::path::is_absolute(UseLinker)) { // If we're passed what looks like an absolute path, don't attempt to // second-guess that. if (llvm::sys::fs::can_execute(UseLinker)) return std::string(UseLinker); - } else if (UseLinker.empty() || UseLinker == "ld") { - // If we're passed -fuse-ld= with no argument, or with the argument ld, - // then use whatever the default system linker is. - return GetProgramPath(getDefaultLinker()); } else { llvm::SmallString<8> LinkerName; - if (Triple.isOSDarwin()) - LinkerName.append("ld64."); - else + // Recognize common abbreviations by appending an OS specific prefix. + if (Triple.isOSDarwin()) { + if (UseLinker == "lld") + LinkerName.append("ld64."); + } else if (UseLinker == "bfd" || UseLinker == "gold" || UseLinker == "lld") LinkerName.append("ld."); + LinkerName.append(UseLinker); std::string LinkerPath(GetProgramPath(LinkerName.c_str())); diff --git a/clang/test/Driver/Inputs/Windows/ARM/8.1/usr/bin/ld.lld-link2 b/clang/test/Driver/Inputs/Windows/ARM/8.1/usr/bin/lld-link2 rename from clang/test/Driver/Inputs/Windows/ARM/8.1/usr/bin/ld.lld-link2 rename to clang/test/Driver/Inputs/Windows/ARM/8.1/usr/bin/lld-link2 diff --git a/clang/test/Driver/Inputs/fuse_ld_windows/ld.foo.exe b/clang/test/Driver/Inputs/fuse_ld_windows/foo.exe rename from clang/test/Driver/Inputs/fuse_ld_windows/ld.foo.exe rename to clang/test/Driver/Inputs/fuse_ld_windows/foo.exe diff --git a/clang/test/Driver/fuse-ld-windows.c b/clang/test/Driver/fuse-ld-windows.c --- a/clang/test/Driver/fuse-ld-windows.c +++ b/clang/test/Driver/fuse-ld-windows.c @@ -13,13 +13,13 @@ // With the full path, the extension can be omitted, too, // because Windows allows that. // RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ -// RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/ld.foo 2>&1 \ +// RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/foo 2>&1 \ // RUN: | FileCheck %s // Check that the full path with the extension works too. // RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ -// RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/ld.foo.exe 2>&1 \ +// RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/foo.exe 2>&1 \ // RUN: | FileCheck %s // CHECK-NOT: invalid linker name -// CHECK: /Inputs/fuse_ld_windows{{/|\\\\}}ld.foo +// CHECK: /Inputs/fuse_ld_windows{{/|\\\\}}foo diff --git a/clang/test/Driver/fuse-ld.c b/clang/test/Driver/fuse-ld.c --- a/clang/test/Driver/fuse-ld.c +++ b/clang/test/Driver/fuse-ld.c @@ -15,6 +15,12 @@ // 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 +// RUN: %clang %s -### -fuse-ld=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 \ @@ -22,6 +28,12 @@ // 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 +// RUN: %clang %s -### -fuse-ld=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 \