CMake: Add support building Qt with the 'mold' linker
The mold linker is a new linker for Linux that provides faster link times compared to BFD ld, ld.gold and lld. It can be found at https://github.com/rui314/mold To build Qt with mold, ensure that the binary in your PATH and then configure Qt with with either cmake /path/to/qtbase -DINPUT_linker=mold or /path/to/qtbase/configure --linker mold The change was tested with gcc 9, clang 10, clang 12, mold 1.0.0. Only qtbase and qtdeclarative (and dependencies) were tested. Pick-to: 6.2 6.3 Task-number: QTBUG-99270 Change-Id: I2e64a1f4257c37ff5b64a9326e548b9b46e07c80 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
f0371487ce
commit
158287c726
@ -1118,6 +1118,62 @@ function(qt_config_compiler_supports_flag_test name)
|
||||
set(TEST_${name} "${TEST_${name}}" CACHE INTERNAL "${label}")
|
||||
endfunction()
|
||||
|
||||
# gcc expects -fuse-ld=mold (no absolute path can be given) (gcc >= 12.1)
|
||||
# or an 'ld' symlink to 'mold' in a dir that is passed via -B flag (gcc < 12.1)
|
||||
#
|
||||
# clang expects -fuse-ld=mold
|
||||
# or -fuse-ld=<mold-abs-path>
|
||||
# or --ldpath=<mold-abs-path> (clang >= 12)
|
||||
# https://github.com/rui314/mold/#how-to-use
|
||||
# TODO: In the gcc < 12.1 case, the qt_internal_check_if_linker_is_available(mold) check will
|
||||
# always return TRUE because gcc will not error out if it is given a -B flag pointing to an
|
||||
# invalid dir, as well as when the the symlink to the linker in the -B dir is not actually
|
||||
# a valid linker.
|
||||
# It would be nice to handle that case in a better way, but it's not that important
|
||||
# given that gcc > 12.1 now supports -fuse-ld=mold
|
||||
# NOTE: In comparison to clang, in the gcc < 12.1 case, we pass the full path to where mold is
|
||||
# and that is recorded in PlatformCommonInternal's INTERFACE_LINK_OPTIONS target.
|
||||
# Moving such a Qt to a different machine and trying to build another repo won't
|
||||
# work because the recorded path will be invalid. This is not a problem with
|
||||
# the gcc >= 12.1 case
|
||||
function(qt_internal_get_mold_linker_flags out_var)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "ERROR_IF_EMPTY" "" "")
|
||||
|
||||
find_program(QT_INTERNAL_LINKER_MOLD mold)
|
||||
|
||||
set(flag "")
|
||||
if(QT_INTERNAL_LINKER_MOLD)
|
||||
if(GCC)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1")
|
||||
set(flag "-fuse-ld=mold")
|
||||
else()
|
||||
set(mold_linker_dir "${CMAKE_CURRENT_BINARY_DIR}/.qt_linker")
|
||||
set(mold_linker_path "${mold_linker_dir}/ld")
|
||||
if(NOT EXISTS "${mold_linker_dir}")
|
||||
file(MAKE_DIRECTORY "${mold_linker_dir}")
|
||||
endif()
|
||||
if(NOT EXISTS "${mold_linker_path}")
|
||||
file(CREATE_LINK
|
||||
"${QT_INTERNAL_LINKER_MOLD}"
|
||||
"${mold_linker_path}"
|
||||
SYMBOLIC)
|
||||
endif()
|
||||
set(flag "-B${mold_linker_dir}")
|
||||
endif()
|
||||
elseif(CLANG)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12")
|
||||
set(flag "--ld-path=mold")
|
||||
else()
|
||||
set(flag "-fuse-ld=mold")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(arg_ERROR_IS_EMPTY AND NOT flag)
|
||||
message(FATAL_ERROR "Could not determine the flags to use the mold linker.")
|
||||
endif()
|
||||
set(${out_var} "${flag}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_get_active_linker_flags out_var)
|
||||
set(flags "")
|
||||
if(GCC OR CLANG)
|
||||
@ -1127,6 +1183,9 @@ function(qt_internal_get_active_linker_flags out_var)
|
||||
list(APPEND flags "-fuse-ld=bfd")
|
||||
elseif(QT_FEATURE_use_lld_linker)
|
||||
list(APPEND flags "-fuse-ld=lld")
|
||||
elseif(QT_FEATURE_use_mold_linker)
|
||||
qt_internal_get_mold_linker_flags(mold_flags ERROR_IF_EMPTY)
|
||||
list(APPEND flags "${mold_flags}")
|
||||
endif()
|
||||
endif()
|
||||
set(${out_var} "${flags}" PARENT_SCOPE)
|
||||
|
@ -39,6 +39,18 @@ qt_internal_check_if_linker_is_available(use_lld_linker
|
||||
FLAG "-fuse-ld=lld"
|
||||
)
|
||||
|
||||
# We set an invalid flag as a default flag so the compile test fails
|
||||
# in case if no mold is found in PATH.
|
||||
set(__qt_internal_mold_linker_flags "-Wl,-invalid-flag")
|
||||
if(NOT QT_CONFIGURE_RUNNING)
|
||||
qt_internal_get_mold_linker_flags(__qt_internal_mold_linker_flags)
|
||||
endif()
|
||||
qt_internal_check_if_linker_is_available(use_mold_linker
|
||||
LABEL "mold linker"
|
||||
FLAG "${__qt_internal_mold_linker_flags}"
|
||||
)
|
||||
unset(__qt_internal_mold_linker_flags)
|
||||
|
||||
qt_feature("use_bfd_linker"
|
||||
PRIVATE
|
||||
LABEL "bfd"
|
||||
@ -46,6 +58,7 @@ qt_feature("use_bfd_linker"
|
||||
CONDITION NOT WIN32 AND NOT INTEGRITY AND NOT WASM AND TEST_use_bfd_linker
|
||||
ENABLE INPUT_linker STREQUAL 'bfd'
|
||||
DISABLE INPUT_linker STREQUAL 'gold' OR INPUT_linker STREQUAL 'lld'
|
||||
OR INPUT_linker STREQUAL 'mold'
|
||||
)
|
||||
qt_feature_config("use_bfd_linker" QMAKE_PRIVATE_CONFIG)
|
||||
|
||||
@ -60,6 +73,7 @@ qt_feature("use_gold_linker"
|
||||
CONDITION NOT WIN32 AND NOT INTEGRITY AND NOT WASM AND NOT rtems AND TEST_use_gold_linker
|
||||
ENABLE INPUT_linker STREQUAL 'gold' OR QT_FEATURE_use_gold_linker_alias
|
||||
DISABLE INPUT_linker STREQUAL 'bfd' OR INPUT_linker STREQUAL 'lld'
|
||||
OR INPUT_linker STREQUAL 'mold'
|
||||
)
|
||||
qt_feature_config("use_gold_linker" QMAKE_PRIVATE_CONFIG)
|
||||
|
||||
@ -70,14 +84,27 @@ qt_feature("use_lld_linker"
|
||||
CONDITION NOT WIN32 AND NOT INTEGRITY AND NOT WASM AND TEST_use_lld_linker
|
||||
ENABLE INPUT_linker STREQUAL 'lld'
|
||||
DISABLE INPUT_linker STREQUAL 'bfd' OR INPUT_linker STREQUAL 'gold'
|
||||
OR INPUT_linker STREQUAL 'mold'
|
||||
)
|
||||
qt_feature_config("use_lld_linker" QMAKE_PRIVATE_CONFIG)
|
||||
|
||||
qt_feature("use_mold_linker"
|
||||
PRIVATE
|
||||
LABEL "mold"
|
||||
AUTODETECT FALSE
|
||||
CONDITION NOT WIN32 AND NOT INTEGRITY AND NOT WASM AND TEST_use_mold_linker
|
||||
ENABLE INPUT_linker STREQUAL 'mold'
|
||||
DISABLE INPUT_linker STREQUAL 'bfd' OR INPUT_linker STREQUAL 'gold'
|
||||
OR INPUT_linker STREQUAL 'lld'
|
||||
)
|
||||
qt_feature_config("use_mold_linker" QMAKE_PRIVATE_CONFIG)
|
||||
|
||||
if(NOT QT_CONFIGURE_RUNNING)
|
||||
qt_evaluate_feature(use_bfd_linker)
|
||||
qt_evaluate_feature(use_gold_linker_alias)
|
||||
qt_evaluate_feature(use_gold_linker)
|
||||
qt_evaluate_feature(use_lld_linker)
|
||||
qt_evaluate_feature(use_mold_linker)
|
||||
endif()
|
||||
|
||||
|
||||
@ -1004,9 +1031,10 @@ qt_configure_add_summary_entry(
|
||||
)
|
||||
qt_configure_add_summary_entry(
|
||||
TYPE "firstAvailableFeature"
|
||||
ARGS "use_bfd_linker use_gold_linker use_lld_linker"
|
||||
ARGS "use_bfd_linker use_gold_linker use_lld_linker use_mold_linker"
|
||||
MESSAGE "Linker"
|
||||
CONDITION QT_FEATURE_use_bfd_linker OR QT_FEATURE_use_gold_linker OR QT_FEATURE_use_lld_linker
|
||||
OR QT_FEATURE_use_mold_linker
|
||||
)
|
||||
qt_configure_add_summary_entry(
|
||||
ARGS "enable_new_dtags"
|
||||
|
@ -63,7 +63,7 @@ qt_commandline_option(gui TYPE boolean)
|
||||
qt_commandline_option(headersclean TYPE boolean)
|
||||
qt_commandline_option(incredibuild-xge TYPE boolean NAME incredibuild_xge)
|
||||
qt_commandline_option(libudev TYPE boolean)
|
||||
qt_commandline_option(linker TYPE optionalString VALUES bfd gold lld)
|
||||
qt_commandline_option(linker TYPE optionalString VALUES bfd gold lld mold)
|
||||
qt_commandline_option(ltcg TYPE boolean)
|
||||
# special case begin
|
||||
qt_commandline_option(make TYPE addString VALUES examples libs tests tools
|
||||
|
Loading…
Reference in New Issue
Block a user