diff --git a/clang/lib/Driver/ToolChains/Fuchsia.h b/clang/lib/Driver/ToolChains/Fuchsia.h --- a/clang/lib/Driver/ToolChains/Fuchsia.h +++ b/clang/lib/Driver/ToolChains/Fuchsia.h @@ -86,9 +86,7 @@ void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; - const char *getDefaultLinker() const override { - return "ld.lld"; - } + const char *getDefaultLinker() const override { return "ld.lld"; } protected: Tool *buildLinker() const override; diff --git a/clang/lib/Driver/ToolChains/MipsLinux.h b/clang/lib/Driver/ToolChains/MipsLinux.h --- a/clang/lib/Driver/ToolChains/MipsLinux.h +++ b/clang/lib/Driver/ToolChains/MipsLinux.h @@ -48,9 +48,7 @@ : RuntimeLibType::RLT_CompilerRT; } - const char *getDefaultLinker() const override { - return "ld.lld"; - } + const char *getDefaultLinker() const override { return "ld.lld"; } private: Multilib SelectedMultilib; diff --git a/clang/lib/Driver/ToolChains/WebAssembly.h b/clang/lib/Driver/ToolChains/WebAssembly.h --- a/clang/lib/Driver/ToolChains/WebAssembly.h +++ b/clang/lib/Driver/ToolChains/WebAssembly.h @@ -23,6 +23,7 @@ explicit Linker(const ToolChain &TC); bool isLinkJob() const override; bool hasIntegratedCPP() const override; + std::string getLinkerPath(const llvm::opt::ArgList &Args) const; void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, @@ -50,6 +51,7 @@ bool hasBlocksRuntime() const override; bool SupportsProfiling() const override; bool HasNativeLLVMSupport() const override; + void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, @@ -65,8 +67,6 @@ void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; - const char *getDefaultLinker() const override { return "wasm-ld"; } - Tool *buildLinker() const override; }; diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -12,6 +12,8 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Option/ArgList.h" using namespace clang::driver; @@ -36,6 +38,25 @@ bool wasm::Linker::hasIntegratedCPP() const { return false; } +std::string wasm::Linker::getLinkerPath(const ArgList &Args) const { + const ToolChain &ToolChain = getToolChain(); + if (const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { + StringRef UseLinker = A->getValue(); + + if (llvm::sys::path::is_absolute(UseLinker)) { + if (llvm::sys::fs::can_execute(UseLinker)) + return UseLinker; + } + + // Since 'wasm-ld' is just another name for lld we accept that name, + // otherwise generate an error. + if (UseLinker != "lld") + ToolChain.getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); + } + + return ToolChain.GetProgramPath("wasm-ld"); +} + void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -43,7 +64,7 @@ const char *LinkingOutput) const { const ToolChain &ToolChain = getToolChain(); - const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath()); + const char *Linker = Args.MakeArgString(getLinkerPath(Args)); ArgStringList CmdArgs; if (Args.hasArg(options::OPT_s)) diff --git a/clang/test/Driver/wasm-toolchain.c b/clang/test/Driver/wasm-toolchain.c --- a/clang/test/Driver/wasm-toolchain.c +++ b/clang/test/Driver/wasm-toolchain.c @@ -12,25 +12,25 @@ // A basic C link command-line with unknown OS. -// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK %s +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK %s // LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C link command-line with optimization with unknown OS. -// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s +// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s // LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C link command-line with known OS. -// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s // LINK_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C link command-line with optimization with known OS. -// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s +// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s // LINK_OPT_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" diff --git a/clang/test/Driver/wasm-toolchain.cpp b/clang/test/Driver/wasm-toolchain.cpp --- a/clang/test/Driver/wasm-toolchain.cpp +++ b/clang/test/Driver/wasm-toolchain.cpp @@ -12,25 +12,25 @@ // A basic C++ link command-line with unknown OS. -// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK %s +// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK %s // LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C++ link command-line with optimization with unknown OS. -// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ -fuse-ld=wasm-ld 2>&1 | FileCheck -check-prefix=LINK_OPT %s +// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ 2>&1 | FileCheck -check-prefix=LINK_OPT %s // LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C++ link command-line with known OS. -// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo -fuse-ld=wasm-ld --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s +// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s // LINK_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C++ link command-line with optimization with known OS. -// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo %s --stdlib=c++ -fuse-ld=wasm-ld 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s +// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo %s --stdlib=c++ 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s // LINK_OPT_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"