gollvm: rework handling of default linker Revise the recipe for setting the default linker, setting the default of "gold" in the cmake code instead of the tools code. As before with no explicit setting of GOLLVM_DEFAULT_LINKER we'll target gold, but GOLLVM_DEFAULT_LINKER can be set to "bfd" or "lld" (to select those variants) or set to the empty string to just invoke "ld". Change-Id: Ie8cca9244067b84d0841b01edb938b63ebc47053 Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/239957 Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4baae8a..e461235 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -16,6 +16,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") set(GOLLVM_USE_SPLIT_STACK ON CACHE BOOL "use split stack by default") +set(GOLLVM_DEFAULT_LINKER gold CACHE STRING "default linker for Go links") include(CmakeUtils) include(AddGollvm)
diff --git a/README.md b/README.md index b9881fa..0d5785f 100644 --- a/README.md +++ b/README.md
@@ -1,4 +1,5 @@ + # Gollvm Gollvm is an LLVM-based Go compiler. It incorporates "gofrontend" (a Go language front end written in C++ and shared with GCCGO), a bridge component (which translates from gofrontend IR to LLVM IR), and a driver that sends the resulting IR through the LLVM back end. @@ -80,7 +81,9 @@ % ``` -This will build the various tools and libraries needed for Gollvm. To select a specific C/C++ compiler for the build, you can use the "-DCMAKE_C_COMPILER" and "-DCMAKE_CXX_COMPILER" options to select your desired C/C++ compiler when invoking cmake (details [here](https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-do-i-use-a-different-compiler)). +This will build the various tools and libraries needed for Gollvm. To select a specific C/C++ compiler for the build, you can use the "-DCMAKE_C_COMPILER" and "-DCMAKE_CXX_COMPILER" options to select your desired C/C++ compiler when invoking cmake (details [here](https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-do-i-use-a-different-compiler)). Use the "-DLLVM_USE_LINKER=<variant>" cmake variable to control which linker is selected to link the Gollvm compiler and tools (where variant is one of "bfd", "gold", "lld", etc). + +The Gollvm compiler driver defaults to using the gold linker when linking Go programs. If some other linker is desired, this can be accomplished by passing "-DGOLLVM_DEFAULT_LINKER=<variant>" when running cmake. Note that this default can still be overridden on the command line using the "-fuse-ld" option. ## Installing gollvm <a name="installing"></a>
diff --git a/cmake/modules/AddGollvm.cmake b/cmake/modules/AddGollvm.cmake index f5dd868..16c6e4f 100644 --- a/cmake/modules/AddGollvm.cmake +++ b/cmake/modules/AddGollvm.cmake
@@ -20,7 +20,8 @@ set(GOLLVM_LIBVERSION "${libversion}") set(GOLLVM_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}") set(GOLLVM_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/${libsubdir}") -set(GOLLVM_DEFAULT_LINKER "${LLVM_USE_LINKER}") + +message(STATUS "default linker set to \"${GOLLVM_DEFAULT_LINKER}\"") # Check to see whether the build compiler supports -fcf-protection=branch set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") @@ -39,7 +40,11 @@ # FIXME: update here once one day there is a linker that supports '-fsplit-stack' # on arm64. set(C_SUPPORTS_SPLIT_STACK 0) - set(CMAKE_REQUIRED_FLAGS "-fuse-ld=gold -fsplit-stack") + set(LVARIANT "") + if(GOLLVM_DEFAULT_LINKER) + set(LVARIANT "-fuse-ld=${GOLLVM_DEFAULT_LINKER}") + endif() + set(CMAKE_REQUIRED_FLAGS "${LVARIANT} -fsplit-stack") check_c_source_compiles("#include<stdio.h>\nint main(){printf(\"hello\");\nreturn 0;}" SPLIT_STACK_FUNCTIONAL) if(NOT SPLIT_STACK_FUNCTIONAL) if(C_SUPPORTS_CF_PROTECTION_BRANCH) @@ -47,7 +52,7 @@ # can cause unpleasant interactions with gold (see # https://sourceware.org/bugzilla/show_bug.cgi?id=25921 for details). message(STATUS "trying -fcf-protection=none workaround") - SET(CMAKE_REQUIRED_FLAGS "-fuse-ld=gold -fsplit-stack -fcf-protection=none") + SET(CMAKE_REQUIRED_FLAGS "${LVARIANT} -fsplit-stack -fcf-protection=none") check_c_source_compiles("#include<stdio.h>\nint main(){printf(\"hello\");\nreturn 0;}" SPLIT_STACK_WORKAROUND) if(SPLIT_STACK_WORKAROUND) message(STATUS "applying -fcf-protection=none workaround")
diff --git a/driver/GnuTools.cpp b/driver/GnuTools.cpp index 2fb63a1..ea148f5 100644 --- a/driver/GnuTools.cpp +++ b/driver/GnuTools.cpp
@@ -339,11 +339,7 @@ // will always look for "ld.ABC" on the path. With clang, however, // you can supply a full path (e.g. "-fuse-ld=/my/path/to/ld"). This // code is intended to be consistent with clang. -#ifdef GOLLVM_DEFAULT_LINKER const char *variant = GOLLVM_DEFAULT_LINKER; -#else - const char *variant = "gold"; -#endif const char *linker = nullptr; llvm::opt::Arg *ldarg = args.getLastArg(gollvm::options::OPT_fuse_ld_EQ); const char *executable = nullptr; @@ -353,8 +349,13 @@ else variant = args.MakeArgString(ldarg->getValue()); } - if (linker == nullptr) - linker = args.MakeArgString(llvm::StringRef("ld.") + variant); + if (linker == nullptr) { + if (strlen(variant) != 0) { + linker = args.MakeArgString(llvm::StringRef("ld.") + variant); + } else { + linker = args.MakeArgString(llvm::StringRef("ld")); + } + } if (executable == nullptr) executable = args.MakeArgString(toolchain().getProgramPath(linker)); if (! executable) {
diff --git a/driver/GollvmConfig.h.cmake b/driver/GollvmConfig.h.cmake index b22caca..0b53513 100644 --- a/driver/GollvmConfig.h.cmake +++ b/driver/GollvmConfig.h.cmake
@@ -22,6 +22,6 @@ #define GOLLVM_COMPILERVERSION GOLLVM_LIBVERSION // Gollvm default linker -#cmakedefine GOLLVM_DEFAULT_LINKER "@GOLLVM_DEFAULT_LINKER@" +#define GOLLVM_DEFAULT_LINKER "@GOLLVM_DEFAULT_LINKER@" #endif // GOLLVM_CONFIG_H