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 @@ -554,6 +554,18 @@ std::string LinkerPath(GetProgramPath(LinkerName.c_str())); if (llvm::sys::fs::can_execute(LinkerPath)) return LinkerPath; + + const Arg *WorkingDir = Args.getLastArg(options::OPT_working_directory); + SmallString<128> ResolvedPath(UseLinker); + if (WorkingDir) { + sys::fs::make_absolute(WorkingDir->getValue(), ResolvedPath); + if (llvm::sys::fs::can_execute(ResolvedPath)) + return std::string(ResolvedPath); + } + + if (!sys::fs::make_absolute(ResolvedPath) && + llvm::sys::fs::can_execute(ResolvedPath)) + return std::string(ResolvedPath); } if (A) 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 @@ -4,7 +4,6 @@ // RUN: | FileCheck %s --check-prefix=CHECK-ABSOLUTE-LD // CHECK-ABSOLUTE-LD: /usr/local/bin/or1k-linux-ld - // RUN: %clang %s -### \ // RUN: -target x86_64-unknown-freebsd 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-FREEBSD-LD @@ -94,3 +93,18 @@ // RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-BFD // CHECK-WINDOWS-MSVC-BFD: "{{.*}}ld.bfd" // CHECK-WINDOWS-MSVC-BFD-SAME: "-o" + +// RUN: %clang %s -### \ +// RUN: -target x86_64-unknown-linux \ +// RUN: -working-directory "%S/Inputs" \ +// RUN: -fuse-ld=fuse_ld_windows/ld.foo.exe 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-RELATIVE-WORKDIR-LD +// CHECK-RELATIVE-WORKDIR-LD-NOT: error: invalid linker name +// CHECK-RELATIVE-WORKDIR-LD: test{{/|\\+}}Driver{{/|\\+}}Inputs/fuse_ld_windows/ld.foo.exe + +// RUN: cd "%S" && %clang %s -### \ +// RUN: -target x86_64-unknown-linux \ +// RUN: -fuse-ld=Inputs/fuse_ld_windows/ld.foo.exe 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-RELATIVE-LD +// CHECK-RELATIVE-LD-NOT: error: invalid linker name +// CHECK-RELATIVE-LD: test{{/|\\+}}Driver{{/|\\+}}Inputs/fuse_ld_windows/ld.foo.exe