diff --git a/src/libs/qtcreatorcdbext/CMakeLists.txt b/src/libs/qtcreatorcdbext/CMakeLists.txt index 7bf3bcc9e89..8c95cb400b8 100644 --- a/src/libs/qtcreatorcdbext/CMakeLists.txt +++ b/src/libs/qtcreatorcdbext/CMakeLists.txt @@ -75,8 +75,9 @@ if (_library_enabled) else() set(PythonZipFileName "python${CMAKE_MATCH_4}.zip") endif() + set(PythonNameWithVersion "${CMAKE_MATCH_3}") - set(PythonDll "${CMAKE_MATCH_1}/${CMAKE_MATCH_3}${CMAKE_SHARED_LIBRARY_SUFFIX}") + set(PythonDll "${CMAKE_MATCH_1}/${PythonNameWithVersion}${CMAKE_SHARED_LIBRARY_SUFFIX}") set(PythonExe "${CMAKE_MATCH_1}/python${CMAKE_EXECUTABLE_SUFFIX}") set(PythonZip "${CMAKE_MATCH_1}/${PythonZipFileName}") @@ -92,6 +93,76 @@ if (_library_enabled) return() endif() + # Support for cross-compilation for arm64 on a x64 system + if (MSVC_CXX_ARCHITECTURE_ID MATCHES "^ARM" AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^AMD") + find_program(dumpbin_executable dumpbin) + find_program(lib_executable lib) + + string(TOLOWER ${MSVC_CXX_ARCHITECTURE_ID} lower_arch_name) + + if (NOT dumpbin_executable OR NOT lib_executable) + message(WARNING "Couldn't locate dumpbin.exe or lib.exe executables") + return() + endif() + + if (Python3_VERSION VERSION_LESS "3.11.0") + message(WARNING "Python 3.11.0 needs to be installed. This version is the first version that has arm64 Windows support") + return() + endif() + + execute_process( + COMMAND ${dumpbin_executable} /exports ${PythonDll} + OUTPUT_VARIABLE dumpbin_output + RESULT_VARIABLE dumpbin_result) + + string(REGEX REPLACE ".*[ \t]+ordinal[ \t]+hint[ \t]+RVA[ \t]+name[\r\n][\r\n]" "" dumpbin_output "${dumpbin_output}") + string(REGEX REPLACE "[\r\n][ \t]+Summary[\r\n].*" "" dumpbin_output "${dumpbin_output}") + string(REGEX REPLACE "([ \t]+[0-9]+)([ \t]+[a-fA-F0-9]+)([ \t]+[a-fA-F0-9]+)[ \t]+([a-zA-Z0-9_]+)( = [a-zA-Z0-9_]+[\r\n]|[\r\n])" "\\4;" filter_output "${dumpbin_output}") + + string(APPEND pythondef "LIBRARY ${PythonNameWithVersion}\nEXPORTS\n") + foreach(var IN LISTS filter_output) + if (var) + string(APPEND pythondef "${var}\n") + endif() + endforeach() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${PythonNameWithVersion}.def "${pythondef}") + + execute_process( + COMMAND ${lib_executable} + /def:${CMAKE_CURRENT_BINARY_DIR}/${PythonNameWithVersion}.def + /out:${CMAKE_CURRENT_BINARY_DIR}/${PythonNameWithVersion}.lib /machine:${lower_arch_name} /nologo) + set(Python3_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/${PythonNameWithVersion}.lib") + + if (NOT PythonTargetArchDll AND ENV{PythonTargetArchDll}) + set(PythonTargetArchDll $ENV{PythonTargetArchDll}) + endif() + + if (NOT PythonTargetArchDll) + set(python_embed_url "https://www.python.org/ftp/python/${Python3_VERSION}/python-${Python3_VERSION}-embed-${lower_arch_name}.zip") + message(STATUS "Downloading ${python_embed_url}") + + foreach(retry RANGE 10) + file(DOWNLOAD ${python_embed_url} ${CMAKE_CURRENT_BINARY_DIR}/python-embed.zip) + file(SIZE ${CMAKE_CURRENT_BINARY_DIR}/python-embed.zip fileSize) + if (fileSize GREATER 0) + break() + endif() + endforeach() + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python-embed) + file(ARCHIVE_EXTRACT INPUT ${CMAKE_CURRENT_BINARY_DIR}/python-embed.zip DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/python-embed) + + set(PythonTargetArchDll ${CMAKE_CURRENT_BINARY_DIR}/python-embed/${PythonNameWithVersion}${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() + + if (NOT PythonTargetArchDll) + message(WARNING "PythonTargetArchDll CMake parameter or ENV{PythonTargetArchDll} was not configured and the Python runtime cannot be configured") + return() + endif() + + set(PythonDll "${PythonTargetArchDll}") + endif() + extend_qtc_library(qtcreatorcdbext DEPENDS "${Python3_LIBRARIES}" INCLUDES "${Python3_INCLUDE_DIRS}"