From 96bdcdacbc09b1f3091a39b83fe394af1ccb41ea Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 27 Aug 2020 14:11:00 +0200 Subject: [PATCH] CMake: Implement configure -ltcg This configure switch sets the CMake variable CMAKE_INTERPROCEDURAL_OPTIMIZATION_ per release config to ON. The feature 'ltcg' is enabled if any of the variables CMAKE_INTERPROCEDURAL_OPTIMIZATION, CMAKE_INTERPROCEDURAL_OPTIMIZATION_ are ON. In order to implement the check, configurejson2cmake had to be extended to be able to write extra CMake code before and after the feature definition. This extra code can be added to a feature mapping below the keys "cmakePrelude" and "cmakeEpilogue". Task-number: QTBUG-85373 Change-Id: Ia2eb907edcf087f137977a9b090705397f83eb05 Reviewed-by: Qt CI Bot Reviewed-by: Cristian Adam --- cmake/QtProcessConfigureArgs.cmake | 10 ++++++++++ cmake/configure-cmake-mapping.md | 3 ++- configure.cmake | 16 +++++++++++++-- util/cmake/configurejson2cmake.py | 32 ++++++++++++++++++++++++++++-- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/cmake/QtProcessConfigureArgs.cmake b/cmake/QtProcessConfigureArgs.cmake index b4fc1792c5c..8a620ba31cf 100644 --- a/cmake/QtProcessConfigureArgs.cmake +++ b/cmake/QtProcessConfigureArgs.cmake @@ -603,6 +603,16 @@ elseif(nr_of_build_configs GREATER 1) list(APPEND cmake_args "-DCMAKE_CONFIGURATION_TYPES=${escaped_build_configs}") endif() +drop_input(ltcg) +if("${INPUT_ltcg}" STREQUAL "yes") + foreach(config ${build_configs}) + string(TOUPPER "${config}" ucconfig) + if(NOT ucconfig STREQUAL "DEBUG") + push("-DCMAKE_INTERPROCEDURAL_OPTIMIZATION_${ucconfig}=ON") + endif() + endforeach() +endif() + translate_list_input(device-option QT_QMAKE_DEVICE_OPTIONS) translate_list_input(defines QT_EXTRA_DEFINES) translate_list_input(fpaths QT_EXTRA_FRAMEWORKPATHS) diff --git a/cmake/configure-cmake-mapping.md b/cmake/configure-cmake-mapping.md index 6e4b2c45495..780bbebef42 100644 --- a/cmake/configure-cmake-mapping.md +++ b/cmake/configure-cmake-mapping.md @@ -66,7 +66,8 @@ The effort of this is tracked in QTBUG-85373 and QTBUG-85349. | -plugin-manifests | | | | -static-runtime | -DFEATURE_static_runtime=ON | | | -pch | -DBUILD_WITH_PCH=ON | | -| -ltcg | | | +| -ltcg | -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON or | | +| | -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_=ON | | | -linker [bfd,gold,lld] | -DINPUT_linker= or | | | | -DFEATURE_use__linker=ON | | | -incredibuild-xge | n/a | This option enables remote distribution of Visual Studio | diff --git a/configure.cmake b/configure.cmake index 754f0c324c3..8e7ba06299f 100644 --- a/configure.cmake +++ b/configure.cmake @@ -616,11 +616,23 @@ qt_feature("precompile_header" CONDITION BUILD_WITH_PCH ) qt_feature_config("precompile_header" QMAKE_PRIVATE_CONFIG) +set(__qt_ltcg_detected FALSE) +if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + set(__qt_ltcg_detected TRUE) +else() + foreach(config ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES}) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION_${config}) + set(__qt_ltcg_detected TRUE) + break() + endif() + endforeach() +endif() qt_feature("ltcg" LABEL "Using LTCG" - AUTODETECT 1 - CONDITION CMAKE_INTERPROCEDURAL_OPTIMIZATION + AUTODETECT ON + CONDITION __qt_ltcg_detected ) +unset(__qt_ltcg_detected) qt_feature_config("ltcg" QMAKE_PRIVATE_CONFIG) qt_feature("enable_gdb_index" LABEL "Generating GDB index" diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py index cccfabb9e82..b0c4f61d55c 100755 --- a/util/cmake/configurejson2cmake.py +++ b/util/cmake/configurejson2cmake.py @@ -914,7 +914,22 @@ def get_feature_mapping(): "condition": "NOT QT_FEATURE_icu AND QT_FEATURE_textcodec AND NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND WrapIconv_FOUND", }, "incredibuild_xge": None, - "ltcg": {"autoDetect": "1", "condition": "CMAKE_INTERPROCEDURAL_OPTIMIZATION"}, + "ltcg": { + "autoDetect": "ON", + "cmakePrelude": """set(__qt_ltcg_detected FALSE) +if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + set(__qt_ltcg_detected TRUE) +else() + foreach(config ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES}) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION_${config}) + set(__qt_ltcg_detected TRUE) + break() + endif() + endforeach() +endif()""", + "condition": "__qt_ltcg_detected", + "cmakeEpilogue": "unset(__qt_ltcg_detected)" + }, "msvc_mp": None, "simulator_and_device": {"condition": "UIKIT AND NOT QT_UIKIT_SDK"}, "pkg-config": {"condition": "PKG_CONFIG_FOUND"}, @@ -1001,6 +1016,8 @@ def parseFeature(ctx, feature, data, cm_fh): enable = map_condition(mapping.get("enable", data.get("enable", ""))) disable = map_condition(mapping.get("disable", data.get("disable", ""))) emitIf = map_condition(mapping.get("emitIf", data.get("emitIf", ""))) + cmakePrelude = mapping.get("cmakePrelude", None) + cmakeEpilogue = mapping.get("cmakeEpilogue", None) for k in [k for k in data.keys() if k not in handled]: print(f" XXXX UNHANDLED KEY {k} in feature description") @@ -1070,10 +1087,16 @@ def parseFeature(ctx, feature, data, cm_fh): labelAppend="", superFeature=None, autoDetect="", + cmakePrelude=None, + cmakeEpilogue=None, ): if comment: cm_fh.write(f"# {comment}\n") + if cmakePrelude is not None: + cm_fh.write(cmakePrelude) + cm_fh.write("\n") + cm_fh.write(f'qt_feature("{name}"') if publicFeature: cm_fh.write(" PUBLIC") @@ -1096,11 +1119,16 @@ def parseFeature(ctx, feature, data, cm_fh): cm_fh.write(lineify("EMIT_IF", emitIf, quote=False)) cm_fh.write(")\n") + if cmakeEpilogue is not None: + cm_fh.write(cmakeEpilogue) + cm_fh.write("\n") + # Write qt_feature() calls before any qt_feature_definition() calls # Default internal feature case. featureCalls = {} - featureCalls[feature] = {"name": feature, "labelAppend": "", "autoDetect": autoDetect} + featureCalls[feature] = {"name": feature, "labelAppend": "", "autoDetect": autoDetect, + "cmakePrelude": cmakePrelude, "cmakeEpilogue": cmakeEpilogue} # Go over all outputs to compute the number of features that have to be declared for o in output: