Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -195,6 +195,17 @@ set(ENABLE_X86_RELAX_RELOCATIONS OFF CACHE BOOL "enable x86 relax relocations by default") +set(CLANG_DEFAULT_LINKER "" CACHE STRING + "Default linker to use (\"bfd\" or \"gold\" or \"lld\", empty for platform default") +if (NOT(CLANG_DEFAULT_LINKER STREQUAL "" OR + CLANG_DEFAULT_LINKER STREQUAL "bfd" OR + CLANG_DEFAULT_LINKER STREQUAL "gold" OR + CLANG_DEFAULT_LINKER STREQUAL "lld")) + message(WARNING "Resetting default linker to use platform default") + set(CLANG_DEFAULT_LINKER "" CACHE STRING + "Default linker to use (\"bfd\" or \"gold\" or \"lld\", empty for platform default" FORCE) +endif() + set(CLANG_DEFAULT_CXX_STDLIB "" CACHE STRING "Default C++ stdlib to use (\"libstdc++\" or \"libc++\", empty for platform default") if (NOT(CLANG_DEFAULT_CXX_STDLIB STREQUAL "" OR Index: include/clang/Config/config.h.cmake =================================================================== --- include/clang/Config/config.h.cmake +++ include/clang/Config/config.h.cmake @@ -8,6 +8,9 @@ /* Bug report URL. */ #define BUG_REPORT_URL "${BUG_REPORT_URL}" +/* Default linker to use. */ +#define CLANG_DEFAULT_LINKER "${CLANG_DEFAULT_LINKER}" + /* Default C++ stdlib to use. */ #define CLANG_DEFAULT_CXX_STDLIB "${CLANG_DEFAULT_CXX_STDLIB}" Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -341,31 +341,29 @@ } std::string ToolChain::GetLinkerPath() const { - if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { - StringRef UseLinker = A->getValue(); - - if (llvm::sys::path::is_absolute(UseLinker)) { - // If we're passed -fuse-ld= with what looks like an absolute path, - // don't attempt to second-guess that. - if (llvm::sys::fs::exists(UseLinker)) - return UseLinker; - } else { - // 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("ld"); - - llvm::SmallString<8> LinkerName("ld."); - LinkerName.append(UseLinker); - - std::string LinkerPath(GetProgramPath(LinkerName.c_str())); - if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; - } + const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ); + StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER; + + if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) + return UseLinker; + } else if (A && (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("ld"); + } else if (!UseLinker.empty()) { + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) + return LinkerPath; + } + if (A) getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); - return ""; - } return GetProgramPath(DefaultLinker); }