whitequark created this revision. whitequark added a reviewer: majnemer. whitequark added a subscriber: cfe-commits. whitequark set the repository for this revision to rL LLVM. Herald added a subscriber: aemerson.
This patch extends the -fuse-ld option to accept a full path to an executable and use it verbatim to invoke the linker. There are generally two reasons to desire this. The first reason relates to the sad truth is that Clang is retargetable, Binutils are not. While any Clang from a binary distribution is sufficient to compile code for a wide range of architectures and prefixed BFD linkers (e.g. installed as /usr/bin/arm-none-linux-gnueabi-ld) as well as cross-compiled libc's (for non-bare-metal targets) are widely available, including on all Debian derivatives, it is impossible to use them together because the -fuse-ld= option allows to specify neither a linker prefix nor a full path to one. The second reason is linker development, both when porting existing linkers to new architectures and when working on a new linker such as LLD. Repository: rL LLVM http://reviews.llvm.org/D17952 Files: cfe/trunk/lib/Driver/ToolChain.cpp Index: cfe/trunk/lib/Driver/ToolChain.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { - StringRef Suffix = A->getValue(); - - // If we're passed -fuse-ld= with no argument, or with the argument ld, - // then use whatever the default system linker is. - if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - - llvm::SmallString<8> LinkerName("ld."); - LinkerName.append(Suffix); - - std::string LinkerPath(GetProgramPath(LinkerName.c_str())); - if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; + StringRef UseLinker = A->getValue(); + + if (UseLinker[0] == '/') { + // 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; + } getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return "";
Index: cfe/trunk/lib/Driver/ToolChain.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { - StringRef Suffix = A->getValue(); - - // If we're passed -fuse-ld= with no argument, or with the argument ld, - // then use whatever the default system linker is. - if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - - llvm::SmallString<8> LinkerName("ld."); - LinkerName.append(Suffix); - - std::string LinkerPath(GetProgramPath(LinkerName.c_str())); - if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; + StringRef UseLinker = A->getValue(); + + if (UseLinker[0] == '/') { + // 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; + } getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return "";
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits