From 205a900f9faf0c8530d6b5d618df4521a7c6ba69 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 27 Feb 2023 17:03:20 +0100 Subject: [PATCH] qtcreatorcdbext: python deployment for arm64 Use dumpbin to extract the symbols from the host dll. Use lib to create an arm64 library to link the qtcreatorcdbext.dll arm64 shared library. Use the PythonTargetArchDll CMake or environment variable to install the target arm64 python.dll If PythonTargetArchDll is not configured the script will download the python-embed-arm64.zip, extract and set PythonTargetArchDll Task-number: QTCREATORBUG-25859 Change-Id: I09320bb758fded546f203c905b75485d7de3b94e Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- src/libs/qtcreatorcdbext/CMakeLists.txt | 73 ++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) 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}"