From 7c62caa3555d247be569102d8f01b3e7ae362b8a Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 2 Mar 2021 12:36:27 +0100 Subject: [PATCH] Make toolchain inspection more robust QtAutoDetect.cmake did read the (possibly detected) toolchain file and looked for the string "The Android Open Source Project" to deduce that we want to build for Android. This has been done, because we're autodetecting the platform before the first project comment, i.e. before the toolchain file is loaded. This magic string detection is a bit fragile, and we need a similar approach for WebAssembly. A more robust approach would be to fetch the value of CMAKE_SYSTEM_NAME from the toolchain file without actually loading it. Now, we run a CMake script that includes the toolchain file and prints variables were interested in. The calling code reads these variables and stores them in prefixed variables in the current scope. Change-Id: Ide9ea3054e1453d17129523e1ec86ecaed55af2a Reviewed-by: Craig Scott Reviewed-by: Cristian Adam --- cmake/QtAutoDetect.cmake | 37 +++++++++++++++++++++++++++++---- cmake/QtLoadFilePrintVars.cmake | 15 +++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 cmake/QtLoadFilePrintVars.cmake diff --git a/cmake/QtAutoDetect.cmake b/cmake/QtAutoDetect.cmake index 36761dba35a..85b1abac029 100644 --- a/cmake/QtAutoDetect.cmake +++ b/cmake/QtAutoDetect.cmake @@ -14,6 +14,37 @@ function(qt_auto_detect_cmake_generator) endif() endfunction() +# Peek into CMAKE_TOOLCHAIN_FILE before it is actually loaded. +# +# Usage: +# qt_autodetect_read_toolchain_file(tcf VARIABLES CMAKE_SYSTEM_NAME) +# if(tcf_CMAKE_SYSTEM_NAME STREQUAL "Android") +# ...we have detected Android +# endif() +# +function(qt_auto_detect_read_toolchain_file prefix) + cmake_parse_arguments(arg "" "" "VARIABLES" ${ARGN}) + set(script_path "${CMAKE_CURRENT_LIST_DIR}/QtLoadFilePrintVars.cmake") + execute_process( + COMMAND "${CMAKE_COMMAND}" "-DIN_FILE=${CMAKE_TOOLCHAIN_FILE}" + "-DVARIABLES=${arg_VARIABLES}" -P "${script_path}" + RESULT_VARIABLE exit_code + OUTPUT_VARIABLE output + ERROR_VARIABLE ignore) + if(NOT exit_code EQUAL 0) + message(FATAL_ERROR "Executing CMake script ${script_path} failed with code ${exit_code}.") + endif() + string(REGEX REPLACE "^.*---QtLoadFilePrintVars---\n" "" output "${output}") + string(REPLACE ";" "\;" output "${output}") + string(REPLACE "\n" ";" output "${output}") + foreach(line IN LISTS output) + string(REGEX MATCH "-- ([^ ]+) (.*)" m "${line}") + if(CMAKE_MATCH_1 IN_LIST arg_VARIABLES) + set(${prefix}_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" PARENT_SCOPE) + endif() + endforeach() +endfunction() + function(qt_auto_detect_android) # Auto-detect NDK root if(NOT DEFINED CMAKE_ANDROID_NDK_ROOT AND DEFINED ANDROID_SDK_ROOT) @@ -37,10 +68,8 @@ function(qt_auto_detect_android) endif() if(DEFINED CMAKE_TOOLCHAIN_FILE AND NOT DEFINED QT_AUTODETECT_ANDROID) - - file(READ ${CMAKE_TOOLCHAIN_FILE} toolchain_file_content OFFSET 0 LIMIT 80) - string(FIND "${toolchain_file_content}" "The Android Open Source Project" find_result REVERSE) - if (NOT ${find_result} EQUAL -1) + qt_auto_detect_read_toolchain_file(tcf VARIABLES CMAKE_SYSTEM_NAME) + if(tcf_CMAKE_SYSTEM_NAME STREQUAL "Android") set(android_detected TRUE) else() set(android_detected FALSE) diff --git a/cmake/QtLoadFilePrintVars.cmake b/cmake/QtLoadFilePrintVars.cmake new file mode 100644 index 00000000000..fe0f3ee8d2d --- /dev/null +++ b/cmake/QtLoadFilePrintVars.cmake @@ -0,0 +1,15 @@ +# Load a file and print variables and their values +# +# IN_FILE: path to a file to be included +# VARIABLES: list of variables to be printed + +cmake_minimum_required(VERSION 3.16) +include("${IN_FILE}") + +# Print a magic comment that the caller must look for +message(STATUS "---QtLoadFilePrintVars---") + +# Print the variables +foreach(v IN LISTS VARIABLES) + message(STATUS "${v} ${${v}}") +endforeach()