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 <craig.scott@qt.io>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Joerg Bornemann 2021-03-02 12:36:27 +01:00
parent 1f8f13cbe7
commit 7c62caa355
2 changed files with 48 additions and 4 deletions

View File

@ -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)

View File

@ -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()