CMake: Split and clean up WebAssembly auto-detection code

Split qt_auto_detect_wasm into multiple helper functions and place
them in a new QtPublicWasmToolchainHelpers.cmake file.

We want to use them to try and detect the CMake toolchain
file location from within the generated qt.toolchain.cmake
file whem configuring a user project.

Pick-to: 6.2
Task-number: QTBUG-96843
Change-Id: Id8c2350e6dbe3c994b435681353bdaee114249a7
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Alexandru Croitor 2021-09-24 17:06:02 +02:00
parent a0e56294c1
commit c7d9e05a2b
3 changed files with 83 additions and 35 deletions

View File

@ -16,57 +16,46 @@ function(qt_internal_ensure_static_qt_config)
endif() endif()
endfunction() endfunction()
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicWasmToolchainHelpers.cmake")
function(qt_auto_detect_wasm) function(qt_auto_detect_wasm)
if("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "wasm-emscripten") if("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "wasm-emscripten")
if (NOT DEFINED ENV{EMSDK}) if (NOT DEFINED ENV{EMSDK})
message(FATAL_ERROR message(FATAL_ERROR
"Can't find EMSDK! Make sure EMSDK environment variable " "Can't find an Emscripten SDK! Make sure the EMSDK environment variable is "
"is available and emcc is in your path.") "available by activating and sourcing the emscripten sdk. Also ensure emcc is in "
"your path.")
endif() endif()
if(NOT DEFINED QT_AUTODETECT_WASM) if(NOT DEFINED QT_AUTODETECT_WASM_IS_DONE)
# detect EMSCRIPTEN_ROOT path message(STATUS "Extracting Emscripten SDK info from EMSDK env var: $ENV{EMSDK}")
file(READ "$ENV{EMSDK}/.emscripten" ver) __qt_internal_get_emroot_path_suffix_from_emsdk_env(EMROOT_PATH)
string(REGEX MATCH "EMSCRIPTEN_ROOT.*$" EMROOT "${ver}")
string(REGEX MATCH "'([^' ]*)'" EMROOT2 "${EMROOT}")
string(REPLACE "'" "" EMROOT_PATH "${EMROOT2}")
# get emscripten version __qt_internal_query_emsdk_version("${EMROOT_PATH}" TRUE CMAKE_EMSDK_REGEX_VERSION)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set (EXECUTE_COMMANDPATH "$ENV{EMSDK}/${EMROOT_PATH}/emcc.bat")
else()
set (EXECUTE_COMMANDPATH "$ENV{EMSDK}/${EMROOT_PATH}/emcc")
endif()
file(TO_NATIVE_PATH "${EXECUTE_COMMANDPATH}" EXECUTE_COMMAND)
execute_process(COMMAND ${EXECUTE_COMMAND} --version
OUTPUT_VARIABLE emOutput
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE emrun_error
RESULT_VARIABLE result)
if(NOT emOutput)
message(FATAL_ERROR
"Can't determine Emscripten version! Error: ${emrun_error}")
endif()
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CMAKE_EMSDK_REGEX_VERSION "${emOutput}")
set(EMCC_VERSION "${CMAKE_EMSDK_REGEX_VERSION}" CACHE STRING INTERNAL FORCE) set(EMCC_VERSION "${CMAKE_EMSDK_REGEX_VERSION}" CACHE STRING INTERNAL FORCE)
# find toolchain file # Find toolchain file
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
set(wasm_toolchain_file "$ENV{EMSDK}/${EMROOT_PATH}/cmake/Modules/Platform/Emscripten.cmake") __qt_internal_get_emscripten_cmake_toolchain_file_path_from_emsdk_env(
"${EMROOT_PATH}" wasm_toolchain_file)
set(CMAKE_TOOLCHAIN_FILE "${wasm_toolchain_file}" CACHE STRING "" FORCE) set(CMAKE_TOOLCHAIN_FILE "${wasm_toolchain_file}" CACHE STRING "" FORCE)
endif() endif()
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}") if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "Emscripten ${CMAKE_EMSDK_REGEX_VERSION} toolchain file detected at ${CMAKE_TOOLCHAIN_FILE}") message(STATUS
"Emscripten ${EMCC_VERSION} toolchain file detected at ${CMAKE_TOOLCHAIN_FILE}")
else() else()
message(FATAL_ERROR "Cannot find the toolchain file Emscripten.cmake. " message(FATAL_ERROR
"Please specify the toolchain file with -DCMAKE_TOOLCHAIN_FILE=<file>.") "Cannot find the toolchain file Emscripten.cmake. "
"Please specify the toolchain file with -DCMAKE_TOOLCHAIN_FILE=<file> "
"or provide a path to a valid emscripten installation via the EMSDK "
"environment variable.")
endif() endif()
set(QT_AUTODETECT_WASM TRUE CACHE BOOL "")
qt_internal_ensure_static_qt_config() qt_internal_ensure_static_qt_config()
# this version of Qt needs this version of emscripten
set(QT_EMCC_RECOMMENDED_VERSION 2.0.14 CACHE STRING INTERNAL FORCE) __qt_internal_get_emcc_recommended_version(recommended_version)
set(QT_EMCC_RECOMMENDED_VERSION "${recommended_version}" CACHE STRING INTERNAL FORCE)
set(QT_AUTODETECT_WASM_IS_DONE TRUE CACHE BOOL "")
endif() endif()
endif() endif()
endfunction() endfunction()

View File

@ -285,6 +285,10 @@ set(__public_cmake_helpers
cmake/QtPublicWalkLibsHelpers.cmake cmake/QtPublicWalkLibsHelpers.cmake
cmake/QtPublicFindPackageHelpers.cmake cmake/QtPublicFindPackageHelpers.cmake
cmake/QtPublicDependencyHelpers.cmake cmake/QtPublicDependencyHelpers.cmake
# Public CMake files that are installed next Qt6Config.cmake, but are NOT included by it.
# Instead they are included by the generated CMake toolchain file.
cmake/QtPublicWasmToolchainHelpers.cmake
) )
qt_copy_or_install(FILES ${__public_cmake_helpers} DESTINATION "${__GlobalConfig_install_dir}") qt_copy_or_install(FILES ${__public_cmake_helpers} DESTINATION "${__GlobalConfig_install_dir}")

View File

@ -0,0 +1,55 @@
# Assuming EMSDK == /path/emsdk
#
# Then we expect /path/emsdk/.emscripten file to contain the following line
# EMSCRIPTEN_ROOT = emsdk_path + '/upstream/emscripten'
#
# then we set out_var to '/upstream/emscripten', so it's not a full path
function(__qt_internal_get_emroot_path_suffix_from_emsdk_env out_var)
# Query EMSCRIPTEN_ROOT path.
file(READ "$ENV{EMSDK}/.emscripten" ver)
string(REGEX MATCH "EMSCRIPTEN_ROOT.*$" EMROOT "${ver}")
string(REGEX MATCH "'([^' ]*)'" EMROOT2 "${EMROOT}")
string(REPLACE "'" "" EMROOT_PATH "${EMROOT2}")
set(${out_var} "${EMROOT_PATH}" PARENT_SCOPE)
endfunction()
function(__qt_internal_get_emscripten_cmake_toolchain_file_path_from_emsdk_env emroot_path out_var)
set(wasm_toolchain_file "$ENV{EMSDK}/${emroot_path}/cmake/Modules/Platform/Emscripten.cmake")
set(${out_var} "${wasm_toolchain_file}" PARENT_SCOPE)
endfunction()
function(__qt_internal_query_emsdk_version emroot_path is_fatal out_var)
# get emscripten version
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(EXECUTE_COMMANDPATH "$ENV{EMSDK}/${emroot_path}/emcc.bat")
else()
set(EXECUTE_COMMANDPATH "$ENV{EMSDK}/${emroot_path}/emcc")
endif()
file(TO_NATIVE_PATH "${EXECUTE_COMMANDPATH}" EXECUTE_COMMAND)
execute_process(COMMAND ${EXECUTE_COMMAND} --version
OUTPUT_VARIABLE emOutput
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE emrun_error
RESULT_VARIABLE result)
message(DEBUG "emcc --version output: ${emOutput}")
if(NOT emOutput)
if(is_fatal)
message(FATAL_ERROR
"Couldn't determine Emscripten version from running ${EXECUTE_COMMAND} --version. "
"Error: ${emrun_error}")
endif()
set(${out_var} "" PARENT_SCOPE)
else()
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CMAKE_EMSDK_REGEX_VERSION "${emOutput}")
set(${out_var} "${CMAKE_EMSDK_REGEX_VERSION}" PARENT_SCOPE)
endif()
endfunction()
function(__qt_internal_get_emcc_recommended_version out_var)
# This version of Qt needs this version of emscripten.
set(QT_EMCC_RECOMMENDED_VERSION "2.0.14")
set(${out_var} "${QT_EMCC_RECOMMENDED_VERSION}" PARENT_SCOPE)
endfunction()