summaryrefslogtreecommitdiffstats
path: root/cmake/QtBuildInformation.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtBuildInformation.cmake')
-rw-r--r--cmake/QtBuildInformation.cmake271
1 files changed, 240 insertions, 31 deletions
diff --git a/cmake/QtBuildInformation.cmake b/cmake/QtBuildInformation.cmake
index 9dc3461f5b..11fa9996b1 100644
--- a/cmake/QtBuildInformation.cmake
+++ b/cmake/QtBuildInformation.cmake
@@ -1,68 +1,239 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+function(qt_internal_set_message_log_level out_var)
+ # Decide whether output should be verbose or not.
+ # Default to verbose (--log-level=STATUS) in a developer-build and
+ # non-verbose (--log-level=NOTICE) otherwise.
+ # If a custom CMAKE_MESSAGE_LOG_LEVEL was specified, it takes priority.
+ # Passing an explicit --log-level=Foo has the highest priority.
+ if(NOT CMAKE_MESSAGE_LOG_LEVEL)
+ if(FEATURE_developer_build OR QT_FEATURE_developer_build)
+ set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
+ else()
+ set(CMAKE_MESSAGE_LOG_LEVEL "NOTICE")
+ endif()
+ set(${out_var} "${CMAKE_MESSAGE_LOG_LEVEL}" PARENT_SCOPE)
+ endif()
+endfunction()
+
function(qt_print_feature_summary)
- include(FeatureSummary)
+ if(QT_SUPERBUILD)
+ qt_internal_set_message_log_level(message_log_level)
+ if(message_log_level)
+ # In a top-level build, ensure that the feature_summary is affected by the
+ # selected log-level.
+ set(CMAKE_MESSAGE_LOG_LEVEL "${message_log_level}")
+ endif()
+ endif()
+
# Show which packages were found.
- feature_summary(WHAT PACKAGES_FOUND
+ feature_summary(INCLUDE_QUIET_PACKAGES
+ WHAT PACKAGES_FOUND
REQUIRED_PACKAGES_NOT_FOUND
RECOMMENDED_PACKAGES_NOT_FOUND
OPTIONAL_PACKAGES_NOT_FOUND
RUNTIME_PACKAGES_NOT_FOUND
FATAL_ON_MISSING_REQUIRED_PACKAGES)
+ qt_internal_run_additional_summary_checks()
qt_configure_print_summary()
endfunction()
+function(qt_internal_run_additional_summary_checks)
+ get_property(
+ rpath_workaround_enabled
+ GLOBAL PROPERTY _qt_internal_staging_prefix_build_rpath_workaround)
+ if(rpath_workaround_enabled)
+ set(message
+ "Due to CMAKE_STAGING_PREFIX usage and an unfixed CMake bug,
+ to ensure correct build time rpaths, directory-level install
+ rules like ninja src/gui/install will not work.
+ Check QTBUG-102592 for further details.")
+ qt_configure_add_report_entry(
+ TYPE NOTE
+ MESSAGE "${message}"
+ )
+ endif()
+endfunction()
+
function(qt_print_build_instructions)
if((NOT PROJECT_NAME STREQUAL "QtBase" AND
- NOT PROJECT_NAME STREQUAL "Qt") OR
- QT_BUILD_STANDALONE_TESTS)
+ NOT PROJECT_NAME STREQUAL "Qt") OR QT_INTERNAL_BUILD_STANDALONE_PARTS)
return()
endif()
+ if(QT_SUPERBUILD)
+ qt_internal_set_message_log_level(message_log_level)
+ if(message_log_level)
+ # In a top-level build, ensure that qt_print_build_instructions is affected by the
+ # selected log-level.
+ set(CMAKE_MESSAGE_LOG_LEVEL "${message_log_level}")
+ endif()
+ endif()
+
set(build_command "cmake --build . --parallel")
set(install_command "cmake --install .")
- message("Qt is now configured for building. Just run '${build_command}'\n")
+ # Suggest "ninja install" for Multi-Config builds
+ # until https://gitlab.kitware.com/cmake/cmake/-/issues/21475 is fixed.
+ if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
+ set(install_command "ninja install")
+ endif()
+
+ set(configure_module_command "qt-configure-module")
+ if(CMAKE_HOST_WIN32)
+ string(APPEND configure_module_command ".bat")
+ endif()
+ if("${CMAKE_STAGING_PREFIX}" STREQUAL "")
+ set(local_install_prefix "${CMAKE_INSTALL_PREFIX}")
+ else()
+ set(local_install_prefix "${CMAKE_STAGING_PREFIX}")
+ endif()
+
+ set(msg "\n")
+
+ list(APPEND msg "Qt is now configured for building. Just run '${build_command}'\n")
if(QT_WILL_INSTALL)
- message("Once everything is built, you must run '${install_command}'")
- message("Qt will be installed into '${CMAKE_INSTALL_PREFIX}'")
+ list(APPEND msg "Once everything is built, you must run '${install_command}'")
+ list(APPEND msg "Qt will be installed into '${CMAKE_INSTALL_PREFIX}'")
+ else()
+ list(APPEND msg
+ "Once everything is built, Qt is installed. You should NOT run '${install_command}'")
+ list(APPEND msg
+ "Note that this build cannot be deployed to other machines or devices.")
+ endif()
+ list(APPEND msg
+ "\nTo configure and build other Qt modules, you can use the following convenience script:
+ ${local_install_prefix}/${INSTALL_BINDIR}/${configure_module_command}")
+ list(APPEND msg "\nIf reconfiguration fails for some reason, try removing 'CMakeCache.txt' \
+from the build directory")
+ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
+ list(APPEND msg "Alternatively, you can add the --fresh flag to your CMake flags.\n")
else()
- message("Once everything is built, Qt is installed. You should NOT run '${install_command}'")
- message("Note that this build cannot be deployed to other machines or devices.")
+ list(APPEND msg "\n")
+ endif()
+
+ list(JOIN msg "\n" msg)
+
+ if(NOT QT_INTERNAL_BUILD_INSTRUCTIONS_SHOWN)
+ qt_configure_print_build_instructions_helper("${msg}")
+ endif()
+
+ set(QT_INTERNAL_BUILD_INSTRUCTIONS_SHOWN "TRUE" CACHE STRING "" FORCE)
+
+ if(QT_SUPERBUILD)
+ qt_internal_save_previously_visited_packages()
endif()
- message("\nTo configure and build other Qt modules, you can use the following convenience script:
- ${QT_STAGING_PREFIX}/${INSTALL_BINDIR}/qt-cmake-private")
- message("\nIf reconfiguration fails for some reason, try to remove 'CMakeCache.txt' \
-from the build directory \n")
+endfunction()
+
+function(qt_configure_print_summary_helper summary_reports force_show)
+ # We force show the summary by temporarily (within the scope of the function) resetting the
+ # current log level.
+ if(force_show)
+ set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
+
+ # Need 2 flushes to ensure no interleaved input is printed due to a mix of message(STATUS)
+ # and message(NOTICE) calls.
+ execute_process(COMMAND ${CMAKE_COMMAND} -E echo " ")
+
+ message(STATUS "Configure summary:\n${summary_reports}")
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E echo " ")
+ endif()
+endfunction()
+
+function(qt_configure_print_build_instructions_helper msg)
+ # We want to ensure build instructions are always shown the first time, regardless of the
+ # current log level.
+ set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
+ message(STATUS "${msg}")
endfunction()
function(qt_configure_print_summary)
# Evaluate all recorded commands.
qt_configure_eval_commands()
- # Show Qt-specific configure summary and any notes, wranings, etc.
+ set(summary_file "${CMAKE_BINARY_DIR}/config.summary")
+ file(WRITE "${summary_file}" "")
+
+ get_property(features_possibly_changed GLOBAL PROPERTY _qt_dirty_build)
+
+ # Show Qt-specific configuration summary.
if(__qt_configure_reports)
- message("Configure summary:\n${__qt_configure_reports}")
+ # The summary will only be printed for log level STATUS or above.
+ # Check whether the log level is sufficient for printing the summary.
+ set(log_level_sufficient_for_printed_summary TRUE)
+ if(CMAKE_VERSION GREATER_EQUAL "3.25")
+ cmake_language(GET_MESSAGE_LOG_LEVEL log_level)
+ set(sufficient_log_levels STATUS VERBOSE DEBUG TRACE)
+ if(NOT log_level IN_LIST sufficient_log_levels)
+ set(log_level_sufficient_for_printed_summary FALSE)
+ endif()
+ endif()
+
+ # We want to show the configuration summary file and log level message only on
+ # first configuration or when we detect a feature change, to keep most
+ # reconfiguration output as quiet as possible.
+ # Currently feature change detection is not entirely reliable.
+ if(log_level_sufficient_for_printed_summary
+ AND (NOT QT_INTERNAL_SUMMARY_INSTRUCTIONS_SHOWN OR features_possibly_changed))
+ set(force_show_summary TRUE)
+ message(
+ "\n"
+ "-- Configuration summary shown below. It has also been written to"
+ " ${CMAKE_BINARY_DIR}/config.summary")
+ message(
+ "-- Configure with --log-level=STATUS or higher to increase "
+ "CMake's message verbosity. "
+ "The log level does not persist across reconfigurations.")
+ else()
+ set(force_show_summary FALSE)
+ message(
+ "\n"
+ "-- Configuration summary has been written to"
+ " ${CMAKE_BINARY_DIR}/config.summary")
+ endif()
+
+ qt_configure_print_summary_helper(
+ "${__qt_configure_reports}"
+ ${force_show_summary})
+
+ file(APPEND "${summary_file}" "${__qt_configure_reports}")
endif()
+
+ # Show Qt specific notes, warnings, errors.
if(__qt_configure_notes)
message("${__qt_configure_notes}")
+ file(APPEND "${summary_file}" "${__qt_configure_notes}")
endif()
if(__qt_configure_warnings)
message("${__qt_configure_warnings}")
+ file(APPEND "${summary_file}" "${__qt_configure_warnings}")
endif()
if(__qt_configure_errors)
message("${__qt_configure_errors}")
+ file(APPEND "${summary_file}" "${__qt_configure_errors}")
endif()
message("")
if(__qt_configure_an_error_occurred)
message(FATAL_ERROR "Check the configuration messages for an error that has occurred.")
endif()
+ file(APPEND "${summary_file}" "\n")
+ set(QT_INTERNAL_SUMMARY_INSTRUCTIONS_SHOWN "TRUE" CACHE STRING "" FORCE)
endfunction()
# Takes a list of arguments, and saves them to be evaluated at the end of the configuration
# phase when the configuration summary is shown.
+#
+# RECORD_ON_FEATURE_EVALUATION option allows to record the command even while the feature
+# evaluation-only stage.
function(qt_configure_record_command)
+ cmake_parse_arguments(arg "RECORD_ON_FEATURE_EVALUATION"
+ ""
+ "" ${ARGV})
# Don't record commands when only evaluating features of a configure.cmake file.
- if(__QtFeature_only_evaluate_features)
+ if(__QtFeature_only_evaluate_features AND NOT arg_RECORD_ON_FEATURE_EVALUATION)
return()
endif()
@@ -70,11 +241,11 @@ function(qt_configure_record_command)
if(NOT DEFINED command_count)
set(command_count 0)
- else()
- math(EXPR command_count "${command_count}+1")
endif()
- set_property(GLOBAL PROPERTY qt_configure_command_${command_count} "${ARGV}")
+ set_property(GLOBAL PROPERTY qt_configure_command_${command_count} "${arg_UNPARSED_ARGUMENTS}")
+
+ math(EXPR command_count "${command_count}+1")
set_property(GLOBAL PROPERTY qt_configure_command_count "${command_count}")
endfunction()
@@ -131,13 +302,32 @@ macro(qt_configure_add_report_padded label message)
set(__qt_configure_reports "${__qt_configure_reports}" PARENT_SCOPE)
endmacro()
+# Pad 'label' and 'value' with dots like this:
+# "label ............... value"
+#
+# PADDING_LENGTH specifies the number of characters from the start to the last dot.
+# Default is 30.
+# MIN_PADDING specifies the minimum number of dots that are used for the padding.
+# Default is 0.
function(qt_configure_get_padded_string label value out_var)
- set(pad_string "........................................")
+ cmake_parse_arguments(arg "" "PADDING_LENGTH;MIN_PADDING" "" ${ARGN})
+ if("${arg_MIN_PADDING}" STREQUAL "")
+ set(arg_MIN_PADDING 0)
+ endif()
+ if(arg_PADDING_LENGTH)
+ set(pad_string "")
+ math(EXPR n "${arg_PADDING_LENGTH} - 1")
+ foreach(i RANGE ${n})
+ string(APPEND pad_string ".")
+ endforeach()
+ else()
+ set(pad_string ".........................................")
+ endif()
string(LENGTH "${label}" label_len)
string(LENGTH "${pad_string}" pad_len)
math(EXPR pad_len "${pad_len}-${label_len}")
if(pad_len LESS "0")
- set(pad_len "0")
+ set(pad_len ${arg_MIN_PADDING})
endif()
string(SUBSTRING "${pad_string}" 0 "${pad_len}" pad_string)
set(output "${label} ${pad_string} ${value}")
@@ -149,9 +339,11 @@ function(qt_configure_add_summary_entry)
endfunction()
function(qt_configure_process_add_summary_entry)
- qt_parse_all_arguments(arg "qt_configure_add_summary_entry"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
""
- "ARGS;TYPE;MESSAGE" "CONDITION" ${ARGN})
+ "ARGS;TYPE;MESSAGE"
+ "CONDITION")
+ _qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_TYPE)
set(arg_TYPE "feature")
@@ -220,6 +412,8 @@ function(qt_configure_process_add_summary_entry)
endif()
qt_configure_add_report_padded("${label}" "${value}")
+ elseif(arg_TYPE STREQUAL "message")
+ qt_configure_add_report_padded("${arg_ARGS}" "${arg_MESSAGE}")
endif()
endfunction()
@@ -229,17 +423,22 @@ endfunction()
function(qt_configure_process_add_summary_build_type_and_config)
get_property(subarch_summary GLOBAL PROPERTY qt_configure_subarch_summary)
- set(message
- "Building for: ${QT_QMAKE_TARGET_MKSPEC} (${TEST_architecture_arch}, CPU features: ${subarch_summary})")
+ if(APPLE AND (CMAKE_OSX_ARCHITECTURES MATCHES ";"))
+ set(message
+ "Building for: ${QT_QMAKE_TARGET_MKSPEC} (${CMAKE_OSX_ARCHITECTURES}), ${TEST_architecture_arch} features: ${subarch_summary})")
+ else()
+ set(message
+ "Building for: ${QT_QMAKE_TARGET_MKSPEC} (${TEST_architecture_arch}, CPU features: ${subarch_summary})")
+ endif()
qt_configure_add_report("${message}")
set(message "Compiler: ")
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
string(APPEND message "clang (Apple)")
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
+ string(APPEND message "clang (Intel LLVM)")
elseif(CLANG)
string(APPEND message "clang")
- elseif(ICC)
- string(APPEND message "intel_icc")
elseif(QCC)
string(APPEND message "rim_qcc")
elseif(GCC)
@@ -301,8 +500,11 @@ function(qt_configure_add_summary_section)
endfunction()
function(qt_configure_process_add_summary_section)
- qt_parse_all_arguments(arg "qt_configure_add_summary_section"
- "" "NAME" "" ${ARGN})
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ ""
+ "NAME"
+ "")
+ _qt_internal_validate_all_args_are_parsed(arg)
qt_configure_add_report("${__qt_configure_indent}${arg_NAME}:")
if(NOT DEFINED __qt_configure_indent)
@@ -328,10 +530,17 @@ function(qt_configure_add_report_entry)
qt_configure_record_command(ADD_REPORT_ENTRY ${ARGV})
endfunction()
+function(qt_configure_add_report_error error)
+ message(SEND_ERROR "${error}")
+ qt_configure_add_report_entry(TYPE ERROR MESSAGE "${error}" CONDITION TRUE ${ARGN})
+endfunction()
+
function(qt_configure_process_add_report_entry)
- qt_parse_all_arguments(arg "qt_configure_add_report_entry"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
""
- "TYPE;MESSAGE" "CONDITION" ${ARGN})
+ "TYPE;MESSAGE"
+ "CONDITION")
+ _qt_internal_validate_all_args_are_parsed(arg)
set(possible_types NOTE WARNING ERROR FATAL_ERROR)
if(NOT "${arg_TYPE}" IN_LIST possible_types)