diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -278,6 +278,8 @@ set(CLANG_DEFAULT_LINKER "" CACHE STRING "Default linker to use (linker name or absolute path, empty for platform default)") +option(CLANG_ENABLE_GLD "Default to GNU ld." OFF) + 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 diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -11,6 +11,9 @@ /* Default linker to use. */ #define CLANG_DEFAULT_LINKER "${CLANG_DEFAULT_LINKER}" +/* Default to GNU ld. */ +#cmakedefine01 CLANG_ENABLE_GLD + /* Default C/ObjC standard to use. */ #cmakedefine CLANG_DEFAULT_STD_C LangStandard::lang_${CLANG_DEFAULT_STD_C} diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -615,7 +615,7 @@ StringRef Sanitizer) { // Solaris ld defaults to --export-dynamic behaviour but doesn't support // the option, so don't try to pass it. - if (TC.getTriple().getOS() == llvm::Triple::Solaris) + if (TC.getTriple().getOS() == llvm::Triple::Solaris && !CLANG_ENABLE_GLD) return true; // Myriad is static linking only. Furthermore, some versions of its // linker have the bug where --export-dynamic overrides -static, so @@ -634,7 +634,9 @@ // While the Solaris 11.2 ld added --as-needed/--no-as-needed as aliases // for the native forms -z ignore/-z record, they are missing in Illumos, // so always use the native form. - if (TC.getTriple().isOSSolaris()) + // GNU ld doesn't support -z ignore/-z record, so don't use them even on + // Solaris. + if (TC.getTriple().isOSSolaris() && !CLANG_ENABLE_GLD) return as_needed ? "-zignore" : "-zrecord"; else return as_needed ? "--as-needed" : "--no-as-needed"; diff --git a/clang/lib/Driver/ToolChains/Solaris.h b/clang/lib/Driver/ToolChains/Solaris.h --- a/clang/lib/Driver/ToolChains/Solaris.h +++ b/clang/lib/Driver/ToolChains/Solaris.h @@ -65,10 +65,7 @@ SanitizerMask getSupportedSanitizers() const override; unsigned GetDefaultDwarfVersion() const override { return 2; } - const char *getDefaultLinker() const override { - // clang currently uses Solaris ld-only options. - return "/usr/bin/ld"; - } + const char *getDefaultLinker() const override; protected: Tool *buildAssembler() const override; diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -53,7 +53,9 @@ ArgStringList CmdArgs; // Demangle C++ names in errors +#if !CLANG_ENABLE_GLD CmdArgs.push_back("-C"); +#endif if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) { CmdArgs.push_back("-e"); @@ -75,6 +77,36 @@ Args.ClaimAllArgs(options::OPT_pthreads); } +#if CLANG_ENABLE_GLD + // FIXME: Correct comment. + // Explicitly set the linker emulation for platforms that might not + // be the default emulation for the linker. + const toolchains::Solaris &ToolChain = + static_cast(getToolChain()); + const llvm::Triple::ArchType Arch = ToolChain.getArch(); + + switch (Arch) { + case llvm::Triple::x86: + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf_i386_sol2"); + break; + case llvm::Triple::x86_64: + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf_x86_64_sol2"); + break; + case llvm::Triple::sparc: + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf32_sparc_sol2"); + break; + case llvm::Triple::sparcv9: + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf64_sparc_sol2"); + break; + default: + break; + } +#endif + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -214,6 +246,17 @@ return Res; } +const char *Solaris::getDefaultLinker() const { +#if CLANG_ENABLE_GLD + // FIXME: Hack around /usr/gnu/bin/ld being configure with --with-sysroot. + return "/vol/gcc/bin/gld-2.35"; + //return "/usr/gnu/bin/ld"; +#else + // clang currently uses Solaris ld-only options. + return "/usr/bin/ld"; +#endif +} + Tool *Solaris::buildAssembler() const { return new tools::solaris::Assembler(*this); }