diff --git a/cmake/QtAutoDetect.cmake b/cmake/QtAutoDetect.cmake index 5c6cba89ae..efb798f3c4 100644 --- a/cmake/QtAutoDetect.cmake +++ b/cmake/QtAutoDetect.cmake @@ -16,57 +16,46 @@ function(qt_internal_ensure_static_qt_config) endif() endfunction() +include("${CMAKE_CURRENT_LIST_DIR}/QtPublicWasmToolchainHelpers.cmake") function(qt_auto_detect_wasm) if("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "wasm-emscripten") if (NOT DEFINED ENV{EMSDK}) message(FATAL_ERROR - "Can't find EMSDK! Make sure EMSDK environment variable " - "is available and emcc is in your path.") + "Can't find an Emscripten SDK! Make sure the EMSDK environment variable is " + "available by activating and sourcing the emscripten sdk. Also ensure emcc is in " + "your path.") endif() - if(NOT DEFINED QT_AUTODETECT_WASM) - # detect 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}") + if(NOT DEFINED QT_AUTODETECT_WASM_IS_DONE) + message(STATUS "Extracting Emscripten SDK info from EMSDK env var: $ENV{EMSDK}") + __qt_internal_get_emroot_path_suffix_from_emsdk_env(EMROOT_PATH) - # 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() + __qt_internal_query_emsdk_version("${EMROOT_PATH}" TRUE CMAKE_EMSDK_REGEX_VERSION) + set(EMCC_VERSION "${CMAKE_EMSDK_REGEX_VERSION}" CACHE STRING INTERNAL FORCE) - 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) - - # find toolchain file + # Find 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) endif() 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() - message(FATAL_ERROR "Cannot find the toolchain file Emscripten.cmake. " - "Please specify the toolchain file with -DCMAKE_TOOLCHAIN_FILE=.") + message(FATAL_ERROR + "Cannot find the toolchain file Emscripten.cmake. " + "Please specify the toolchain file with -DCMAKE_TOOLCHAIN_FILE= " + "or provide a path to a valid emscripten installation via the EMSDK " + "environment variable.") endif() - set(QT_AUTODETECT_WASM TRUE CACHE BOOL "") 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() endfunction() diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index ed23a3fe7f..dd7ceecb35 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -285,6 +285,10 @@ set(__public_cmake_helpers cmake/QtPublicWalkLibsHelpers.cmake cmake/QtPublicFindPackageHelpers.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}") diff --git a/cmake/QtPublicWasmToolchainHelpers.cmake b/cmake/QtPublicWasmToolchainHelpers.cmake new file mode 100644 index 0000000000..53d74e0234 --- /dev/null +++ b/cmake/QtPublicWasmToolchainHelpers.cmake @@ -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()