diff options
author | Campbell Barton <campbell@blender.org> | 2022-01-12 05:35:07 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-01-14 01:44:58 +0300 |
commit | 8b3d798374a2c6b5026791e8ef5ce4fe6494f801 (patch) | |
tree | 63c5e1bd9e13fbe7d196a05c2cefa3802fe1417b /build_files/cmake | |
parent | 0c5ccae79d62127106af589f2d732cf40aa5213a (diff) |
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
Diffstat (limited to 'build_files/cmake')
-rw-r--r-- | build_files/cmake/platform/platform_unix.cmake | 69 |
1 files changed, 69 insertions, 0 deletions
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 |