[Bf-blender-cvs] [8b3d798374a] master: CMake: add WITH_LINKER_MOLD option for GCC/Clang Unix platforms

Campbell Barton noreply at git.blender.org
Thu Jan 13 23:45:35 CET 2022


Commit: 8b3d798374a2c6b5026791e8ef5ce4fe6494f801
Author: Campbell Barton
Date:   Wed Jan 12 13:35:07 2022 +1100
Branches: master
https://developer.blender.org/rB8b3d798374a2c6b5026791e8ef5ce4fe6494f801

CMake: add WITH_LINKER_MOLD option for GCC/Clang Unix platforms

Can give considerably faster linking, especially on system with many
cores.

The mold linker recently reached 1.0, see:
https://github.com/rui314/mold

The current stable release of GCC can't use this linker via
-fuse-ld=mold, so this patch uses the "-B" argument to add a binary
directory containing an alternate "ld" command that points to
"mold" (which is part of the default mold installation).

Some timing tests for linking full builds for AMD TR 3970X:

- BFD: 20.78 seconds.
- LLD: 12.16 seconds.
- GOLD: 7.21 seconds.
- MOLD: 2.53 seconds.

Ref D13807

Reviewed by: sergey, brecht

===================================================================

M	CMakeLists.txt
M	build_files/cmake/platform/platform_unix.cmake

===================================================================

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88c71899f8e..5d796a5c140 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -567,6 +567,10 @@ if(UNIX AND NOT APPLE)
     option(WITH_LINKER_LLD "Use ld.lld linker which is usually faster than ld.gold" OFF)
     mark_as_advanced(WITH_LINKER_LLD)
   endif()
+  if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+    option(WITH_LINKER_MOLD "Use ld.mold linker which is usually faster than ld.gold & ld.lld." OFF)
+    mark_as_advanced(WITH_LINKER_MOLD)
+  endif()
 endif()
 
 option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index 317ea0af4ae..4ba3f81fe93 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -692,9 +692,78 @@ if(CMAKE_COMPILER_IS_GNUCC)
     unset(LD_VERSION)
   endif()
 
+  # NOTE(@campbellbarton): Eventually mold will be able to use `-fuse-ld=mold`,
+  # however at the moment this only works for GCC 12.1+ (unreleased at time of writing).
+  # So a workaround is used here "-B" which points to another path to find system commands
+  # such as `ld`.
+  if(WITH_LINKER_MOLD)
+    find_program(MOLD_BIN "mold")
+    mark_as_advanced(MOLD_BIN)
+    if(NOT MOLD_BIN)
+      message(STATUS "The \"mold\" binary could not be found, using system linker!")
+      set(WITH_LINKER_MOLD OFF)
+    else()
+      # By default mold installs the binary to:
+      # - `{PREFIX}/bin/mold` as well as a symbolic-link in...
+      # - `{PREFIX}/lib/mold/ld`.
+      # (where `PREFIX` is typically `/usr/`).
+      #
+      # This block of code finds `{PREFIX}/lib/mold` from the `mold` binary.
+      # Other methods of searching for the path could also be made to work,
+      # we could even make our own directory and symbolic-link, however it's more
+      # convenient to use the one provided by mold.
+      #
+      # Use the binary path to "mold", to find the common prefix which contains "lib/mold".
+      # The parent directory: e.g. `/usr/bin/mold` -> `/usr/bin/`.
+      get_filename_component(MOLD_PREFIX "${MOLD_BIN}" DIRECTORY)
+      # The common prefix path: e.g. `/usr/bin/` -> `/usr/` to use as a hint.
+      get_filename_component(MOLD_PREFIX "${MOLD_PREFIX}" DIRECTORY)
+      # Find `{PREFIX}/lib/mold/ld`, store the directory component (without the `ld`).
+      # Then pass `-B {PREFIX}/lib/mold` to GCC so the `ld` located there overrides the default.
+      find_path(
+        MOLD_BIN_DIR "ld"
+        HINTS "${MOLD_PREFIX}"
+        PATH_SUFFIXES "lib/mold" "lib64/mold"
+        NO_DEFAULT_PATH
+        NO_CACHE
+      )
+      if(NOT MOLD_BIN_DIR)
+        message(STATUS
+          "The mold linker could not find the directory containing the linker command "
+          "(typically \"${MOLD_PREFIX}/lib/mold\"), using system linker!")
+        set(WITH_LINKER_MOLD OFF)
+      endif()
+      unset(MOLD_PREFIX)
+    endif()
+
+    if(WITH_LINKER_MOLD)
+      # GCC will search for `ld` in this directory first.
+      string(APPEND CMAKE_CXX_FLAGS " -B \"${MOLD_BIN_DIR}\"")
+      string(APPEND CMAKE_C_FLAGS " -B \"${MOLD_BIN_DIR}\"")
+    endif()
+    unset(MOLD_BIN)
+    unset(MOLD_BIN_DIR)
+  endif()
+
 # CLang is the same as GCC for now.
 elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
   set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
+
+  if(WITH_LINKER_MOLD)
+    find_program(MOLD_BIN "mold")
+    mark_as_advanced(MOLD_BIN)
+    if(NOT MOLD_BIN)
+      message(STATUS "The \"mold\" binary could not be found, using system linker!")
+      set(WITH_LINKER_MOLD OFF)
+    else()
+      if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0)
+        string(APPEND CMAKE_EXE_LINKER_FLAGS " --ld-path=\"${MOLD_BIN}\"")
+      else()
+        string(APPEND CMAKE_EXE_LINKER_FLAGS " -fuse-ld=\"${MOLD_BIN}\"")
+      endif()
+    endif()
+  endif()
+
 # Intel C++ Compiler
 elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
   # think these next two are broken



More information about the Bf-blender-cvs mailing list